1 var func = require("../base/functions"), 2 define = require("../define").define; 3 4 5 var Broadcaster = define(null, { 6 instance : { 7 /** @lends comb.plugins.Broadcaster.prototype */ 8 /** 9 * Plugin to allow a class to easily broadcast events 10 * 11 * @example 12 * 13 * var Mammal = define(comb.plugins.Broadcaster, { 14 * instance : { 15 * 16 * constructor: function(options) { 17 * options = options || {}; 18 * this.super(arguments); 19 * this._type = options.type || "mammal"; 20 * }, 21 * 22 * speak : function() { 23 * var str = "A mammal of type " + this._type + " sounds like"; 24 * this.broadcast("speak", str); 25 * this.onSpeak(str); 26 * return str; 27 * }, 28 * 29 * onSpeak : function(){} 30 * } 31 * }); 32 * 33 * 34 * var m = new Mammal({color : "gold"}); 35 * m.listen("speak", function(str){ 36 * //called back from the broadcast event 37 * console.log(str); 38 * }); 39 * m.speak(); 40 * 41 * @constructs 42 */ 43 constructor : function() { 44 this.__listeners = {}; 45 }, 46 47 /** 48 * Broadcasts an event from an object 49 * 50 * @param name the name of the event to broadcast 51 * @param {Object|String|Function|Date|Number} [args] variable number of arguments to pass to listeners, can be anything 52 */ 53 broadcast : function(topic, args) { 54 var args = Array.prototype.slice.call(arguments, 0), topic = args.shift(); 55 if (topic && topic in this.__listeners) { 56 var list = this.__listeners[topic], i = list.length - 1; 57 while (i >= 0) { 58 list[i--].cb.apply(this, args); 59 } 60 } 61 }, 62 63 /** 64 * Listens to a broadcasted event 65 * Simimlar to {@link comb.listen} 66 * 67 * @param {String} topic the topic to listen to 68 * @param {Function} callback the function to callback on event publish 69 * 70 * @returns {Array} handle to disconnect a topic 71 */ 72 listen : function(topic, callback) { 73 if (!func.isFunction(callback)) throw new Error("callback must be a function"); 74 var handle = { 75 topic : topic, 76 cb : callback 77 }; 78 var list = this.__listeners[topic]; 79 if (!list) { 80 list = (this.__listeners[topic] = [handle]); 81 handle.pos = 0; 82 } else { 83 handle.pos = list.push(handle); 84 } 85 return handle; 86 }, 87 88 /** 89 * Disconnects a listener 90 * Similar to {@link comb.unListen} 91 * 92 * @param handle disconnect a handle returned from Broadcaster.listen 93 */ 94 unListen : function(handle) { 95 if (handle) { 96 var topic = handle.topic; 97 if (topic in this.__listeners) { 98 var listeners = this.__listeners, list = listeners[topic]; 99 if (list) { 100 for (var i = list.length - 1; i >= 0; i--) { 101 if (list[i] == handle) { 102 list.splice(i, 1); 103 break; 104 } 105 } 106 } 107 } 108 } 109 } 110 } 111 }); 112 113 exports = module.exports = Broadcaster;