You can now use EventDispatcher.filter to scan outgoing events.

This commit is contained in:
photonstorm 2016-12-06 14:08:58 +00:00
parent a3e23e5c8a
commit 952d6aa49d
3 changed files with 68 additions and 19 deletions

View file

@ -1,4 +1,4 @@
var CHECKSUM = { var CHECKSUM = {
build: '8271a1a0-bb58-11e6-92c7-1bf1ec33cb5b' build: 'ada471e0-bbbc-11e6-8998-8541b7b364d1'
}; };
module.exports = CHECKSUM; module.exports = CHECKSUM;

View file

@ -138,15 +138,13 @@ EventBinding.prototype = {
else if (this.active.length === 0) else if (this.active.length === 0)
{ {
// This was a valid dispatch call, we just had nothing to do ... // This was a valid dispatch call, we just had nothing to do ...
return true; return;
} }
this.state = CONST.DISPATCHER_DISPATCHING; this.state = CONST.DISPATCHER_DISPATCHING;
var listener; var listener;
event.reset(this.dispatcher);
for (var i = 0; i < this.active.length; i++) for (var i = 0; i < this.active.length; i++)
{ {
listener = this.active[i]; listener = this.active[i];

View file

@ -3,6 +3,8 @@ var EventBinding = require('./EventBinding');
var EventDispatcher = function () var EventDispatcher = function ()
{ {
this.bindings = {}; this.bindings = {};
this.filters = [];
this.hasFilters = false;
}; };
EventDispatcher.prototype.constructor = EventDispatcher; EventDispatcher.prototype.constructor = EventDispatcher;
@ -55,6 +57,29 @@ EventDispatcher.prototype = {
return this; return this;
}, },
// 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;
},
has: function (type, listener) has: function (type, listener)
{ {
var binding = this.getBinding(type); var binding = this.getBinding(type);
@ -93,30 +118,46 @@ EventDispatcher.prototype = {
return this; return this;
}, },
_dispatchHandler: function (event)
{
event.reset(this);
// Pass the event through the filters first
if (this.hasFilters)
{
for (var i = 0; i < this.filters.length; i++)
{
this.filters[i].call(this, event);
// Did the filter kill the event? If so, we can abort now
if (!event._propagate)
{
return;
}
}
}
var binding = this.getBinding(event.type);
if (binding)
{
binding.dispatch(event);
}
},
dispatch: function (event) dispatch: function (event)
{ {
var binding;
if (Array.isArray(event)) if (Array.isArray(event))
{ {
for (var i = 0; i < event.length; i++) for (var i = 0; i < event.length; i++)
{ {
binding = this.getBinding(event[i].type); this._dispatchHandler(event[i]);
if (binding)
{
return binding.dispatch(event[i]);
}
} }
} }
else else
{ {
binding = this.getBinding(event.type); this._dispatchHandler(event);
if (binding)
{
return binding.dispatch(event);
}
} }
}, },
@ -133,6 +174,15 @@ EventDispatcher.prototype = {
return this; return this;
}, },
removeAllFilters: function ()
{
this.filters.length = 0;
this.hasFilters = false;
return this;
},
delete: function (type) delete: function (type)
{ {
var binding = this.getBinding(type); var binding = this.getBinding(type);
@ -159,7 +209,8 @@ EventDispatcher.prototype = {
destroy: function () destroy: function ()
{ {
// What would it do any differently to deleteAll? this.deleteAll();
this.removeAllFilters();
} }
}; };