Commit | Line | Data |
---|---|---|
1920a38e | 1 | var events = require('events'), |
991091b7 D |
2 | util = require('util'), |
3 | _ = require('lodash'); | |
1920a38e D |
4 | |
5 | ||
991091b7 D |
6 | /** |
7 | * Publisher | |
8 | * The main point in which events are fired and bound to | |
9 | */ | |
10 | ||
1920a38e D |
11 | // Where events are bound to |
12 | var active_publisher; | |
13 | ||
14 | ||
15 | // Create a publisher to allow event subscribing | |
16 | function Publisher (obj) { | |
991091b7 D |
17 | var EventPublisher = function modulePublisher() {}; |
18 | util.inherits(EventPublisher, events.EventEmitter); | |
1920a38e | 19 | |
991091b7 | 20 | return new EventPublisher(); |
874f28a5 | 21 | } |
1920a38e D |
22 | |
23 | ||
24 | // Register an already created Publisher() as the active instance | |
25 | function registerPublisher (obj) { | |
991091b7 D |
26 | active_publisher = obj; |
27 | } | |
28 | ||
29 | ||
30 | ||
31 | ||
32 | ||
33 | ||
34 | /** | |
35 | * Keeping track of modules | |
36 | */ | |
37 | ||
38 | // Hold the loaded modules | |
39 | var registered_modules = {}; | |
40 | ||
41 | function loadModule (module_file) { | |
42 | var module; | |
43 | ||
44 | // Get an instance of the module and remove it from the cache | |
45 | try { | |
46 | module = require(module_file); | |
47 | delete require.cache[require.resolve(module_file)]; | |
48 | } catch (err) { | |
49 | // Module was not found | |
50 | return false; | |
51 | } | |
52 | ||
53 | return module; | |
1920a38e D |
54 | } |
55 | ||
56 | ||
991091b7 D |
57 | // Find a registered collection, .dispose() of it and remove it |
58 | function unloadModule (module) { | |
59 | registered_modules = _.reject(registered_modules, function (registered_module) { | |
60 | if (module === registered_module) { | |
61 | module.dispose(); | |
62 | return true; | |
63 | } | |
64 | }); | |
65 | } | |
66 | ||
67 | ||
68 | ||
69 | ||
1920a38e | 70 | |
1920a38e | 71 | |
874f28a5 D |
72 | /** |
73 | * Module object | |
74 | * To be created by modules to bind to server events | |
75 | */ | |
991091b7 D |
76 | function Module (module_name) { |
77 | registered_modules[module_name] = this; | |
78 | } | |
1920a38e | 79 | |
1920a38e | 80 | |
874f28a5 D |
81 | // Holder for all the bound events by this module |
82 | Module.prototype._events = {}; | |
1920a38e | 83 | |
1920a38e | 84 | |
874f28a5 | 85 | // Keep track of this modules events and bind |
991091b7 D |
86 | Module.prototype.on = function (event_name, fn) { |
87 | var internal_events = ['dispose']; | |
88 | ||
89 | this._events[event_name] = this._events[event_name] || []; | |
90 | this._events[event_name].push(fn); | |
1920a38e | 91 | |
991091b7 D |
92 | // If this is an internal event, do not propogate the event |
93 | if (internal_events.indexOf(event_name) !== -1) { | |
94 | active_publisher.on(event_name, fn); | |
95 | } | |
874f28a5 | 96 | }; |
1920a38e | 97 | |
1920a38e | 98 | |
874f28a5 D |
99 | // Keep track of this modules events and bind once |
100 | Module.prototype.once = function (event_name, fn) { | |
991091b7 D |
101 | this._events[event_name] = this._events[event_name] || []; |
102 | this._events[event_name].push(fn); | |
874f28a5 | 103 | |
991091b7 | 104 | active_publisher.once(event_name, fn); |
874f28a5 | 105 | }; |
1920a38e D |
106 | |
107 | ||
874f28a5 | 108 | // Remove any events by this module only |
991091b7 D |
109 | Module.prototype.off = function (event_name, fn) { |
110 | var idx; | |
111 | ||
112 | if (typeof event_name === 'undefined') { | |
113 | // Remove all events | |
114 | this._events = []; | |
115 | ||
116 | } else if (typeof fn === 'undefined') { | |
117 | // Remove all of 1 event type | |
118 | delete this._events[event_name]; | |
119 | ||
120 | } else { | |
121 | // Remove a single event + callback | |
122 | for (idx in (this._events[event_name] || [])) { | |
123 | if (this._events[event_name][idx] === fn) { | |
124 | delete this._events[event_name][idx]; | |
125 | } | |
126 | } | |
127 | } | |
128 | ||
129 | active_publisher.removeListener(event_name, fn); | |
874f28a5 | 130 | }; |
1920a38e D |
131 | |
132 | ||
991091b7 | 133 | |
874f28a5 D |
134 | // Clean up anything used by this module |
135 | Module.prototype.dispose = function () { | |
991091b7 D |
136 | // Call any dispose callbacks |
137 | (this._events['dispose'] || []).forEach(function (callback) { | |
138 | callback(); | |
139 | }); | |
140 | ||
141 | // Remove all bound event listeners | |
142 | this.off(); | |
1920a38e D |
143 | }; |
144 | ||
145 | ||
146 | ||
874f28a5 D |
147 | |
148 | ||
149 | ||
1920a38e | 150 | module.exports = { |
991091b7 D |
151 | // Objects |
152 | Module: Module, | |
153 | Publisher: Publisher, | |
154 | ||
155 | // Methods | |
156 | registerPublisher: registerPublisher, | |
157 | load: loadModule, | |
158 | unload: unloadModule, | |
159 | getRegisteredModules: function () { return registered_modules; } | |
1920a38e | 160 | }; |