2 * The same functionality as EventEmitter but with the inclusion of callbacks
7 function PluginInterface () {
8 // Holder for all the bound listeners by this module
14 PluginInterface
.prototype.on = function (event_name
, fn
, scope
) {
15 this._listeners
[event_name
] = this._listeners
[event_name
] || [];
16 this._listeners
[event_name
].push(['on', fn
, scope
]);
21 PluginInterface
.prototype.once = function (event_name
, fn
, scope
) {
22 this._listeners
[event_name
] = this._listeners
[event_name
] || [];
23 this._listeners
[event_name
].push(['once', fn
, scope
]);
28 PluginInterface
.prototype.off = function (event_name
, fn
, scope
) {
31 if (typeof event_name
=== 'undefined') {
32 // Remove all listeners
35 } else if (typeof fn
=== 'undefined') {
36 // Remove all of 1 event type
37 delete this._listeners
[event_name
];
39 } else if (typeof scope
=== 'undefined') {
40 // Remove a single event type + callback
41 for (idx
in (this._listeners
[event_name
] || [])) {
42 if (this._listeners
[event_name
][idx
][1] === fn
) {
43 delete this._listeners
[event_name
][idx
];
47 // Remove a single event type + callback + scope
48 for (idx
in (this._listeners
[event_name
] || [])) {
49 if (this._listeners
[event_name
][idx
][1] === fn
&& this._listeners
[event_name
][idx
][2] === scope
) {
50 delete this._listeners
[event_name
][idx
];
58 // Call all the listeners for a certain event, passing them some event data that may be changed
59 PluginInterface
.prototype.emit = function (event_name
, event_data
) {
60 var emitter
= new this.EmitCall(event_name
, event_data
);
61 var listeners
= this._listeners
[event_name
] || [];
63 // Once emitted, remove any 'once' bound listeners
64 emitter
.done(function () {
65 var len
= listeners
.length
,
68 for(idx
= 0; idx
< len
; idx
++) {
69 if (listeners
[idx
][0] === 'once') {
70 listeners
[idx
] = undefined;
75 // Emit the event to the listeners and return
76 emitter
.callListeners(listeners
);
82 // Promise style object to emit events to listeners
83 PluginInterface
.prototype.EmitCall
= function EmitCall (event_name
, event_data
) {
88 // Has event.preventDefault() been called
93 // Emit this event to an array of listeners
94 function callListeners(listeners
) {
95 var current_event_idx
= -1;
97 // Make sure we have some data to pass to the listeners
98 event_data
= event_data
|| undefined;
100 // If no bound listeners for this event, leave now
101 if (listeners
.length
=== 0) {
107 // Call the next listener in our array
108 function nextListener() {
109 var listener
, event_obj
;
111 // We want the next listener
114 // If we've ran out of listeners end this emit call
115 if (!listeners
[current_event_idx
]) {
120 // Object the listener ammends to tell us what it's going to do
122 // If changed to true, expect this listener is going to callback
125 // If wait is true, this callback must be called to continue running listeners
126 callback: function () {
127 // Invalidate this callback incase a listener decides to call it again
128 event_obj
.callback
= undefined;
130 nextListener
.apply(that
);
133 // Prevents the default 'done' functions from executing
134 preventDefault: function () {
140 listener
= listeners
[current_event_idx
];
141 listener
[1].call(listener
[2] || that
, event_obj
, event_data
);
143 // If the listener hasn't signalled it's going to wait, proceed to next listener
144 if (!event_obj
.wait
) {
145 // Invalidate the callback just incase a listener decides to call it anyway
146 event_obj
.callback
= undefined;
157 function emitComplete() {
160 var funcs
= prevented
? prevented_fn
: completed_fn
;
163 // Call the completed/prevented functions
164 for (var idx
= 0; idx
< funcs
.length
; idx
++) {
165 if (typeof funcs
[idx
] === 'function') funcs
[idx
]();
171 function addCompletedFunc(fn
) {
172 // Only accept functions
173 if (typeof fn
!== 'function') return false;
175 completed_fn
.push(fn
);
177 // If we have already completed the emits, call this now
178 if (completed
&& !prevented
) fn();
185 function addPreventedFunc(fn
) {
186 // Only accept functions
187 if (typeof fn
!== 'function') return false;
189 prevented_fn
.push(fn
);
191 // If we have already completed the emits, call this now
192 if (completed
&& prevented
) fn();
199 callListeners
: callListeners
,
200 done
: addCompletedFunc
,
201 prevented
: addPreventedFunc
207 // If running a node module, set the exports
208 if (typeof module
=== 'object' && typeof module
.exports
!== 'undefined') {
209 module
.exports
= PluginInterface
;
220 var modules = new PluginInterface();
225 modules.on('client:command', function (event, data) {
227 setTimeout(event.callback, 2000);
233 // Core code that is being extended by plugins
240 modules.emit('client:command', data).done(function () {
241 console.log('Your command is: ' + data.command);