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