Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I'm creating an event hub object in for a large project I am building in Javascript. The project will have modules in charge of the UI, commands, and rendering. Each module will use this hub for broadcasting events to each other.

This is my Javascript library (I cut out RequireJS for conciseness):

Hub = Object.create ({});
// initialize this hub
Hub.init = function () {
    this.events = {};
    this.contexts = {};
    return this;
};
// register a function and context
Hub.on = function (name, callback, contexts) {
    // create event type if it isn't already and push our callback
    (this.events [name] || (this.events [name] = [])).push (callback);
    (this.contexts [name] || (this.contexts [name] = [])).push (contexts);
};
// un-register a function
Hub.off = function (name, callback) {
    // if this event type exists, splice out our callback
    this.events [name] && this.events [name].splice (this.events [name].indexOf (callback), 1);
    this.contexts [name] && this.contexts [name].splice (this.events [name].indexOf (callback), 1);
};
// fire all of a type of functions
Hub.trigger = function (name) {
    if (!this.events [name] || this.events [name].length === 0) return;
    var args = Array.prototype.slice.call (arguments, 1),
        i = 0, event = this.events [name], context = this.contexts [name], l = event.length;
    // if this event type exists, run all the callbacks
    for (; i < l; event [i].apply (context [i++], args));
};

And this about how it is used:

// MAIN.JS: create the main hub
Main.hub = Object.create (Hub);

// RENDER.JS: listen for entity addition
Main.hub.on ('entity_add', function (entity) {
    this.draw (entity);
}, this);

// DRAW_CMD.JS: listen for canvas click
DrawCMD.init = function () {
    Main.hub.on ('canvas_click', this.clicked, this);
};
DrawCMD.clicked = function (ev) {
    // tell everyone that an entity is added
    Main.hub.trigger ('entity_add', this.entity);
    Main.hub.off ('canvas_click', clicked);
};

// UI.JS: fire canvas click
canvas.addEventListener ('click', function (ev) {
    Main.hub.trigger ('canvas_click', ev);
});

So, I have a few questions about this:

  1. Efficiency : there are a few scenarios where this seems resource-wasteful, for example: when there are no commands active, click and mouse-move events are still being broadcast. Are there ways I make my .trigger function faster for this?
  2. Organization : does this seem like it will make my project more or less elegant compared to just directly calling functions on each relevant module?
  3. OOP : this is my first attempt at using the new Object.create. Could I be using it better, or does this look good?
  4. Context : I am using two arrays (events and contexts) so I can have registered functions keep the same context they would have normally. I would use Function.bind, except that doesn't allow me to use .off to un-register events. Is there a more elegant way to do this?
  5. Messes : Does anyone see any other potential pitfalls with this approach?
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.