/** * Created by y.x on 16/11/8. */ var signals = require("signals"); var notification = { _signals: [], _cachebinds: {}, _findSignal: function(eEvent) { var i, signal; for(i = this._signals.length; i--;) { signal = this._signals[i]; if(signal.event === eEvent) { return signal; } } return null; }, /** * 创建一个信号与监听函数的绑定 * @param {Number} [eEvent] 事件id(也可使用字符串)。 * @param {Function} [fnListener] 信号处理函数. * @param {Object} [oTarget] 信号处理函数的对象。 * @return {Object} 返回一个描述信号与处理函数的绑定对象,作为移除绑定的句柄使用。 */ createBinding: function(eEvent, fnListener, oTarget) { // find signal var signal = this._findSignal(eEvent); // find unused signal if(signal === null) { signal = this._findSignal(null); } // create new signal if(signal === null) { signal = new signals.Signal(); this._signals.push(signal); } // bind listener if(signal) { signal.event = eEvent; return signal.add(fnListener, oTarget); } }, /** * 移除信号的绑定函数 * @param {Object|Array} [oBinding] createSignalBinding返回的对象。 */ removeBinding: function(oBinding) { var bindings = oBinding instanceof Array ? oBinding : [oBinding]; for(var i = bindings.length; i--;) { var one = bindings[i], signal = one.getSignal(); one.detach(); if(signal && signal.getNumListeners() == 0) { signal.event = null; } } }, /** * 监听事件 * 与createBinding功能一致(增加了缓存,方便删除) */ on(eEvent, fnListener, oTarget){ let obj = this._cachebinds[eEvent]; if(!obj){ obj = []; this._cachebinds[eEvent] = obj; } let ob = obj.find((element) => { return element.listener == fnListener && element.target == oTarget; }); if(ob){ return ob.binding; } let bd = this.createBinding(eEvent, fnListener, oTarget); ob = { listener: fnListener, target: oTarget, binding: bd }; obj.push(ob); return bd; }, /** * 取消监听事件(参数必须与监听事件保持一致) */ off(eEvent, fnListener, oTarget){ let obj = this._cachebinds[eEvent]; if(!obj){ return; } let idx = obj.findIndex((element) => { return element.listener == fnListener && element.target == oTarget; }); if(idx < 0){ return; } let ob = obj[idx]; this.removeBinding(ob.binding); obj.splice(idx, 1); }, /** * 发送信号 * @param {Number} [eEvent] 事件id。 */ emit: function(eEvent) { var signal = this._findSignal(eEvent); if(signal) { signal.dispatch.apply(this, arguments); } } }; module.exports = notification;