@robotlegsjs/core
Version:
An architecture-based IoC framework for JavaScript/TypeScript
274 lines • 11.4 kB
JavaScript
"use strict";
//////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2014-present, Egret Technology.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Egret nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventDispatcher = void 0;
var tslib_1 = require("tslib");
var inversify_1 = require("inversify");
var IEventDispatcher_1 = require("../api/IEventDispatcher");
var Event_1 = require("../impl/Event");
var ONCE_EVENT_LIST = [];
/**
* The EventDispatcher class is the base class for all classes that dispatchEvent events. The EventDispatcher class implements
* the IEventDispatcher interface and is the base class for the DisplayObject class. The EventDispatcher class allows
* any object on the display list to be an event target and as such, to use the methods of the IEventDispatcher interface.
* Event targets are an important part of the Egret event model. The event target serves as the focal point for how events
* flow through the display list hierarchy. When an event such as a touch tap, Egret dispatches an event object into the
* event flow from the root of the display list. The event object then makes its way through the display list until it
* reaches the event target, at which point it begins its return trip through the display list. This round-trip journey
* to the event target is conceptually divided into three phases: <br/>
* the capture phase comprises the journey from the root to the last node before the event target's node, the target
* phase comprises only the event target node, and the bubbling phase comprises any subsequent nodes encountered on
* the return trip to the root of the display list. In general, the easiest way for a user-defined class to gain event
* dispatching capabilities is to extend EventDispatcher. If this is impossible (that is, if the class is already extending
* another class), you can instead implement the IEventDispatcher interface, create an EventDispatcher member, and write simple
* hooks to route calls into the aggregated EventDispatcher.
*
* @see egret.IEventDispatcher
* @version Egret 2.4
* @platform Web,Native
* @includeExample egret/events/EventDispatcher.ts
* @language en_US
*/
var EventDispatcher = /** @class */ (function () {
/**
* create an instance of the EventDispatcher class.
*
* @param target The target object for events dispatched to the EventDispatcher object. This parameter is used when
* the EventDispatcher instance is aggregated by a class that implements IEventDispatcher; it is necessary so that the
* containing object can be the target for events. Do not use this parameter in simple cases in which a class extends EventDispatcher.
* @version Egret 2.4
* @platform Web,Native
* @language en_US
*/
function EventDispatcher(target) {
if (target === void 0) { target = null; }
this._eventDispatcher = {
0: target ? target : this,
1: {},
2: {},
3: 0
};
}
/**
* @inheritDoc
* @version Egret 2.4
* @platform Web,Native
*/
EventDispatcher.prototype.addEventListener = function (type, listener, thisObject, useCapture, priority) {
this._addListener(type, listener, thisObject, useCapture, priority);
};
/**
* @inheritDoc
* @version Egret 2.4
* @platform Web,Native
*/
EventDispatcher.prototype.once = function (type, listener, thisObject, useCapture, priority) {
this._addListener(type, listener, thisObject, useCapture, priority, true);
};
/**
* @inheritDoc
* @version Egret 2.4
* @platform Web,Native
*/
EventDispatcher.prototype.removeEventListener = function (type, listener, thisObject, useCapture) {
var values = this._eventDispatcher;
var eventMap = this._getEventMap(useCapture);
var list = eventMap[type];
if (!list) {
return;
}
if (values[3 /* notifyLevel */] !== 0) {
eventMap[type] = list = list.concat();
}
this._removeEventBin(list, listener, thisObject);
if (list.length === 0) {
eventMap[type] = null;
}
};
/**
* @inheritDoc
* @version Egret 2.4
* @platform Web,Native
*/
EventDispatcher.prototype.hasEventListener = function (type) {
var values = this._eventDispatcher;
return !!(values[1 /* eventsMap */][type] || values[2 /* captureEventsMap */][type]);
};
/**
* @inheritDoc
* @version Egret 2.4
* @platform Web,Native
*/
EventDispatcher.prototype.willTrigger = function (type) {
return this.hasEventListener(type);
};
/**
* @inheritDoc
* @version Egret 2.4
* @platform Web,Native
*/
EventDispatcher.prototype.dispatchEvent = function (event) {
event.currentTarget = this._eventDispatcher[0 /* eventTarget */];
event.target = event.currentTarget;
return this._notifyListener(event, false);
};
/**
* Distribute a specified event parameters.
*
* @param type The type of the event. Event listeners can access this information through the inherited type property.
* @param bubbles Determines whether the Event object bubbles. Event listeners can access this information through
* the inherited bubbles property.
* @param data {any} data
* @param cancelable Determines whether the Event object can be canceled. The default values is false.
* @version Egret 2.4
* @platform Web,Native
* @language en_US
*/
EventDispatcher.prototype.dispatchEventWith = function (type, bubbles, data, cancelable) {
if (bubbles || this.hasEventListener(type)) {
var event_1 = new Event_1.Event(type, bubbles, cancelable, data);
var result = this.dispatchEvent(event_1);
return result;
}
return true;
};
/**
* @private
*
* @param useCapture
*/
EventDispatcher.prototype._getEventMap = function (useCapture) {
var values = this._eventDispatcher;
var eventMap = useCapture ? values[2 /* captureEventsMap */] : values[1 /* eventsMap */];
return eventMap;
};
/**
* @private
*/
EventDispatcher.prototype._addListener = function (type, listener, thisObject, useCapture, priority, dispatchOnce) {
var values = this._eventDispatcher;
var eventMap = this._getEventMap(useCapture);
var list = eventMap[type];
if (!list) {
list = eventMap[type] = [];
}
else if (values[3 /* notifyLevel */] !== 0) {
eventMap[type] = list = list.concat();
}
this._insertEventBin(list, type, listener, thisObject, useCapture, priority, dispatchOnce);
};
/**
* @private
*/
EventDispatcher.prototype._insertEventBin = function (list, type, listener, thisObject, useCapture, priority, dispatchOnce) {
priority = priority || 0;
var insertIndex = -1;
var length = list.length;
for (var i = 0; i < length; i++) {
var bin = list[i];
if (bin.listener === listener && bin.thisObject === thisObject && bin.target === this) {
return false;
}
if (insertIndex === -1 && bin.priority < priority) {
insertIndex = i;
}
}
var eventBin = {
type: type,
listener: listener,
thisObject: thisObject,
priority: priority,
target: this,
useCapture: useCapture,
dispatchOnce: !!dispatchOnce
};
if (insertIndex !== -1) {
list.splice(insertIndex, 0, eventBin);
}
else {
list.push(eventBin);
}
return true;
};
/**
* @private
*/
EventDispatcher.prototype._removeEventBin = function (list, listener, thisObject) {
var length = list.length;
for (var i = 0; i < length; i++) {
var bin = list[i];
if (bin.listener === listener && bin.thisObject === thisObject && bin.target === this) {
list.splice(i, 1);
return true;
}
}
return false;
};
/**
* @private
*/
EventDispatcher.prototype._notifyListener = function (event, capturePhase) {
var values = this._eventDispatcher;
var eventMap = this._getEventMap(capturePhase);
var list = eventMap[event.type];
if (!list) {
return true;
}
var length = list.length;
if (length === 0) {
return true;
}
var onceList = ONCE_EVENT_LIST;
values[3 /* notifyLevel */]++;
for (var i = 0; i < length; i++) {
var eventBin = list[i];
eventBin.listener.call(eventBin.thisObject, event);
if (eventBin.dispatchOnce) {
onceList.push(eventBin);
}
if (event.isPropagationImmediateStopped) {
break;
}
}
values[3 /* notifyLevel */]--;
while (onceList.length) {
var eventBin = onceList.pop();
eventBin.target.removeEventListener(eventBin.type, eventBin.listener, eventBin.thisObject, eventBin.useCapture);
}
return !event.isDefaultPrevented;
};
EventDispatcher = tslib_1.__decorate([
inversify_1.injectable(),
tslib_1.__metadata("design:paramtypes", [Object])
], EventDispatcher);
return EventDispatcher;
}());
exports.EventDispatcher = EventDispatcher;
//# sourceMappingURL=EventDispatcher.js.map