Skip to content

Instantly share code, notes, and snippets.

@ar-nelson
Last active December 21, 2015 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ar-nelson/6330779 to your computer and use it in GitHub Desktop.
Save ar-nelson/6330779 to your computer and use it in GitHub Desktop.
node.js EventEmitter wrapper for the wmii event loop.
// wmii event handler module
// Adam R. Nelson
// August 2013
var events = require('events');
var util = require('util');
var wmiir = require('./wmiir.js');
function WmiiEvents() {
events.EventEmitter.call(this);
var me = this;
me.readProc = wmiir.read('/event', function(err, line) {
var tokens;
if (err) {
// In the event of an error, emit a 'FatalError' event.
tokens = ['FatalError', err.message || err];
} else {
// Split the line (minus the trailing newline) into tokens.
tokens = line.split(" ");
}
// Emit a Node event based on the wmii event.
// (The emit method is renamed below so that it can be overridden).
me.emit_.apply(me, tokens);
});
// Turn off the max-listeners limit, since there will be a LOT of listeners
// attached to this object.
me.setMaxListeners(0);
// The wmiir process will keep running forever until it is killed. Make
// sure it is always killed before Node exits.
function cleanup() {
me.readProc.kill();
}
process.on('exit', cleanup);
me.on('FatalError', function(/* varargs */) {
// The message will be split up into string-separated tokens, which
// need to be rejoined. Array.prototype.slice is needed to convert
// 'arguments' to a real array, because Javascript.
var message = Array.prototype.slice.apply(arguments).join(' ');
console.log("Fatal error occurred! - " + message);
cleanup();
});
}
// Extend EventEmitter.
util.inherits(WmiiEvents, events.EventEmitter);
// Rename the original emit method...
WmiiEvents.prototype.emit_ = WmiiEvents.prototype.emit;
// ... and add a new one that broadcasts events globally.
WmiiEvents.prototype.emit = function(/* No arg names; this is varargs. */) {
// Convert 'arguments' to an array, because it's not by default.
// (*sigh* Javascript...)
var eventParts = Array.prototype.slice.call(arguments);
var me = this;
// Remove any problematic newline-containing elements and non-string
// elements from the array.
eventParts = eventParts.filter(function(e) {
return (typeof e == 'string' || e instanceof String) && e.indexOf('\n') == -1;
});
// Write a space-separated event string to the /event file.
wmiir.write('/event', eventParts.join(' '), function(err) {
if (err) {
// If an error occurs, broadcast an event.
me.emit_('Error', err);
}
});
// Always return true... the original emit() returns true if there was a
// listener for the event, but there may always be another process
// listening in this case.
return true;
};
// Call this function to terminate the event listener without terminating Node.
WmiiEvents.stopListening = function() {
this.readProc.kill('SIGHUP');
};
// Export a single copy of the event handler object.
module.exports = new WmiiEvents();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment