2017-06-30 14:47:51 +00:00
|
|
|
var Class = require('../utils/Class');
|
2017-11-01 22:21:31 +00:00
|
|
|
var CONST = require('./const');
|
2016-12-06 01:38:53 +00:00
|
|
|
var EventBinding = require('./EventBinding');
|
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
var EventDispatcher = new Class({
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
initialize:
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
function EventDispatcher ()
|
|
|
|
{
|
|
|
|
this.bindings = {};
|
|
|
|
this.filters = [];
|
|
|
|
this.hasFilters = false;
|
|
|
|
},
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
getBinding: function (type)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
if (this.bindings.hasOwnProperty(type))
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
return this.bindings[type];
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
createBinding: function (type)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
if (!this.getBinding(type))
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
this.bindings[type] = new EventBinding(this, type);
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
return this.bindings[type];
|
2016-12-05 15:29:35 +00:00
|
|
|
},
|
|
|
|
|
2017-11-07 17:05:51 +00:00
|
|
|
on: function (type, listener, priority, scope)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
|
|
|
if (priority === undefined) { priority = 0; }
|
2017-11-07 17:05:51 +00:00
|
|
|
if (scope === undefined) { scope = this; }
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
var binding = this.createBinding(type);
|
|
|
|
|
|
|
|
if (binding)
|
|
|
|
{
|
2017-11-07 17:05:51 +00:00
|
|
|
binding.add(listener, priority, scope, false);
|
2016-12-06 01:38:53 +00:00
|
|
|
}
|
2016-12-05 15:29:35 +00:00
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2017-11-07 17:05:51 +00:00
|
|
|
once: function (type, listener, priority, scope)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
|
|
|
if (priority === undefined) { priority = 0; }
|
2017-11-07 17:05:51 +00:00
|
|
|
if (scope === undefined) { scope = this; }
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
var binding = this.createBinding(type);
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
if (binding)
|
2016-12-05 17:19:12 +00:00
|
|
|
{
|
2017-11-07 17:05:51 +00:00
|
|
|
binding.add(listener, priority, scope, true);
|
2016-12-05 17:19:12 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
return this;
|
2016-12-05 17:19:12 +00:00
|
|
|
},
|
|
|
|
|
2016-12-06 14:08:58 +00:00
|
|
|
// Add a callback that is notified every time this EventDispatcher dispatches an event
|
|
|
|
// no matter what the event type is. Filters are invoked first, before any bindings,
|
|
|
|
// and can stop events if they wish (in which case they'll never reach the bindings)
|
|
|
|
filter: function (callback)
|
|
|
|
{
|
|
|
|
var i = this.filters.indexOf(callback);
|
|
|
|
|
|
|
|
if (i === -1)
|
|
|
|
{
|
|
|
|
// Add the filter
|
|
|
|
this.filters.push(callback);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Remove the filter
|
|
|
|
this.filters.splice(i, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.hasFilters = (this.filters.length > 0);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2016-12-05 15:29:35 +00:00
|
|
|
has: function (type, listener)
|
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
var binding = this.getBinding(type);
|
|
|
|
|
|
|
|
if (binding)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
return binding.has(listener);
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
2016-12-06 01:38:53 +00:00
|
|
|
else
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
return false;
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-12-06 02:07:30 +00:00
|
|
|
total: function (type)
|
|
|
|
{
|
|
|
|
var binding = this.getBinding(type);
|
|
|
|
|
|
|
|
if (binding)
|
|
|
|
{
|
|
|
|
return binding.total();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2016-12-05 15:29:35 +00:00
|
|
|
// Removes an event listener.
|
|
|
|
// If there is no matching listener registered with the EventDispatcher, a call to this method has no effect.
|
|
|
|
off: function (type, listener)
|
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
var binding = this.getBinding(type);
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
if (binding)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
binding.remove(listener);
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2016-12-06 14:08:58 +00:00
|
|
|
_dispatchHandler: function (event)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 14:08:58 +00:00
|
|
|
event.reset(this);
|
2016-12-05 17:19:12 +00:00
|
|
|
|
2016-12-06 14:08:58 +00:00
|
|
|
// Pass the event through the filters first
|
|
|
|
|
|
|
|
if (this.hasFilters)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 14:08:58 +00:00
|
|
|
for (var i = 0; i < this.filters.length; i++)
|
2016-12-05 17:19:12 +00:00
|
|
|
{
|
2016-12-06 14:08:58 +00:00
|
|
|
this.filters[i].call(this, event);
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2016-12-06 14:08:58 +00:00
|
|
|
// Did the filter kill the event? If so, we can abort now
|
|
|
|
if (!event._propagate)
|
2016-12-06 01:38:53 +00:00
|
|
|
{
|
2016-12-06 14:08:58 +00:00
|
|
|
return;
|
2016-12-06 01:38:53 +00:00
|
|
|
}
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
}
|
2016-12-06 14:08:58 +00:00
|
|
|
|
|
|
|
var binding = this.getBinding(event.type);
|
|
|
|
|
|
|
|
if (binding)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 14:08:58 +00:00
|
|
|
binding.dispatch(event);
|
|
|
|
}
|
|
|
|
},
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2016-12-06 14:08:58 +00:00
|
|
|
dispatch: function (event)
|
|
|
|
{
|
|
|
|
if (Array.isArray(event))
|
|
|
|
{
|
|
|
|
for (var i = 0; i < event.length; i++)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 14:08:58 +00:00
|
|
|
this._dispatchHandler(event[i]);
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
}
|
2016-12-06 14:08:58 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
this._dispatchHandler(event);
|
|
|
|
}
|
2016-12-05 15:29:35 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
// Removes all listeners, but retains the event type entries
|
2016-12-06 01:38:53 +00:00
|
|
|
removeAll: function (type)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
var binding = this.getBinding(type);
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
if (binding)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
binding.removeAll();
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2016-12-06 14:08:58 +00:00
|
|
|
removeAllFilters: function ()
|
|
|
|
{
|
|
|
|
this.filters.length = 0;
|
|
|
|
|
|
|
|
this.hasFilters = false;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
delete: function (type)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2016-12-06 01:38:53 +00:00
|
|
|
var binding = this.getBinding(type);
|
|
|
|
|
|
|
|
if (binding)
|
2016-12-05 15:29:35 +00:00
|
|
|
{
|
2017-11-01 22:21:31 +00:00
|
|
|
if (binding.state === CONST.DISPATCHER_IDLE)
|
|
|
|
{
|
|
|
|
binding.destroy();
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2017-11-01 22:21:31 +00:00
|
|
|
delete this.bindings[type];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
binding.state = CONST.DISPATCHER_DESTROYED;
|
|
|
|
}
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
return this;
|
|
|
|
},
|
2016-12-05 15:29:35 +00:00
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
deleteAll: function ()
|
|
|
|
{
|
|
|
|
for (var binding in this.bindings)
|
|
|
|
{
|
2017-11-14 13:20:33 +00:00
|
|
|
this.bindings[binding].destroy();
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 01:38:53 +00:00
|
|
|
this.bindings = {};
|
|
|
|
},
|
|
|
|
|
|
|
|
destroy: function ()
|
|
|
|
{
|
2016-12-06 14:08:58 +00:00
|
|
|
this.deleteAll();
|
|
|
|
this.removeAllFilters();
|
2016-12-05 15:29:35 +00:00
|
|
|
}
|
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
});
|
2016-12-05 15:29:35 +00:00
|
|
|
|
|
|
|
module.exports = EventDispatcher;
|