Pawel Chmielowski - Object.Slot-0.01
NAME
Object.Slot
DESCRIPTION
This module adds functions for managing slots and signals.
Object.Slot.connect(SLOTOBJECT, SLOTNAME, SIGNALOBJECT, SIGNALNAME)
Connects SIGNALNAME method from SIGNALOBJECT to SLOTNAME method on SLOTOBJECT object.
Any further invocation of SLOTNAME will automaticaly also execute SIGNALOBJECT method with arguments passed to primary method.
Object.Slot.disconnect(SLOTOBJECT, SLOTNAME, SIGNALOBJECT, SIGNALNAME)
Disonnects SIGNALNAME method from SIGNALOBJECT object from SLOTNAME method on SLOTOBJECT object.
This break links between SLOTNAME method and SIGNALNAME created by Object.Slot.connect
.
Next invocations of SLOTNAME will not be dispatched to SIGNALOBJECT.
AUTHOR
Pawel Chmielowski <prefiks@aviary.pl>
/* =head1 NAME Object.Slot =head1 DESCRIPTION This module adds functions for managing slots and signals. =cut */ try { JSAN.use( 'List.Utils' ); } catch (e) { throw "Object.Slot requires JSAN to be loaded"; } if (!Object.Slot) { Object.Slot = { VERSION: "0.01", /* =head2 Object.Slot.connect(SLOTOBJECT, SLOTNAME, SIGNALOBJECT, SIGNALNAME) Connects SIGNALNAME method from SIGNALOBJECT to SLOTNAME method on SLOTOBJECT object. Any further invocation of SLOTNAME will automaticaly also execute SIGNALOBJECT method with arguments passed to primary method. =cut */ connect: function(obj, slotName, signalObj, signalMethodName) { var base; if (slotName in obj) { if (obj[slotName] != null && typeof(obj[slotName]) != "function") throw "Object.Slot.connect() can be used only on function slots."; if (obj[slotName].__SLOT_SIGNALS__) { insertIntoList(obj[slotName].__SLOT_SIGNALS__, [signalObj, signalMethodName], function(a){return a[0] == signalObj && a[1] == signalMethodName}); return; } base = obj[slotName]; } obj[slotName] = function() { var res, i, signals, exc; if (arguments.callee.__SLOT_BASE__) res = arguments.callee.__SLOT_BASE__.apply(this, arguments); try { var i, signals = arguments.callee.__SLOT_SIGNALS__; for (i = 0; i < signals.length; i++) { signal=signals[i]; signal[0][signal[1]].apply(signal[0], arguments); } } catch (ex) { } return res; } if (base) obj[slotName].__SLOT_BASE__ = base; obj[slotName].__SLOT_SIGNALS__ = [[signalObj, signalMethodName]]; }, /* =head2 Object.Slot.disconnect(SLOTOBJECT, SLOTNAME, SIGNALOBJECT, SIGNALNAME) Disonnects SIGNALNAME method from SIGNALOBJECT object from SLOTNAME method on SLOTOBJECT object. This break links between SLOTNAME method and SIGNALNAME created by C<Object.Slot.connect>. Next invocations of SLOTNAME will not be dispatched to SIGNALOBJECT. =cut */ disconnect: function(obj, slotName, signalObj, signalMethodName) { if (obj[slotName] == null || typeof(obj[slotName]) != "function" || !obj[slotName].__SLOT_SIGNALS__) return; removeFromList(obj[slotName].__SLOT_SIGNALS__, [signalObj, signalMethodName], function(a){return a[0] == signalObj && a[1] == signalMethodName}); if (obj[slotName].__SLOT_SIGNALS__.length > 0) return; obj[slotName] = obj[slotName].__SLOT_BASE__; } } } /* =head1 AUTHOR Pawel Chmielowski <prefiks@aviary.pl> =cut */