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