-
-
Save shimondoodkin/4369108 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
//licence: 2 clouse mit, by Shimon Doodkin | |
function ObserverPubSub(parent, key_of_myself) { | |
this._topics = {}; | |
this.length = 0; | |
this._subUid = -1; | |
this._parent = parent; | |
this._name = key_of_myself; | |
} | |
ObserverPubSub.prototype = { | |
//pubsub | |
on: function(topic, func, token) { | |
var topics = this._topics; | |
if (!topics[topic]) { | |
topics[topic] = []; | |
} | |
if (arguments.length == 2) token = (++this._subUid).toString(); | |
topics[topic].push({ | |
token: token, | |
func: func | |
}); | |
return token; | |
}, | |
emit: function(topic) { | |
var topics = this._topics, | |
args = arguments; | |
if (!topics[topic]) { | |
return false; | |
} | |
setTimeout(function() { | |
var subscribers = topics[topic], | |
len = subscribers ? subscribers.length : 0; | |
while (len--) { | |
subscribers[len].func.apply(this, args); | |
} | |
}, 0); | |
return true; | |
}, | |
unsub: function(token) { | |
var topics = this._topics; | |
for (var m in topics) { | |
if (topics[m]) { | |
for (var i = 0, j = topics[m].length; i < j; i++) { | |
if (topics[m][i].token === token) { | |
topics[m].splice(i, 1); | |
if (topics[m].length == 0) delete topics[m]; | |
return token; | |
} | |
} | |
} | |
} | |
return false; | |
}, | |
//observer | |
emit_recursive: function() { | |
this.emit.apply(this, arguments) | |
if (this._parent) this._parent.emit.apply(this._parent, arguments) | |
}, | |
add: function(k, v) { | |
var objv = new ObserverPubSub(this, k); | |
this[k] = objv; | |
objv._set(v); | |
this.emit('add', k, v); | |
if (this._parent) this._parent.emit_recursive('childadd', this, this._name); | |
return k; | |
}, | |
_remove: function(k) { | |
var deleted=this[k]; | |
if(typeof k=='string') | |
{ | |
delete this[k]; | |
} | |
else | |
{ | |
if(k<0) throw new Error('bad index to remove'); | |
var deleted=this[k]; | |
for(var i=k,l=this.length-1;i<this.length;i++) | |
{ | |
this[i]=this[i+1] | |
} | |
delete this[i+1]; | |
this.length--; | |
} | |
if(deleted instanceof ObserverPubSub) deleted.emit('remove', k, deleted); | |
return deleted; | |
}, | |
indexOf: function(o) { | |
var k=-1; | |
for(var i=0,l=this.length;i<l;i++) | |
{ | |
if(this[i]===o)k=i; break; | |
} | |
return k; | |
}, | |
free(){// useless fn | |
for(var i=this.length-1;i>0;i--) | |
{ | |
if(this[i] instanceof ObserverPubSub) this.remove(i); | |
} | |
/* | |
if(this._value)delete this._value; | |
for(var i=0,l=this.length;i<l;i++) | |
{ | |
if(this[i] instanceof ObserverPubSub) this[i].remove(); | |
delete this[i] | |
//delete this[i]._parent | |
//delete this[i]._name | |
} | |
var topics = this._topics; | |
for (var m in topics) { | |
if (topics[m]) { | |
for (var i = 0, j = topics[m].length; i < j; i++) { | |
delete topics[m] | |
} | |
} | |
delete topics[m]; | |
} | |
delete this._topics; | |
delete this.length; | |
delete this._subUid; | |
delete this._parent; | |
delete this._name;*/ | |
}, | |
remove: function(k,free) { | |
free=free!==undefined?free:true; | |
if(k===true||k===false){free=k;k=undefined;} | |
if(k !== undefined) | |
{ | |
var deleted; | |
deleted=this._remove(k); | |
deleted.emit('remove', k, deleted); | |
var from_Parent=this; | |
this.emit_recursive('childremove', deleted, k, from_Parent); | |
this.emit('change'); //watch this later | |
//this.emit('change', k, v); | |
if (this._parent) this._parent.emit_recursive('childchange', this, this._name); | |
if(free)if(deleted instanceof ObserverPubSub) deleted.free(); | |
return deleted; | |
} | |
else | |
{ | |
if(this._parent){ return _parent.remove(this._name);} | |
else { if(free)this.free();)} | |
} | |
}, | |
push: function(v) { | |
var k = this.length++; | |
this.add(k, v); | |
this.emit('length', this.length); | |
return k; | |
}, | |
_set: function(k, v) { | |
var isnew = this[k] === undefined; | |
if (arguments.length == 1) { | |
v = k; | |
k = '_value'; | |
} | |
if (this[k] instanceof ObserverPubSub) return this[k].set(v); | |
this[k] = v; | |
this.emit('set', k, v); | |
if (this._parent) this._parent.emit_recursive('childset', this, this._name); | |
return isnew; | |
}, | |
set: function(k, v) { | |
if (!this._set.apply(this, arguments)) { | |
this.emit('change', k, v); | |
if (this._parent) this._parent.emit_recursive('childchange', this, this._name); | |
} | |
}, | |
get: function(k) { | |
if (arguments.length == 0) return this['_value']; | |
return this[k]; | |
}, | |
toArray: function() { | |
var arr=[]; | |
for (var i = 0, j = this.length; i < j; i++) { | |
arr[i]=this[i]; | |
} | |
return arr; | |
} | |
}; | |
//var arr= new ObserverPubSub(); | |
//pubsub: | |
//var token=arr.on('foo',function(){})//token='0' | |
//arr._topics | |
//arr.unsub('0') | |
//arr.on('set',function(eventname,key,value){console.log(eventname,key,value)}) | |
//arr.on('add',function(eventname,key,value){console.log(eventname,key,value)}) | |
//arr.on('change',function(eventname,key,value){console.log(eventname,key,value)}) | |
//arr.on('length',function(eventname,key,value){console.log(eventname,key,value)}) | |
//arr.on('childset',function(eventname,key,value){console.log(eventname,key,value)}) | |
//arr.on('childadd',function(eventname,key,value){console.log(eventname,key,value)}) | |
//arr.on('childremove',function(eventname,key,value){console.log(eventname,key,value)}) | |
//arr.on('remove',function(eventname,key,value){console.log(eventname,key,value)}) | |
//arr.on('childchange',function(eventname,key,value){console.log(eventname,key,value)}) | |
//observer: | |
//arr.add('key',"value"); | |
//arr.set('key',"value"); | |
//arr.push("value");//add with key=length,length++ | |
//arr.get('key'); | |
//arr.get(); // key='_value' | |
//arr.set("value"); // key='_value' | |
//arr.remove(); // emit remove this and remove this from parent,also delete children | |
//arr.remove("value"); // remove a child ,also delete its children | |
//arr.remove(false); // emit remove this and remove this from parent,dont delete child children | |
//arr.remove("value",false); // remove a child ,dont delete its children | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment