Last active
December 16, 2015 16:40
-
-
Save sgss/5464760 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Application extends Observable | |
self = @initialize() | |
@static | |
stack: [] | |
@property | |
delegate: | |
defaults: null | |
@property | |
processes: | |
attributes: readonly clones bindable | |
defaults: [] | |
@property | |
startedTime: | |
attributes: readonly | |
defaults: 0 | |
@property | |
processedTime: | |
attributes: readonly | |
defaults: 0 | |
@property | |
consumedTime: | |
attributes: readonly | |
defaults: 0 | |
@property | |
frameRate: | |
attributes: readonly | |
defaults: 0 | |
@property | |
active: | |
attributes: bindable | |
defaults: yes | |
converter: Boolean | |
afterChange: (value) -> if value then @activate() else @deactivate() | |
@property | |
started: | |
attributes: bindable | |
defaults: no | |
converter: Boolean | |
afterChange: (value) -> if value then @start() else @stop() | |
@property | |
pasteboard: | |
attributes: bindable | |
defaults: null | |
#--------------------------------------------------------------------------- | |
# Initialization | |
# method: initialize [parameters] | |
# returns: this | |
initialize: (parameters) -> | |
super() | |
@setProperties parameters | |
@ | |
#--------------------------------------------------------------------------- | |
# Activating Application | |
# method: activate | |
# returns: this | |
activate: -> | |
if application isnt @ | |
application?.setActive no | |
application = @ | |
@setActive yes | |
@_delegate?.applicationActivated? @ | |
self.stack.push @ | |
@ | |
# method: deactivate | |
# returns: this | |
deactivate: -> | |
if application is @ | |
application = null | |
@setActive no | |
@_delegate?.applicationDeactivated? @ | |
self.stack.pop() | |
if self.stack.length | |
self.stack.last().activate() | |
@ | |
#--------------------------------------------------------------------------- | |
# Controlling Application | |
# method: start | |
# returns: this | |
start: -> | |
if not @_intervalTimer? | |
@_startedTime = new Date().getTime() | |
@_intervalTimer = setInterval @process, self.interval | |
@setStarted yes | |
@_delegate?.applicationStarted? @ | |
@ | |
# method: stop | |
# returns: this | |
stop: -> | |
if @_intervalTimer? | |
clearInterval @_intervalTimer | |
@_intervalTimer = null | |
@setStarted no | |
@_delegate?.applicationStopped? @ | |
@ | |
#--------------------------------------------------------------------------- | |
# Managing Application Cycle | |
# method: process | |
# returns: this | |
process: => | |
before = new Date().getTime() | |
@main() | |
process.process() for process in @_processes | |
after = new Date().getTime() | |
@_processedTime = before | |
@_consumedTime = after - before | |
@ | |
# method: main | |
# returns: this | |
main: -> @ | |
#--------------------------------------------------------------------------- | |
# Managing Process | |
# method: attachProcess <process> | |
# returns: this | |
attachProcess: (process) -> | |
if process instanceof Process and @_processes.indexOf(process) is -1 | |
@willChangeProperty 'processes' | |
@_processes.push process | |
@didChangeProperty 'processes' | |
@_delegate?.applicationAttachedProcess? @, process | |
@ | |
# method: detachProcess <process> | |
# returns: this | |
detachProcess: (process) -> | |
index = @_processes.indexOf process | |
if index isnt -1 | |
@willChangeProperty 'processes' | |
@_processes.splice index, 1 | |
@didChangeProperty 'processes' | |
@_delegate?.applicationDetachedProcess? @, process | |
@ | |
window.application = new Application |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict" | |
window.sgss ?= {} | |
#------------------------------------------------------------------------------- | |
# Object Manipulation | |
# function: merge <target>, <sources...> | |
# returns: Object | |
sgss.merge = | |
merge = (target, sources...) -> | |
if not target? then target = {} | |
for source in sources | |
for name, value of source | |
target[name] = value | |
target | |
# function: merge <objs...> | |
# returns: Object | |
sgss.combine = | |
combine = (objs...) -> | |
result = {} | |
for obj in objs | |
for name, value of obj | |
result[name] = value | |
result | |
# function: clone <obj>, [deep] | |
# returns: Object | |
sgss.clone = | |
clone = (obj, deep) -> | |
if obj? and isFunction obj.clone | |
obj.clone deep | |
else | |
_.clone obj, deep | |
# function: equal <a>, <b> | |
# returns: Boolean | |
sgss.equal = | |
equal = (a, b) -> | |
if a? and isFunction a.equals | |
a.equals b | |
else if b? and isFunction b.equals | |
b.equals a | |
else | |
_.isEqual a, b | |
# function: equalEach <objs...> | |
# returns: Boolean | |
sgss.equalEach = | |
equalEach = (objs...) -> | |
for value, i in objs by 2 | |
a = objs[i] | |
b = objs[i + 1] | |
if a? and isFunction a.equals | |
return no unless a.equals b | |
else if b? and isFunction b.equals | |
return no unless b.equals a | |
else | |
return no unless _.isEqual a, b | |
yes | |
# function: equalAll <obj>, <others...> | |
# returns: Boolean | |
sgss.equalAll = | |
equalAll = (obj, others...) -> | |
if obj? and isFunction obj.equals | |
for other in others | |
return no unless obj.equals other | |
else | |
for other in others | |
if other? and isFunction other.equals | |
return no unless other.equals obj | |
else | |
return no unless _.isEqual obj, other | |
yes | |
# function: equalAny <obj>, <others...> | |
# returns: Boolean | |
sgss.equalAny = | |
equalAny = (obj, others...) -> | |
if obj? and isFunction obj.equals | |
for other in others | |
return yes if obj.equals other | |
else | |
for other in others | |
if other? and isFunction other.equals | |
return yes if other.equals obj | |
else | |
return yes if _.isEqual obj, other | |
no | |
# function: slice <array>, [start], [end] | |
# returns: Array | |
sgss.slice = | |
slice = Function::call.bind Array::slice | |
#------------------------------------------------------------------------------- | |
# Property Definitions | |
# function: clones [linker] | |
# returns: Object | |
clones = (linker) -> | |
attribute = { clones: yes } | |
if isFunction linker | |
merge do linker, attribute | |
else if linker? | |
merge linker, attribute | |
else | |
attribute | |
# function: readonly [linker] | |
# returns: Object | |
readonly = (linker) -> | |
attribute = { readonly: yes } | |
if isFunction linker | |
merge do linker, attribute | |
else if linker? | |
merge linker, attribute | |
else | |
attribute | |
# function: writeonly [linker] | |
# returns: Object | |
writeonly = (linker) -> | |
attribute = { writeonly: yes } | |
if isFunction linker | |
merge do linker, attribute | |
else if linker? | |
merge linker, attribute | |
else | |
attribute | |
# function: informative [linker] | |
# returns: Object | |
informative = (linker) -> | |
attribute = { informative: yes } | |
if isFunction linker | |
merge do linker, attribute | |
else if linker? | |
merge linker, attribute | |
else | |
attribute | |
# function: bindable [linker] | |
# returns: Object | |
bindable = (linker) -> | |
attribute = { bindable: yes } | |
if isFunction linker | |
merge do linker, attribute | |
else if linker? | |
merge linker, attribute | |
else | |
attribute | |
# function: parametric [linker] | |
# returns: Object | |
parametric = (linker) -> | |
attribute = { parametric: yes } | |
if isFunction linker | |
merge do linker, attribute | |
else if linker? | |
merge linker, attribute | |
else | |
attribute | |
#------------------------------------------------------------------------------- | |
# Type Tests | |
# function: isArray <obj> | |
# returns: Boolean | |
sgss.isArray = | |
isArray = Object.isArray | |
# function: isBoolean <obj> | |
# returns: Boolean | |
sgss.isBoolean = | |
isBoolean = Object.isBoolean | |
# function: isNaN <obj> | |
# returns: Boolean | |
sgss.isNaN = | |
isNaN = Object.isNaN | |
# function: isDate <obj> | |
# returns: Boolean | |
sgss.isDate = | |
isDate = Object.isDate | |
# function: isFunction <obj> | |
# returns: Boolean | |
sgss.isFunction = | |
isFunction = Object.isFunction | |
# function: isNumber <obj> | |
# returns: Boolean | |
sgss.isNumber = | |
isNumber = Object.isNumber | |
# function: isObject <obj> | |
# returns: Boolean | |
sgss.isObject = | |
isObject = Object.isObject | |
# function: isString <obj> | |
# returns: Boolean | |
sgss.isString = | |
isString = Object.isString | |
# function: isRegExp <obj> | |
# returns: Boolean | |
sgss.isRegExp = | |
isRegExp = Object.isRegExp | |
# function: isEmpty <obj> | |
# returns: Boolean | |
sgss.isEmpty = | |
isEmpty = Object.isEmpty | |
#------------------------------------------------------------------------------- | |
# Debugging | |
# method: log [messages...] | |
sgss.log = | |
log = (messages...) -> | |
console.log messages... | |
# method: error [messages...] | |
sgss.error = | |
error = (messages...) -> | |
console.error messages... | |
# method: assert <condition>, [messages...] | |
sgss.assert = | |
assert = (condition, messages...) -> | |
if not condition | |
console.error messages... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
window.sgss ?= {} | |
sgss.Intrinsic = | |
class Intrinsic | |
self = @ | |
# function: initialize | |
# returns: Function | |
@initialize: -> @ | |
# function: implements <implementation> | |
# returns: Function | |
@implements: (implementation) -> | |
merge @, implementation | |
merge @::, implementation:: | |
@ | |
# function: static <definition> | |
# returns: Function | |
@static: (definition) -> | |
merge @, definition | |
@ | |
# function: getSuper | |
# returns: Function | |
@getSuper: -> @__super__?.constructor | |
# function: getName | |
# returns: String | |
@getName: -> @name | |
#--------------------------------------------------------------------------- | |
# Managing Class and Instance | |
# method: getClass | |
# returns: Function | |
getClass: -> @__proto__.constructor | |
#--------------------------------------------------------------------------- | |
# Managing Instance Variable | |
# method: getInternal <name> | |
# method: getInternal <names> | |
# method: getInternal <name:> | |
# returns: mixed | |
getInternal: (arg0) -> | |
# getInternal <name> | |
if isString arg0 | |
@['_' + arg0] | |
# getInternal <names> | |
else if isArray arg0 | |
result = {} | |
for name in arg0 | |
result[name] = @['_' + name] | |
result | |
# getInternal <name:> | |
else if isObject arg0 | |
result = {} | |
for name of arg0 | |
result[name] = @['_' + name] | |
result | |
# aliases: getInternal | |
getInternals: @::getInternal | |
# method: setInternal <name>, <value> | |
# method: setInternal <names>, <value> | |
# method: setInternal <name: value>, <name: default> | |
# method: setInternal <name: value> | |
# returns: this | |
setInternal: (arg0, arg1) -> | |
# setInternal <name>, <value> | |
if isString arg0 | |
@['_' + arg0] = arg1 | |
# setInternal <names>, <value> | |
else if isArray arg0 | |
for name in arg0 | |
@['_' + name] = arg1 | |
# setInternal <name: value>, <name: default> | |
else if isObject arg1 | |
unless arg0? | |
for name, defaults of arg1 | |
@['_' + name] = defaults | |
else | |
for name, defaults of arg1 | |
@['_' + name] = if name of arg0 then arg0[name] else defaults | |
# setInternal <name: value> | |
else if isObject arg0 | |
for name, value of arg0 | |
@['_' + name] = value | |
@ | |
# aliases: setInternal | |
setInternals: @::setInternal | |
#--------------------------------------------------------------------------- | |
# Debugging | |
# method: log [messages...] | |
# returns: this | |
log: (messages...) -> | |
messages.unshift "#{@getClass().getName()}:" | |
console.log messages... | |
@ | |
# method: error [messages...] | |
# returns: this | |
error: (messages...) -> | |
messages.unshift "#{@getClass().getName()}:" | |
console.error messages... | |
@ | |
# method: assert <condition>, [messages...] | |
# returns: this | |
assert: (condition, messages...) -> | |
if not condition | |
messages.unshift "#{@getClass().getName()}:" | |
console.error messages... | |
@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
window.sgss ?= {} | |
sgss.Manageable = | |
class Manageable extends Intrinsic | |
self = @initialize() | |
@__identifier : 0 | |
@__properties : {} | |
@__propertyOptions : | |
clones : no | |
readonly : no | |
writeonly : no | |
informative : no | |
bindable : no | |
parametric : no | |
internal : null | |
getter : null | |
setter : null | |
defaults : null | |
converter : null | |
inflector : null | |
beforeChange : null | |
afterChange : null | |
# function: property <definition> | |
# returns: Function | |
@property: (definition) -> | |
for name, value of definition | |
if isFunction value | |
definition[name] = value() | |
else if value.attributes? | |
if isFunction value.attributes | |
value.attributes = value.attributes() | |
merge value, value.attributes | |
delete value.attributes | |
@createProperty definition | |
@ | |
# function: initialize | |
# returns: Function | |
@initialize: -> | |
@__properties = clone @__properties | |
@ | |
# function: getProperty <name> | |
# returns: Object | |
@getProperty: (name) -> @__properties[name] | |
# function: getProperty | |
# returns: Object | |
@getProperties: -> @__properties | |
# function: getParameter <name> | |
# returns: Object | |
@getParameter: (name) -> | |
property = @__properties[name] | |
if property?.parametric | |
property | |
else | |
null | |
# function: getParameters | |
# returns: Object | |
@getParameters: -> | |
result = {} | |
for name, property of @__properties | |
if property.parametric | |
result[name] = property | |
result | |
# function: getReadableProperty <name> | |
# returns: Object | |
@getReadableProperty: (name) -> | |
property = @__properties[name] | |
if property? and not property.writeonly | |
property | |
else | |
null | |
# function: getReadableProperties | |
# returns: Object | |
@getReadableProperties: -> | |
result = {} | |
for name, property of @__properties | |
if not property.writeonly | |
result[name] = property | |
result | |
# function: getWritableProperty <name> | |
# returns: Object | |
@getWritableProperty: (name) -> | |
property = @__properties[name] | |
if property? and not property.readonly | |
property | |
else | |
null | |
# function: getWritableProperties | |
# returns: Object | |
@getWritableProperties: -> | |
result = {} | |
for name, property of @__properties | |
if not property.readonly | |
result[name] = property | |
result | |
# function: createProperty <name>, <options> | |
# function: createProperty <name: options> | |
# returns: Function | |
@createProperty: (arg0, arg1) -> | |
# createProperty <name>, <options> | |
if isString arg0 | |
options = arg1 | |
options[name] = value for name, value of @__propertyOptions when not options[name]? | |
internal = '_' + arg0 | |
capital = arg0.first().capitalize() + arg0.from 1 | |
if not options.internal | |
options.internal = internal | |
if not options.writeonly and not options.getter? | |
if arg0.startsWith(/can|should|needs|draws|uses|has/) | |
options.getter = arg0 | |
else if options.converter is Boolean | |
options.getter = 'is' + capital | |
else | |
options.getter = 'get' + capital | |
if not options.readonly and not options.setter? | |
options.setter = 'set' + capital | |
if not options.writeonly and not @::[options.getter] | |
@::[options.getter] = @::propertyGetter.fill arg0, options | |
if not options.readonly and not @::[options.setter] | |
@::[options.setter] = @::propertySetter.fill arg0, options | |
@__properties[arg0] = options | |
# createProperty <name: options> | |
else if isObject arg0 | |
@createProperty name, options for name, options of arg0 | |
@ | |
#--------------------------------------------------------------------------- | |
# Initialization | |
# function: Manageable | |
constructor: -> | |
@preinitialize() | |
@initialize arguments... | |
@postinitialize() | |
# method: preinitialize | |
# returns: this | |
preinitialize: -> | |
@__identifier = ++self.__identifier | |
@__initialized = no | |
@__deferreds = {} | |
for name, options of @getClass().__properties | |
if options.defaults? | |
if options.readonly | |
@[options.internal] = clone options.defaults | |
else if setter = @getSetter name | |
@setAfterInitialization name, [clone options.defaults], setter | |
@ | |
# method: initialize | |
# returns: this | |
initialize: -> @ | |
# method: postinitialize | |
# returns: this | |
postinitialize: -> | |
@__initialized = yes | |
for name, callback of @__deferreds | |
callback() | |
@__deferreds = null | |
@ | |
# method: setAfterInitialization <name>, <args>, [setter] | |
# returns: this | |
setAfterInitialization: (name, args, setter) -> | |
if not setter? | |
setter = @getSetter name | |
if setter? | |
@__deferreds[name] = _.bind.apply _, [setter, @].concat args | |
@ | |
#--------------------------------------------------------------------------- | |
# Managing Class and Instance | |
# method: getIdentifier | |
# returns: Number | |
getIdentifier: -> @__identifier; | |
#--------------------------------------------------------------------------- | |
# Templating Property | |
# method: propertyGetter <name>, <options> | |
# returns: mixed | |
propertyGetter: (name, options) -> | |
# pass the value to inflector | |
if options.inflector? | |
if isString options.inflector | |
return @[options.inflector].apply @, [@[options.internal]].concat slice(arguments, 2) | |
else | |
return options.inflector.apply @, [@[options.internal]].concat slice(arguments, 2) | |
# clone if needed | |
if options.clones | |
return clone @[options.internal] | |
return @[options.internal] | |
# method: propertySetter <name>, <options>, <value> | |
# returns: this | |
propertySetter: (name, options, value) -> | |
# pass the value to converter | |
if options.converter? | |
value = | |
if isString options.converter | |
@[options.converter].apply @, slice(arguments, 2) | |
else | |
options.converter.apply @, slice(arguments, 2) | |
if not equal @[options.internal], value | |
# call before change callback | |
if options.beforeChange? | |
if isString options.beforeChange | |
@[options.beforeChange].apply @, [value, @[options.internal]] | |
else | |
options.beforeChange.apply @, [value, @[options.internal]] | |
oldValue = @[options.internal] | |
@[options.internal] = if options.clones then clone value else value | |
# inform change | |
if options.informative | |
@[name + 'PropertyChanged']? value, oldValue | |
# post property change notification | |
if options.bindable | |
@notifyPropertyChange name, value, oldValue | |
# call after change callback | |
if options.afterChange? | |
if isString options.afterChange | |
@[options.afterChange].apply @, [value, oldValue] | |
else | |
options.afterChange.apply @, [value, oldValue] | |
@ | |
#--------------------------------------------------------------------------- | |
# Managing Property | |
# method: validateProperty <name> | |
# returns: Boolean | |
validateProperty: (name) -> @getClass().getProperty(name)? | |
# method: getGetter <name> | |
# returns: Function | |
getGetter: (name) -> | |
capital = name[0].toUpperCase() + name.substr 1 | |
if isFunction @['get' + capital] | |
@['get' + capital] | |
else | |
@getPropertyGetter name | |
# method: getPropertyGetter <name> | |
# returns: Function | |
getPropertyGetter: (name) -> | |
property = @getClass().getProperty name | |
if property? and not property.writeonly | |
@[property.getter] | |
else | |
null | |
# method: getSetter <name> | |
# returns: Function | |
getSetter: (name) -> | |
capital = name[0].toUpperCase() + name.substr 1 | |
if isFunction @['set' + capital] | |
@['set' + capital] | |
else | |
@getPropertySetter name | |
# method: getPropertySetter <name> | |
# returns: Function | |
getPropertySetter: (name) -> | |
property = @getClass().getProperty name | |
if property? and not property.readonly | |
@[property.setter] | |
else | |
null | |
# method: getProperty <name>, [args...] | |
# method: getProperty <names>, [args...] | |
# method: getProperty <name:>, [args...] | |
# method: getProperty [args...] | |
# returns: mixed | |
getProperty: (arg0, args...) -> | |
# getProperty <name>, [args...] | |
if isString arg0 | |
if getter = @getGetter arg0 | |
getter.apply @, args | |
# getProperty <names>, [args...] | |
else if isArray arg0 | |
result = {} | |
for name in arg0 | |
if getter = @getGetter name | |
result[name] = getter.apply @, args | |
result | |
# getProperty <name:>, [args...] | |
else if isObject arg0 | |
result = {} | |
for name of arg0 | |
if getter = @getGetter name | |
result[name] = getter.apply @, args | |
result | |
# getProperty [args...] | |
else | |
properties = @getClass().getReadableProperties() | |
args = [arg0].concat args | |
result = {} | |
for name, property of properties | |
result[name] = @[property.getter].apply @, args | |
result | |
# aliases: getProperty | |
getProperties: @::getProperty | |
# method: setProperty <name>, <args...> | |
# method: setProperty <names>, <args...> | |
# method: setProperty <name: value>, <name: default> | |
# method: setProperty <name: value> | |
# returns: this | |
setProperty: (arg0, args...) -> | |
arg1 = args[0] | |
# setProperty <name>, <value> | |
if isString arg0 | |
if @__initialized | |
if setter = @getSetter arg0 | |
setter.apply @, args | |
else | |
if setter = @getSetter arg0 | |
@setAfterInitialization arg0, args, setter | |
# setProperty <names>, <value> | |
else if isArray arg0 | |
if @__initialized | |
for name in arg0 | |
if setter = @getSetter name | |
setter.apply @, args | |
else | |
for name in arg0 | |
if setter = @getSetter name | |
@setAfterInitialization name, args, setter | |
# setProperty <name: value>, <name: default> | |
else if isObject arg1 | |
if @__initialized | |
unless arg0? | |
for name, defaults of arg1 | |
if setter = @getSetter name | |
setter.apply @, [defaults] | |
else | |
for name, defaults of arg1 | |
if setter = @getSetter name | |
setter.apply @, [if name of arg0 then arg0[name] else defaults] | |
else | |
unless arg0? | |
for name, defaults of arg1 | |
if setter = @getSetter name | |
@setAfterInitialization name, [defaults], setter | |
else | |
for name, defaults of arg1 | |
if setter = @getSetter name | |
@setAfterInitialization name, [if name of arg0 then arg0[name] else defaults], setter | |
# setProperty <name: value> | |
else if isObject arg0 | |
if @__initialized | |
for name, value of arg0 | |
if setter = @getSetter name | |
setter.apply @, [value] | |
else | |
for name, value of arg0 | |
if setter = @getSetter name | |
@setAfterInitialization name, [value], setter | |
@ | |
# aliases: setProperty | |
setProperties: @::setProperty |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
window.sgss ?= {} | |
sgss.Observable = | |
class Observable extends Manageable | |
self = @initialize() | |
@__regexpOfPattern: [] | |
#--------------------------------------------------------------------------- | |
# Initialization | |
# method: preinitialize | |
# returns: this | |
# overrides: Manageable.preinitialize | |
preinitialize: -> | |
super() | |
@__propertyObserversOfName = {} | |
@__propertyObserversOfPattern = {} | |
@__propertyObservers = {} | |
@__notificationObservers = {} | |
@__notificationObserversOfType = {} | |
@__notificationObserversOfPattern = {} | |
@__valuesOfPropertyWillChange = {} | |
@ | |
#--------------------------------------------------------------------------- | |
# Observing Notification | |
# method: observe <target>, <type>, <callback> | |
# method: observe <target>, <type: callback> | |
# method: observe <target>, <pattern>, <callback> | |
# method: observe <target>, <types>, <callback> | |
# method: observe <target>, <callback> | |
# returns: this | |
observe: (target, arg1, arg2) -> | |
@assert target?, 'cannot observe non-object type of target:', target | |
# observe <target>, <type>, <callback> | |
if isString arg1 | |
target.addNotificationObserverWithType @, arg1, arg2 | |
# observe <target>, <type: callback> | |
else if isObject arg1 | |
target.addNotificationObserverWithType @, type, callback for type, callback of arg1 | |
# observe <target>, <pattern>, <callback> | |
else if isRegExp arg1 | |
target.addNotificationObserverWithPattern @, arg1, arg2 | |
# observe <target>, <types>, <callback> | |
else if isArray arg1 | |
for each1 in arg1 | |
if isString each1 | |
target.addNotificationObserverWithType @, each1, arg2 | |
else if isRegExp each1 | |
target.addNotificationObserverWithPattern @, each1, arg2 | |
else | |
@error 'neither name nor pattern specified in array:', each1 | |
# observe <target>, <callback> | |
else | |
target.addNotificationObserverToAll @, arg1 | |
@ | |
# method: dismiss <target>, <type>, [callback] | |
# method: dismiss <target>, <type: callback> | |
# method: dismiss <target>, <pattern>, [callback] | |
# method: dismiss <target>, <types>, [callback] | |
# method: dismiss <target>, [callback] | |
# returns: this | |
dismiss: (target, arg1, arg2) -> | |
@assert target?, 'cannot dismiss non-object type of target:', target | |
# dismiss <target>, <type>, [callback] | |
if isString arg1 | |
target.removeNotificationObserverWithType @, arg1, arg2 | |
# dismiss <target>, <type: callback> | |
else if isObject arg1 | |
target.removeNotificationObserverWithType @, type, callback for type, callback of arg1 | |
# dismiss <target>, <pattern>, [callback] | |
else if isRegExp arg1 | |
target.removeNotificationObserverWithPattern @, arg1, arg2 | |
# dismiss <target>, <types>, [callback] | |
else if isArray arg1 | |
for each1 in arg1 | |
if isString each1 | |
target.removeNotificationObserverWithType @, each1, arg2 | |
else if isRegExp each1 | |
target.removeNotificationObserverWithPattern @, each1, arg2 | |
else | |
@error 'neither name nor pattern specified in array:', each1 | |
# dismiss <target>, [callback] | |
else | |
target.removeNotificationObserverFromAll @, arg1 | |
@ | |
# method: addObserver <observer>, <type>, <callback> | |
# method: addObserver <observer>, <type: callback> | |
# method: addObserver <observer>, <pattern>, <callback> | |
# method: addObserver <observer>, <types>, <callback> | |
# method: addObserver <observer>, <callback> | |
# returns: this | |
addObserver: (observer, arg1, arg2) -> | |
@assert observer?, 'cannot add non-object type of observer:', observer | |
# addObserver <observer>, <type>, <callback> | |
if isString arg1 | |
@addNotificationObserverWithType observer, arg1, arg2 | |
# addObserver <observer>, <type: callback> | |
else if isObject arg1 | |
for type, callback of arg1 | |
@addNotificationObserverWithType observer, type, callback | |
# addObserver <observer>, <pattern>, <callback> | |
else if isRegExp arg1 | |
@addNotificationObserverWithPattern observer, arg1, arg2 | |
# addObserver <observer>, <types>, <callback> | |
else if isArray arg1 | |
for each1 in arg1 | |
if isString each1 | |
@addNotificationObserverWithType observer, each1, arg2 | |
else if isRegExp each1 | |
@addNotificationObserverWithPattern observer, each1, arg2 | |
else | |
@error 'neither name nor pattern specified in array:', each1 | |
# addObserver <observer>, <callback> | |
else | |
@addNotificationObserverToAll observer, arg1 | |
@ | |
# method: removeObserver <observer>, <type>, [callback] | |
# method: removeObserver <observer>, <type: callback> | |
# method: removeObserver <observer>, <pattern>, [callback] | |
# method: removeObserver <observer>, <types>, [callback] | |
# method: removeObserver <observer>, [callback] | |
# method: removeObserver | |
# returns: this | |
removeObserver: (observer, arg1, arg2) -> | |
# removeObserver <observer>, <type>, [callback] | |
if isString arg1 | |
@removeNotificationObserverWithType observer, arg1, arg2 | |
# removeObserver <observer>, <type: callback> | |
else if isObject arg1 | |
@removeNotificationObserverWithType observer, type, callback for type, callback of arg1 | |
# removeObserver <observer>, <pattern>, [callback] | |
else if isRegExp arg1 | |
@removeNotificationObserverWithPattern observer, arg1, arg2 | |
# removeObserver <observer>, <types>, [callback] | |
else if isArray arg1 | |
for each1 in arg1 | |
if isString each1 | |
@removeNotificationObserverWithType observer, each1, arg2 | |
else if isRegExp each1 | |
@removeNotificationObserverWithPattern observer, each1, arg2 | |
else | |
@error 'neither name nor pattern specified in array:', each1 | |
# removeObserver <observer>, [callback] | |
else if observer? | |
@removeNotificationObserverFromAll observer, arg1 | |
# removeObserver | |
else | |
@removeAllNotificationObservers() | |
@ | |
# method: removeAllNotificationObservers | |
# return: this | |
removeAllNotificationObservers: -> | |
@__notificationObserversOfType = {} | |
@__notificationObserversOfPattern = {} | |
@__notificationObservers = {} | |
@ | |
#--------------------------------------------------------------------------- | |
# Notifying | |
# method: notify <type>, [data] | |
# method: notify <type: data> | |
# method: notify <types>, [data] | |
notify: (arg0, arg1) -> | |
# notify <type>, [data] | |
if isString arg0 | |
@postNotification new Notification @, arg0, arg1 | |
# notify <type: data> | |
else if isObject arg0 | |
@postNotificationWithType new Notification @, type, data for type, data of arg0 | |
# notify <types>, [data] | |
else if isArray arg0 | |
@postNotification new Notification @, type, arg1 for type in arg0 | |
else | |
@error 'insufficient argument to notify:', arguments | |
@ | |
# method: postNotification <notification> | |
# return: this | |
postNotification: (notification) -> | |
type = notification.type | |
args = [notification] | |
observers = @__notificationObserversOfType[type] | |
if observers? | |
for identifier, entry of observers | |
{context, callbacks} = entry | |
for callback in callbacks | |
callback.apply context, args | |
for pattern, observers of @__notificationObserversOfPattern | |
if self.__regexpOfPattern[pattern].test type | |
for identifier, entry of observers | |
{context, callbacks} = entry | |
for callback in callbacks | |
callback.apply context, args | |
for identifier, entry of @__notificationObservers | |
{context, callbacks} = entry | |
for callback in callbacks | |
callback.apply context, args | |
@ | |
#--------------------------------------------------------------------------- | |
# Managing Notification Observer | |
# method: addNotificationObserverWithType <observer>, <type>, <callback> | |
# return: this | |
addNotificationObserverWithType: (observer, type, callback) -> | |
if isFunction callback | |
observers = @__notificationObserversOfType[type] | |
unless observers? | |
observers = @__notificationObserversOfType[type] = {} | |
entry = observers[observer.__identifier] | |
unless entry? | |
entry = observers[observer.__identifier] = | |
context: observer | |
callbacks: [callback] | |
else if entry.callbacks.indexOf(callback) is -1 | |
entry.callbacks.push callback | |
else | |
@error 'attempting to add duplicated observer callback of type:', type, 'observer:', observer | |
else | |
@error 'cannot add non-function type of observer callback:', callback, 'type:', type, 'observer:', observer | |
@ | |
# method: addNotificationObserverWithPattern <observer>, <pattern>, <callback> | |
# return: this | |
addNotificationObserverWithPattern: (observer, pattern, callback) -> | |
if isRegExp pattern | |
regexp = pattern | |
pattern = regexp.toString() | |
else | |
regexp = new RegExp pattern | |
self.__regexpOfPattern[pattern] = regexp | |
if isFunction callback | |
observers = @__notificationObserversOfPattern[pattern] | |
unless observers? | |
observers = @__notificationObserversOfPattern[pattern] = {} | |
entry = observers[observer.__identifier] | |
unless entry? | |
entry = observers[observer.__identifier] = | |
context: observer | |
callbacks: [callback] | |
else if entry.callbacks.indexOf(callback) is -1 | |
entry.callbacks.push callback | |
else | |
@error 'attempting to add duplicated observer callback of pattern:', pattern, 'observer:', observer | |
else | |
@error 'cannot add non-function type of observer callback:', callback, 'pattern:', pattern, 'observer:', observer | |
@ | |
# method: addNotificationObserverToAll <observer>, <callback> | |
# return: this | |
addNotificationObserverToAll: (observer, callback) -> | |
if isFunction callback | |
entry = @__notificationObservers[observer.__identifier] | |
unless entry? | |
entry = @__notificationObservers[observer.__identifier] = | |
context: observer | |
callbacks: [callback] | |
else if entry.callbacks.indexOf(callback) is -1 | |
entry.callbacks.push callback | |
else | |
@error 'attempting to add duplicated observer callback of observer:', observer | |
else | |
@error 'cannot add non-function type of observer callback:', callback, 'observer:', observer | |
@ | |
# method: removeNotificationObserverWithType <observer>, <type>, [callback] | |
# return: this | |
removeNotificationObserverWithType: (observer, type, callback) -> | |
observers = @__notificationObserversOfType[type] | |
if observers? | |
unless callback? | |
delete observers[observer.__identifier] | |
else | |
entry = observers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__notificationObserversOfType[type] | |
@ | |
# method: removeNotificationObserverWithPattern <observer>, <pattern>, [callback] | |
# return: this | |
removeNotificationObserverWithPattern: (observer, pattern, callback) -> | |
if isRegExp pattern | |
pattern = pattern.toString() | |
observers = @__notificationObserversOfPattern[pattern] | |
if observers? | |
unless callback? | |
delete observers[observer.__identifier] | |
else | |
entry = observers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__notificationObserversOfPattern[pattern] | |
@ | |
# method: removeNotificationObserver <observer>, [callback] | |
# return: this | |
removeNotificationObserverFromAll: (observer, callback) -> | |
unless callbacks? | |
for type, observers of @__notificationObserversOfType | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__notificationObserversOfType[type] | |
for pattern, observers of @__notificationObserversOfPattern | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__notificationObserversOfPattern[pattern] | |
@__notificationObservers = [] | |
else | |
for type, observers of @__notificationObserversOfType | |
entry = observers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__notificationObserversOfType[type] | |
for pattern, observers of @__notificationObserversOfPattern | |
entry = observers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__notificationObserversOfPattern[pattern] | |
entry = @__notificationObservers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete @__notificationObservers[observer.__identifier] | |
@ | |
#--------------------------------------------------------------------------- | |
# Observing Property Change | |
# method: observeProperty <target>, <name>, <callback> | |
# method: observeProperty <target>, <name: callback> | |
# method: observeProperty <target>, <pattern>, <callback> | |
# method: observeProperty <target>, <names>, <callback> | |
# method: observeProperty <target>, <callback> | |
# returns: this | |
observeProperty: (target, arg1, arg2) -> | |
@assert target?, 'cannot observe property of non-object type of target:', target | |
# observeProperty <target>, <name>, <callback> | |
if isString arg1 | |
target.addPropertyObserverWithName @, arg1, arg2 | |
# observeProperty <target>, <name: callback> | |
else if isObject arg1 | |
target.addPropertyObserverWithName @, name, callback for name, callback of arg1 | |
# observeProperty <target>, <pattern>, <callback> | |
else if isRegExp arg1 | |
target.addPropertyObserverWithPattern @, arg1, arg2 | |
# observeProperty <target>, <names>, <callback> | |
else if isArray arg1 | |
for each1 in arg1 | |
if isString each1 | |
target.addPropertyObserverWithName @, each1, arg2 | |
else if isRegExp each1 | |
target.addPropertyObserverWithPattern @, each1, arg2 | |
else | |
@error 'neither name nor pattern specified in array:', each1 | |
# observeProperty <target>, <callback> | |
else | |
target.addPropertyObserverToAll @, arg1 | |
@ | |
# aliases: observeProperty | |
observeProperties: @::observeProperty | |
# method: dismissProperty <target>, <name>, [callback] | |
# method: dismissProperty <target>, <name: callback> | |
# method: dismissProperty <target>, <pattern>, [callback] | |
# method: dismissProperty <target>, <names>, [callback] | |
# method: dismissProperty <target>, [callback] | |
# returns: this | |
dismissProperty: (target, arg1, arg2) -> | |
@assert target?, 'cannot dismiss property of non-object type of target:', target | |
# dismissProperty <target>, <name>, [callback] | |
if isString arg1 | |
target.removePropertyObserverWithName @, arg1, arg2 | |
# dismissProperty <target>, <name: callback> | |
else if isObject arg1 | |
target.removePropertyObserverWithName @, type, callback for type, callback of arg1 | |
# dismissProperty <target>, <pattern>, [callback] | |
else if isRegExp arg1 | |
target.removePropertyObserverWithPattern @, arg1, arg2 | |
# dismissProperty <target>, <names>, [callback] | |
else if isArray arg1 | |
for each1 in arg1 | |
if isString each1 | |
target.removePropertyObserverWithName @, each1, arg2 | |
else if isRegExp each1 | |
target.removePropertyObserverWithPattern @, each1, arg2 | |
else | |
@error 'neither name nor pattern specified in array:', each1 | |
# dismissProperty <target>, [callback] | |
else | |
target.removePropertyObserverFromAll @, arg1 | |
@ | |
# aliases: dismissProperty | |
dismissProperties: @::dismissProperty | |
# method: addPropertyObserver <observer>, <name>, <callback> | |
# method: addPropertyObserver <observer>, <name: callback> | |
# method: addPropertyObserver <observer>, <pattern>, <callback> | |
# method: addPropertyObserver <observer>, <names>, <callback> | |
# method: addPropertyObserver <observer>, <callback> | |
# returns: this | |
addPropertyObserver: (observer, arg1, arg2) -> | |
@assert observer?, 'cannot add non-object type of property observer:', observer | |
# addPropertyObserver <observer>, <name>, <callback> | |
if isString arg1 | |
@addPropertyObserverWithName observer, arg1, arg2 | |
# addPropertyObserver <observer>, <name: callback> | |
else if isObject arg1 | |
@addPropertyObserverWithName observer, name, callback for name, callback of arg1 | |
# addPropertyObserver <observer>, <pattern>, <callback> | |
else if isRegExp arg1 | |
@addPropertyObserverWithPattern observer, arg1, arg2 | |
# addPropertyObserver <observer>, <names>, <callback> | |
else if isArray arg1 | |
for each1 in arg1 | |
if isString each1 | |
@addPropertyObserverWithName observer, each1, arg2 | |
else if isRegExp each1 | |
@addPropertyObserverWithPattern observer, each1, arg2 | |
else | |
@error 'neither name nor pattern specified in array:', each1 | |
# addPropertyObserver <observer>, <callback> | |
else | |
@addPropertyObserverToAll observer, arg1 | |
@ | |
# method: removePropertyObserver <observer>, <name>, [callback] | |
# method: removePropertyObserver <observer>, <name: callback> | |
# method: removePropertyObserver <observer>, <pattern>, [callback] | |
# method: removePropertyObserver <observer>, <names>, [callback] | |
# method: removePropertyObserver <observer>, [callback] | |
# method: removePropertyObserver | |
# returns: this | |
removePropertyObserver: (observer, arg1, arg2) -> | |
# removePropertyObserver <observer>, <name>, [callback] | |
if isString arg1 | |
@removePropertyObserverWithName observer, arg1, arg2 | |
# removePropertyObserver <observer>, <name: callback> | |
else if isObject arg1 | |
@removePropertyObserverWithName observer, name, callback for name, callback of arg1 | |
# removePropertyObserver <observer>, <pattern>, [callback] | |
else if isRegExp arg1 | |
@removePropertyObserverWithPattern observer, arg1, arg2 | |
# removePropertyObserver <observer>, <names>, [callback] | |
else if isArray arg1 | |
for each1 in arg1 | |
if isString each1 | |
@removePropertyObserverWithName observer, each1, arg2 | |
else if isRegExp each1 | |
@removePropertyObserverWithPattern observer, each1, arg2 | |
else | |
@error 'neither name nor pattern specified in array:', each1 | |
# removePropertyObserver <observer>, [callback] | |
else if observer? | |
@removePropertyObserverFromAll observer, arg1 | |
# removePropertyObserver | |
else | |
@removeAllPropertyObservers() | |
@ | |
# method: removeAllPropertyObservers | |
# return: this | |
removeAllPropertyObservers: -> | |
@__propertyObserversOfName = {} | |
@__propertyObserversOfPattern = {} | |
@__propertyObservers = {} | |
@ | |
#--------------------------------------------------------------------------- | |
# Notifying Property Change | |
# method: willChangeProperty <names...> | |
# method: willChangeProperty | |
# returns: this | |
willChangeProperty: (names...) -> | |
properties = @getClass().__properties | |
unless names.length | |
names = (name for name of properties) | |
names = names.flatten() | |
for name in names | |
property = properties[name] | |
if property? and property.bindable | |
@__valuesOfPropertyWillChange[name] = | |
if property.writeonly | |
clone @[property.internal] | |
else if property.clones | |
@[property.getter]() | |
else | |
clone @[property.getter]() | |
@ | |
# aliases: willChangeProperty | |
willChangeProperties: @::willChangeProperty | |
# method: didChangeProperty <names...> | |
# method: didChangeProperty | |
# returns: this | |
didChangeProperty: (names...) -> | |
properties = @getClass().__properties | |
unless names.length | |
names = (name for name of properties) | |
names = names.flatten() | |
for name in names | |
if name of @__valuesOfPropertyWillChange | |
property = properties[name] | |
value = | |
if property.writeonly | |
@[property.internal] | |
else | |
@[property.getter]() | |
oldValue = @__valuesOfPropertyWillChange[name] | |
delete @__valuesOfPropertyWillChange[name] | |
@notifyPropertyChange name, value, oldValue | |
else | |
@error 'cannot determine change of unbalanced property:', name, 'object:', @ | |
@ | |
# aliases: didChangeProperty | |
didChangeProperties: @::didChangeProperty | |
# method: notifyPropertyChange <name>, <value>, <oldValue> | |
# returns: this | |
notifyPropertyChange: (name, value, oldValue) -> | |
@postPropertyChangeNotification new Notification @, 'propertyChanged', | |
name: name | |
value: value | |
oldValue: oldValue | |
@ | |
# method: postPropertyChangeNotification <notification> | |
# return: this | |
postPropertyChangeNotification: (notification) -> | |
name = notification.name | |
args = [notification] | |
observers = @__propertyObserversOfName[name] | |
if observers? | |
for identifier, entry of observers | |
{context, callbacks} = entry | |
for callback in callbacks | |
callback.apply context, args | |
for pattern, observers of @__propertyObserversOfPattern | |
if self.__regexpOfPattern[pattern].test name | |
for identifier, entry of observers | |
{context, callbacks} = entry | |
for callback in callbacks | |
callback.apply context, args | |
for identifier, entry of @__propertyObservers | |
{context, callbacks} = entry | |
for callback in callbacks | |
callback.apply context, args | |
@ | |
#--------------------------------------------------------------------------- | |
# Managing Property Observer | |
# method: addPropertyObserverWithName <observer>, <name>, <callback> | |
# return: this | |
addPropertyObserverWithName: (observer, name, callback) -> | |
if isFunction callback | |
observers = @__propertyObserversOfName[name] | |
unless observers? | |
observers = @__propertyObserversOfName[name] = {} | |
entry = observers[observer.__identifier] | |
unless entry? | |
entry = observers[observer.__identifier] = | |
context: observer | |
callbacks: [callback] | |
else if entry.callbacks.indexOf(callback) is -1 | |
entry.callbacks.push callback | |
else | |
@error 'attempting to add duplicated property observer callback of name:', name, 'observer:', observer | |
else | |
@error 'cannot add non-function type of property observer callback:', callback, 'name:', name, 'observer:', observer | |
@ | |
# method: addPropertyObserverWithPattern <observer>, <pattern>, <callback> | |
# return: this | |
addPropertyObserverWithPattern: (observer, pattern, callback) -> | |
if isRegExp pattern | |
regexp = pattern | |
pattern = regexp.toString() | |
else | |
regexp = new RegExp pattern | |
self.__regexpOfPattern[pattern] = regexp | |
if isFunction callback | |
observers = @__propertyObserversOfPattern[pattern] | |
unless observers? | |
observers = @__propertyObserversOfPattern[pattern] = {} | |
entry = observers[observer.__identifier] | |
unless entry? | |
entry = observers[observer.__identifier] = | |
context: observer | |
callbacks: [callback] | |
else if entry.callbacks.indexOf(callback) is -1 | |
entry.callbacks.push callback | |
else | |
@error 'attempting to add duplicated property observer callback of pattern:', pattern, 'observer:', observer | |
else | |
@error 'cannot add non-function type of property observer callback:', callback, 'pattern:', pattern, 'observer:', observer | |
@ | |
# method: addPropertyObserverToAll <observer>, <callback> | |
# return: this | |
addPropertyObserverToAll: (observer, callback) -> | |
if isFunction callback | |
entry = @__propertyObservers[observer.__identifier] | |
unless entry? | |
entry = @__propertyObservers[observer.__identifier] = | |
context: observer | |
callbacks: [callback] | |
else if entry.callbacks.indexOf(callback) is -1 | |
entry.callbacks.push callback | |
else | |
@error 'attempting to add duplicated property observer callback of observer:', observer | |
else | |
@error 'cannot add non-function type of property observer callback:', callback, 'observer:', observer | |
@ | |
# method: removePropertyObserverWithName <observer>, <name>, [callback] | |
# return: this | |
removePropertyObserverWithName: (observer, name, callback) -> | |
observers = @__propertyObserversOfName[name] | |
if observers? | |
unless callback? | |
delete observers[observer.__identifier] | |
else | |
entry = observers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__propertyObserversOfName[name] | |
@ | |
# method: removePropertyObserverWithPattern <observer>, <pattern>, [callback] | |
# return: this | |
removePropertyObserverWithPattern: (observer, pattern, callback) -> | |
if isRegExp pattern | |
pattern = pattern.toString() | |
observers = @__propertyObserversOfPattern[pattern] | |
if observers? | |
unless callback? | |
delete observers[observer.__identifier] | |
else | |
entry = observers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__propertyObserversOfPattern[pattern] | |
@ | |
# method: removePropertyObserverFromAll <observer>, [callback] | |
# return: this | |
removePropertyObserverFromAll: (observer, callback) -> | |
unless callbacks? | |
for name, observers of @__propertyObserversOfName | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__propertyObserversOfName[name] | |
for pattern, observers of @__propertyObserversOfPattern | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__propertyObserversOfPattern[pattern] | |
@__propertyObservers = [] | |
else | |
for name, observers of @__propertyObserversOfName | |
entry = observers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__propertyObserversOfName[name] | |
for pattern, observers of @__propertyObserversOfPattern | |
entry = observers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete observers[observer.__identifier] | |
if isEmpty observers | |
delete @__propertyObserversOfPattern[pattern] | |
entry = @__propertyObservers[observer.__identifier] | |
if entry? | |
callbacks = entry.callbacks | |
index = callbacks.indexOf callback | |
if index isnt -1 | |
callbacks.splice index, 1 | |
unless callbacks.length | |
delete @__propertyObservers[observer.__identifier] | |
@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Process extends Observable | |
self = @initialize() | |
@property | |
started: | |
attributes: bindable | |
defaults: yes | |
converter: Boolean | |
@property | |
needsUpdate: | |
defaults: yes | |
converter: Boolean | |
#--------------------------------------------------------------------------- | |
# Initialization | |
# method : initialize [parameters] | |
# returns : this | |
initialize: (parameters) -> | |
super() | |
@setProperties parameters | |
application.attachProcess @ | |
@ | |
#--------------------------------------------------------------------------- | |
# Managing Process Cycle | |
# method: process | |
# returns: this | |
process: -> | |
if @_needsUpdate | |
@setNeedsUpdate no | |
@update() | |
@ | |
# method: update | |
# returns: this | |
update: -> @ | |
# method: invalidate | |
# returns: this | |
invalidate: -> | |
application.detachProcess @ | |
@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment