2015-01-23 13:09:30 +00:00
|
|
|
/**
|
|
|
|
* The main base class. Manages the signal system.
|
|
|
|
*
|
|
|
|
* @param signals Map with all connected signal handlers
|
|
|
|
**/
|
|
|
|
Vn.Object = new Class
|
|
|
|
({
|
|
|
|
Tag: 'vn-object'
|
|
|
|
,Properties: {}
|
2015-07-28 19:14:26 +00:00
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
,signals: {}
|
2015-07-28 19:14:26 +00:00
|
|
|
,links: {}
|
|
|
|
,refCount: 1
|
2015-01-23 13:09:30 +00:00
|
|
|
|
|
|
|
,initialize: function (props)
|
|
|
|
{
|
|
|
|
for (var prop in props)
|
|
|
|
this[prop] = props[prop];
|
|
|
|
}
|
|
|
|
|
2015-07-28 19:14:26 +00:00
|
|
|
,ref: function ()
|
|
|
|
{
|
|
|
|
this.refCount++;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
,unref: function ()
|
|
|
|
{
|
|
|
|
this.refCount--;
|
|
|
|
|
|
|
|
if (this.refCount === 0)
|
|
|
|
this._destroy ();
|
|
|
|
}
|
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
,loadXml: function (builder, node)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Conects a signal with a function.
|
|
|
|
*
|
|
|
|
* @param {String} id The signal identifier
|
|
|
|
* @param {Function} callback The callback
|
|
|
|
* @param {Object} instance The instance
|
|
|
|
**/
|
|
|
|
,on: function (id, callback, instance)
|
2015-07-17 14:34:42 +00:00
|
|
|
{
|
|
|
|
if (!(callback instanceof Function))
|
|
|
|
{
|
|
|
|
console.warn ('Vn.Object: Invalid callback for signal \'%s\'', id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
if (!this.signals[id])
|
|
|
|
this.signals[id] = [];
|
|
|
|
|
|
|
|
this.signals[id].push
|
|
|
|
({
|
|
|
|
blocked: false
|
|
|
|
,callback: callback
|
|
|
|
,instance: instance
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Locks/Unlocks a signal emission to the specified object.
|
|
|
|
*
|
|
|
|
* @param {String} id The signal identifier
|
|
|
|
* @param {Function} callback The callback
|
|
|
|
* @param {Boolean} block %true for lock the signal, %false for unlock
|
|
|
|
**/
|
2015-07-28 19:14:26 +00:00
|
|
|
,blockSignal: function (id, callback, block, instance)
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
|
|
|
var callbacks = this.signals[id];
|
|
|
|
|
|
|
|
if (!callbacks)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (var i = 0; i < callbacks.length; i++)
|
2015-07-28 19:14:26 +00:00
|
|
|
if (callbacks[i].callback == callback
|
|
|
|
&& callbacks[i].instance == instance)
|
2015-01-23 13:09:30 +00:00
|
|
|
callbacks[i].blocked = block;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Emits a signal in the current object.
|
|
|
|
*
|
|
|
|
* @param {String} id The signal identifier
|
|
|
|
**/
|
|
|
|
,signalEmit: function (id)
|
|
|
|
{
|
|
|
|
var callbacks = this.signals[id];
|
|
|
|
|
|
|
|
if (!callbacks)
|
|
|
|
return;
|
|
|
|
|
|
|
|
var callbackArgs = [];
|
|
|
|
callbackArgs.push (this);
|
|
|
|
|
|
|
|
for (var i = 1; i < arguments.length; i++)
|
|
|
|
callbackArgs.push (arguments[i]);
|
|
|
|
|
|
|
|
for (var i = 0; i < callbacks.length; i++)
|
|
|
|
if (!callbacks[i].blocked)
|
|
|
|
callbacks[i].callback.apply (callbacks[i].instance, callbackArgs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Disconnects a signal from current object.
|
|
|
|
*
|
|
|
|
* @param {String} id The signal identifier
|
|
|
|
* @param {Function} callback The connected callback
|
|
|
|
* @param {Object} instance The instance
|
|
|
|
**/
|
|
|
|
,disconnect: function (id, callback, instance)
|
|
|
|
{
|
|
|
|
var callbacks = this.signals[id];
|
|
|
|
|
|
|
|
if (!callbacks)
|
|
|
|
return;
|
2015-07-28 19:14:26 +00:00
|
|
|
|
2015-01-23 13:09:30 +00:00
|
|
|
for (var i = 0; i < callbacks.length; i++)
|
|
|
|
if (callbacks[i].callback == callback
|
|
|
|
&& callbacks[i].instance == instance)
|
|
|
|
callbacks.splice (i--, 1);
|
|
|
|
}
|
2015-07-28 19:14:26 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Disconnects all signals for the given instance.
|
|
|
|
*
|
|
|
|
* @param {Object} instance The instance
|
|
|
|
**/
|
|
|
|
,disconnectByInstance: function (instance)
|
|
|
|
{
|
|
|
|
for (var signalId in this.signals)
|
|
|
|
{
|
|
|
|
var callbacks = this.signals[signalId];
|
|
|
|
|
|
|
|
for (var i = 0; i < callbacks.length; i++)
|
|
|
|
if (callbacks[i].instance == instance)
|
|
|
|
callbacks.splice (i--, 1);
|
|
|
|
}
|
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroys the object, this method should only be called before losing
|
|
|
|
* the last reference to the object.
|
|
|
|
**/
|
2015-07-28 19:14:26 +00:00
|
|
|
,_destroy: function ()
|
2015-01-23 13:09:30 +00:00
|
|
|
{
|
2015-07-28 19:14:26 +00:00
|
|
|
var links = this.links;
|
|
|
|
|
|
|
|
for (var key in links)
|
|
|
|
links[key].disconnectByInstance (this);
|
|
|
|
|
|
|
|
delete this.links;
|
2015-01-23 13:09:30 +00:00
|
|
|
delete this.signals;
|
|
|
|
}
|
|
|
|
|
|
|
|
,link: function (prop, handlers)
|
|
|
|
{
|
|
|
|
for (var key in prop)
|
|
|
|
{
|
|
|
|
var newObject = prop[key];
|
|
|
|
var oldObject = this[key];
|
|
|
|
|
|
|
|
if (oldObject)
|
2015-07-28 19:14:26 +00:00
|
|
|
{
|
|
|
|
oldObject.disconnectByInstance (this);
|
|
|
|
oldObject.unref ();
|
|
|
|
}
|
2015-01-23 13:09:30 +00:00
|
|
|
|
|
|
|
this[key] = newObject;
|
|
|
|
|
|
|
|
if (newObject)
|
2015-07-28 19:14:26 +00:00
|
|
|
{
|
|
|
|
this.links[key] = newObject.ref ();
|
|
|
|
|
|
|
|
for (var signal in handlers)
|
|
|
|
newObject.on (signal, handlers[signal], this);
|
|
|
|
}
|
|
|
|
else if (oldObject)
|
|
|
|
delete this.links[key];
|
2015-01-23 13:09:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|