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