Skip to content

Instantly share code, notes, and snippets.

@kapv89
Last active December 13, 2015 20:18
Show Gist options
  • Save kapv89/4969004 to your computer and use it in GitHub Desktop.
Save kapv89/4969004 to your computer and use it in GitHub Desktop.
An untested concept of a sandbox for client side dev
// needs underscore and Backbone.Events( really didn't want to code that stuff up :P)
window.sandBoxFactory = function () {
var vent = _.extend({}, Backbone.Events); // The event aggregator for the sandbox
var communicatorEvents = [];
var broadCasters = {};
var sandBox = {
modules: {}, // modules stored as key-val, identifier of a module, and the object
vent: function () {
return vent;
},
communicatorEvents: function () {
return communicatorEvents;
}
registerModule: function (key, module) {
this.modules[key] = module;
},
startModule: function (key) {
this.modules[key] && this.modules[key].start();
// this expects each module to have a start function, after calling which the module
// will start doing what its meant to do
},
stopModule: function (key) {
if(! this.modules[key] ) return;
this.removeConversationsFor(key);
// remove inter-module communications for in-focus module
this.modules[key].stop()
// this expects each module to have a stop function, after calling which the module
// will stop doing whatever its doing
},
deregisterModule: function (key) {
if(! this.modules[key] ) return;
this.stopModule(key);
delete(this.modules[key]);
},
addConversationsFor: function (key, conversations) {
// conversations are on object-hash of the format
// { speakerModuleEvent: { aListenerModule: [ its events to be triggered ] } }
var speakerModule = this.modules[key];
if(! speakerModule) return false;
_.each(conversations, function (conversation, event) {
var communicatorEvent = key + '.' + event; // this is the event using which a conversation happens
communicatorEvents.push(communicatorEvent); // we push it in our list of communicator events
// we maintain a dictionary of broadCasters so that we can stop them from listening to
// speakerModule events later
broadCasters[communicatorEvent] = function () {
var argsArray = _.map(arguments, function (a) { return a; });
vent.trigger.apply(vent, [communicatorEvent].concat(argsArray));
}
// now we set our event aggregator such that when "event" is triggered on
// the event aggregator of speakerModule, a communicatorEvent is triggered on our sandbox's vent
speakerModule.vent().on(event, broadCasters[communicatorEvent]);
// here we make each listener module listen to the communicatorEvent on the sandbox's eventAggregator,
// and let it trigger its own events via its "eventAggregator",
// or its "vent()" whenever the communicatorEvent happens
_.each(conversation, function (events, listener) {
var listenerModule = this.modules[listener];
if(! listenerModule)
return;
if(typeof(events) === 'string') events = [events];
vent.on(communicatorEvent, function () {
var argsArray = _.map(arguments, function (a) { return a; });
_.each(events, function (event) {
// each module should provide access to its own event aggregator using vent()
listenerModule.vent().trigger.apply(listenerModule.vent(), [event].concat(argsArray));
});
});
}, this);
}, this);
},
removeConversationsFor: function (key) {
if(! this.modules[key]) return;
var head = key + '.';
communicatorEvents = _.filter(communicatorEvents, function (ev) {
if(ev.slice(0, head.length) === head) {
// broadCasters of speaker events are made to stop listening to
// events on speakerModule
this.modules[key].vent().off(ev, broadCasters[ev])
// the event aggregator is made to shut up about the communicatorEvent
vent.off(ev);
return false;
} else {
return true;
}
});
}
}
return sandBox;
}
// make an AMD module out of this and debug it and test it.
// line 24, 35, 79 are expect some behavior from modules. so have a look at them
/* Usage:
var sandBox = sandBoxFactory();
sandBox.registerModule('foo', foo);
sandBox.registerModule('bar', bar);
sandBox.registerModule('baz', baz);
// setup inter-module conversations where module with key 'foo' is the speaker
sandBox.addConversationsFor('foo', {
'someEventOnFoo': {
'bar': ['someEventOnBar', 'someOtherEventOnBar'],
'baz': 'someEventOnBaz'
}
});
// stop inter-module conversations for module under key 'foo'
sandBox.removeConversationsFor('foo')
*/
@adityamenon
Copy link

Thanks so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment