ami/src/ami.js/watcher.js

86 lines
2.3 KiB
JavaScript

#include utility.js
var AmiWatcher = function() {
var watchers = [];
return {
watch: function(watcher, thisArg, args) {
if(typeof watcher !== 'function')
throw 'watcher must be a function';
if(watchers.indexOf(watcher) >= 0)
return;
watchers.push(watcher);
if(thisArg !== undefined) {
if(!Array.isArray(args)) {
if(args !== undefined)
args = [args];
else args = [];
}
// initial call
args.push(true);
watcher.apply(thisArg, args);
}
},
unwatch: function(watcher) {
$ari(watchers, watcher);
},
call: function(thisArg, args) {
if(!Array.isArray(args)) {
if(args !== undefined)
args = [args];
else args = [];
}
args.push(false);
for(var i in watchers)
watchers[i].apply(thisArg, args);
},
};
};
var AmiWatcherCollection = function() {
var collection = new Map;
var watch = function(name, watcher, thisArg, args) {
var watchers = collection.get(name);
if(watchers === undefined)
throw 'undefined watcher name';
watchers.watch(watcher, thisArg, args);
};
var unwatch = function(name, watcher) {
var watchers = collection.get(name);
if(watchers === undefined)
throw 'undefined watcher name';
watchers.unwatch(watcher);
};
return {
define: function(names) {
if(!Array.isArray(names))
names = [names];
for(var i in names)
collection.set(names[i], new AmiWatcher);
},
call: function(name, thisArg, args) {
var watchers = collection.get(name);
if(watchers === undefined)
throw 'undefined watcher name';
watchers.call(thisArg, args);
},
watch: watch,
unwatch: unwatch,
proxy: function(obj) {
obj.watch = function(name, watcher) {
watch(name, watcher);
};
obj.unwatch = unwatch;
},
};
};