123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922 |
- /****************************************************************************
- Copyright (c) 2011-2012 cocos2d-x.org
- Copyright (c) 2013-2014 Chukong Technologies Inc.
- http://www.cocos2d-x.org
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
- cc._EventListenerVector = cc.Class.extend({
- _fixedListeners: null,
- _sceneGraphListeners: null,
- gt0Index: 0,
- ctor: function () {
- this._fixedListeners = [];
- this._sceneGraphListeners = [];
- },
- size: function () {
- return this._fixedListeners.length + this._sceneGraphListeners.length;
- },
- empty: function () {
- return (this._fixedListeners.length === 0) && (this._sceneGraphListeners.length === 0);
- },
- push: function (listener) {
- if (listener._getFixedPriority() == 0)
- this._sceneGraphListeners.push(listener);
- else
- this._fixedListeners.push(listener);
- },
- clearSceneGraphListeners: function () {
- this._sceneGraphListeners.length = 0;
- },
- clearFixedListeners: function () {
- this._fixedListeners.length = 0;
- },
- clear: function () {
- this._sceneGraphListeners.length = 0;
- this._fixedListeners.length = 0;
- },
- getFixedPriorityListeners: function () {
- return this._fixedListeners;
- },
- getSceneGraphPriorityListeners: function () {
- return this._sceneGraphListeners;
- }
- });
- cc.__getListenerID = function (event) {
- var eventType = cc.Event, getType = event.getType();
- if(getType === eventType.ACCELERATION)
- return cc._EventListenerAcceleration.LISTENER_ID;
- if(getType === eventType.CUSTOM)
- return event.getEventName();
- if(getType === eventType.KEYBOARD)
- return cc._EventListenerKeyboard.LISTENER_ID;
- if(getType === eventType.MOUSE)
- return cc._EventListenerMouse.LISTENER_ID;
- if(getType === eventType.TOUCH){
- // Touch listener is very special, it contains two kinds of listeners, EventListenerTouchOneByOne and EventListenerTouchAllAtOnce.
- // return UNKNOWN instead.
- cc.log(cc._LogInfos.__getListenerID);
- }
- return "";
- };
- /**
- * <p>
- * cc.eventManager is a singleton object which manages event listener subscriptions and event dispatching. <br/>
- * <br/>
- * The EventListener list is managed in such way so that event listeners can be added and removed <br/>
- * while events are being dispatched.
- * </p>
- * @class
- * @name cc.eventManager
- */
- cc.eventManager = /** @lends cc.eventManager# */{
- //Priority dirty flag
- DIRTY_NONE:0,
- DIRTY_FIXED_PRIORITY:1 <<0,
- DIRTY_SCENE_GRAPH_PRIORITY : 1<< 1,
- DIRTY_ALL: 3,
- _listenersMap: {},
- _priorityDirtyFlagMap: {},
- _nodeListenersMap: {},
- _nodePriorityMap: {},
- _globalZOrderNodeMap: {},
- _toAddedListeners: [],
- _dirtyNodes: [],
- _inDispatch: 0,
- _isEnabled: false,
- _nodePriorityIndex: 0,
- _internalCustomListenerIDs:[cc.game.EVENT_HIDE, cc.game.EVENT_SHOW],
- _setDirtyForNode: function (node) {
- // Mark the node dirty only when there is an event listener associated with it.
- if (this._nodeListenersMap[node.__instanceId] != null)
- this._dirtyNodes.push(node);
- var _children = node.getChildren();
- for(var i = 0, len = _children.length; i < len; i++)
- this._setDirtyForNode(_children[i]);
- },
- /**
- * Pauses all listeners which are associated the specified target.
- * @param {cc.Node} node
- * @param {Boolean} [recursive=false]
- */
- pauseTarget: function (node, recursive) {
- var listeners = this._nodeListenersMap[node.__instanceId], i, len;
- if (listeners) {
- for ( i = 0, len = listeners.length; i < len; i++)
- listeners[i]._setPaused(true);
- }
- if (recursive === true) {
- var locChildren = node.getChildren();
- for ( i = 0, len = locChildren.length; i< len; i++)
- this.pauseTarget(locChildren[i], true);
- }
- },
- /**
- * Resumes all listeners which are associated the specified target.
- * @param {cc.Node} node
- * @param {Boolean} [recursive=false]
- */
- resumeTarget: function (node, recursive) {
- var listeners = this._nodeListenersMap[node.__instanceId], i, len;
- if (listeners){
- for ( i = 0, len = listeners.length; i < len; i++)
- listeners[i]._setPaused(false);
- }
- this._setDirtyForNode(node);
- if (recursive === true) {
- var locChildren = node.getChildren();
- for ( i = 0, len = locChildren.length; i< len; i++)
- this.resumeTarget(locChildren[i], true);
- }
- },
- _addListener: function (listener) {
- if (this._inDispatch === 0)
- this._forceAddEventListener(listener);
- else
- this._toAddedListeners.push(listener);
- },
- _forceAddEventListener: function (listener) {
- var listenerID = listener._getListenerID();
- var listeners = this._listenersMap[listenerID];
- if (!listeners) {
- listeners = new cc._EventListenerVector();
- this._listenersMap[listenerID] = listeners;
- }
- listeners.push(listener);
- if (listener._getFixedPriority() == 0) {
- this._setDirty(listenerID, this.DIRTY_SCENE_GRAPH_PRIORITY);
- var node = listener._getSceneGraphPriority();
- if (node == null)
- cc.log(cc._LogInfos.eventManager__forceAddEventListener);
- this._associateNodeAndEventListener(node, listener);
- if (node.isRunning())
- this.resumeTarget(node);
- } else
- this._setDirty(listenerID, this.DIRTY_FIXED_PRIORITY);
- },
- _getListeners: function (listenerID) {
- return this._listenersMap[listenerID];
- },
- _updateDirtyFlagForSceneGraph: function () {
- if (this._dirtyNodes.length == 0)
- return;
- var locDirtyNodes = this._dirtyNodes, selListeners, selListener, locNodeListenersMap = this._nodeListenersMap;
- for (var i = 0, len = locDirtyNodes.length; i < len; i++) {
- selListeners = locNodeListenersMap[locDirtyNodes[i].__instanceId];
- if (selListeners) {
- for (var j = 0, listenersLen = selListeners.length; j < listenersLen; j++) {
- selListener = selListeners[j];
- if (selListener)
- this._setDirty(selListener._getListenerID(), this.DIRTY_SCENE_GRAPH_PRIORITY);
- }
- }
- }
- this._dirtyNodes.length = 0;
- },
- _removeAllListenersInVector: function (listenerVector) {
- if (!listenerVector)
- return;
- var selListener;
- for (var i = 0; i < listenerVector.length;) {
- selListener = listenerVector[i];
- selListener._setRegistered(false);
- if (selListener._getSceneGraphPriority() != null){
- this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
- selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
- }
- if (this._inDispatch === 0)
- cc.arrayRemoveObject(listenerVector, selListener);
- else
- ++i;
- }
- },
- _removeListenersForListenerID: function (listenerID) {
- var listeners = this._listenersMap[listenerID], i;
- if (listeners) {
- var fixedPriorityListeners = listeners.getFixedPriorityListeners();
- var sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
- this._removeAllListenersInVector(sceneGraphPriorityListeners);
- this._removeAllListenersInVector(fixedPriorityListeners);
- // Remove the dirty flag according the 'listenerID'.
- // No need to check whether the dispatcher is dispatching event.
- delete this._priorityDirtyFlagMap[listenerID];
- if (!this._inDispatch) {
- listeners.clear();
- delete this._listenersMap[listenerID];
- }
- }
- var locToAddedListeners = this._toAddedListeners, listener;
- for (i = 0; i < locToAddedListeners.length;) {
- listener = locToAddedListeners[i];
- if (listener && listener._getListenerID() == listenerID)
- cc.arrayRemoveObject(locToAddedListeners, listener);
- else
- ++i;
- }
- },
- _sortEventListeners: function (listenerID) {
- var dirtyFlag = this.DIRTY_NONE, locFlagMap = this._priorityDirtyFlagMap;
- if (locFlagMap[listenerID])
- dirtyFlag = locFlagMap[listenerID];
- if (dirtyFlag != this.DIRTY_NONE) {
- // Clear the dirty flag first, if `rootNode` is null, then set its dirty flag of scene graph priority
- locFlagMap[listenerID] = this.DIRTY_NONE;
- if (dirtyFlag & this.DIRTY_FIXED_PRIORITY)
- this._sortListenersOfFixedPriority(listenerID);
- if (dirtyFlag & this.DIRTY_SCENE_GRAPH_PRIORITY){
- var rootNode = cc.director.getRunningScene();
- if(rootNode)
- this._sortListenersOfSceneGraphPriority(listenerID, rootNode);
- else
- locFlagMap[listenerID] = this.DIRTY_SCENE_GRAPH_PRIORITY;
- }
- }
- },
- _sortListenersOfSceneGraphPriority: function (listenerID, rootNode) {
- var listeners = this._getListeners(listenerID);
- if (!listeners)
- return;
- var sceneGraphListener = listeners.getSceneGraphPriorityListeners();
- if(!sceneGraphListener || sceneGraphListener.length === 0)
- return;
- // Reset priority index
- this._nodePriorityIndex = 0;
- this._nodePriorityMap = {};
- this._visitTarget(rootNode, true);
- // After sort: priority < 0, > 0
- listeners.getSceneGraphPriorityListeners().sort(this._sortEventListenersOfSceneGraphPriorityDes);
- },
- _sortEventListenersOfSceneGraphPriorityDes : function(l1, l2){
- var locNodePriorityMap = cc.eventManager._nodePriorityMap;
- if(!l1 || !l2 || !l1._getSceneGraphPriority() || !l2._getSceneGraphPriority())
- return -1;
- return locNodePriorityMap[l2._getSceneGraphPriority().__instanceId] - locNodePriorityMap[l1._getSceneGraphPriority().__instanceId];
- },
- _sortListenersOfFixedPriority: function (listenerID) {
- var listeners = this._listenersMap[listenerID];
- if (!listeners)
- return;
- var fixedListeners = listeners.getFixedPriorityListeners();
- if(!fixedListeners || fixedListeners.length === 0)
- return;
- // After sort: priority < 0, > 0
- fixedListeners.sort(this._sortListenersOfFixedPriorityAsc);
- // FIXME: Should use binary search
- var index = 0;
- for (var len = fixedListeners.length; index < len;) {
- if (fixedListeners[index]._getFixedPriority() >= 0)
- break;
- ++index;
- }
- listeners.gt0Index = index;
- },
- _sortListenersOfFixedPriorityAsc: function (l1, l2) {
- return l1._getFixedPriority() - l2._getFixedPriority();
- },
- _onUpdateListeners: function (listenerID) {
- var listeners = this._listenersMap[listenerID];
- if (!listeners)
- return;
- var fixedPriorityListeners = listeners.getFixedPriorityListeners();
- var sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
- var i, selListener;
- if (sceneGraphPriorityListeners) {
- for (i = 0; i < sceneGraphPriorityListeners.length;) {
- selListener = sceneGraphPriorityListeners[i];
- if (!selListener._isRegistered()) {
- cc.arrayRemoveObject(sceneGraphPriorityListeners, selListener);
- } else
- ++i;
- }
- }
- if (fixedPriorityListeners) {
- for (i = 0; i < fixedPriorityListeners.length;) {
- selListener = fixedPriorityListeners[i];
- if (!selListener._isRegistered())
- cc.arrayRemoveObject(fixedPriorityListeners, selListener);
- else
- ++i;
- }
- }
- if (sceneGraphPriorityListeners && sceneGraphPriorityListeners.length === 0)
- listeners.clearSceneGraphListeners();
- if (fixedPriorityListeners && fixedPriorityListeners.length === 0)
- listeners.clearFixedListeners();
- },
- _updateListeners: function (event) {
- var locInDispatch = this._inDispatch;
- cc.assert(locInDispatch > 0, cc._LogInfos.EventManager__updateListeners);
- if (event.getType() == cc.Event.TOUCH) {
- this._onUpdateListeners(cc._EventListenerTouchOneByOne.LISTENER_ID);
- this._onUpdateListeners(cc._EventListenerTouchAllAtOnce.LISTENER_ID);
- } else
- this._onUpdateListeners(cc.__getListenerID(event));
- if(locInDispatch > 1)
- return;
- cc.assert(locInDispatch == 1, cc._LogInfos.EventManager__updateListeners_2);
- var locListenersMap = this._listenersMap, locPriorityDirtyFlagMap = this._priorityDirtyFlagMap;
- for (var selKey in locListenersMap) {
- if (locListenersMap[selKey].empty()) {
- delete locPriorityDirtyFlagMap[selKey];
- delete locListenersMap[selKey];
- }
- }
- var locToAddedListeners = this._toAddedListeners;
- if (locToAddedListeners.length !== 0) {
- for (var i = 0, len = locToAddedListeners.length; i < len; i++)
- this._forceAddEventListener(locToAddedListeners[i]);
- this._toAddedListeners.length = 0;
- }
- },
- _onTouchEventCallback: function(listener, argsObj){
- // Skip if the listener was removed.
- if (!listener._isRegistered)
- return false;
- var event = argsObj.event, selTouch = argsObj.selTouch;
- event._setCurrentTarget(listener._node);
- var isClaimed = false, removedIdx;
- var getCode = event.getEventCode(), eventCode = cc.EventTouch.EventCode;
- if (getCode == eventCode.BEGAN) {
- if (listener.onTouchBegan) {
- isClaimed = listener.onTouchBegan(selTouch, event);
- if (isClaimed && listener._registered)
- listener._claimedTouches.push(selTouch);
- }
- } else if (listener._claimedTouches.length > 0
- && ((removedIdx = listener._claimedTouches.indexOf(selTouch)) != -1)) {
- isClaimed = true;
- if(getCode === eventCode.MOVED && listener.onTouchMoved){
- listener.onTouchMoved(selTouch, event);
- } else if(getCode === eventCode.ENDED){
- if (listener.onTouchEnded)
- listener.onTouchEnded(selTouch, event);
- if (listener._registered)
- listener._claimedTouches.splice(removedIdx, 1);
- } else if(getCode === eventCode.CANCELLED){
- if (listener.onTouchCancelled)
- listener.onTouchCancelled(selTouch, event);
- if (listener._registered)
- listener._claimedTouches.splice(removedIdx, 1);
- }
- }
- // If the event was stopped, return directly.
- if (event.isStopped()) {
- cc.eventManager._updateListeners(event);
- return true;
- }
- if (isClaimed && listener._registered && listener.swallowTouches) {
- if (argsObj.needsMutableSet)
- argsObj.touches.splice(selTouch, 1);
- return true;
- }
- return false;
- },
- _dispatchTouchEvent: function (event) {
- this._sortEventListeners(cc._EventListenerTouchOneByOne.LISTENER_ID);
- this._sortEventListeners(cc._EventListenerTouchAllAtOnce.LISTENER_ID);
- var oneByOneListeners = this._getListeners(cc._EventListenerTouchOneByOne.LISTENER_ID);
- var allAtOnceListeners = this._getListeners(cc._EventListenerTouchAllAtOnce.LISTENER_ID);
- // If there aren't any touch listeners, return directly.
- if (null == oneByOneListeners && null == allAtOnceListeners)
- return;
- var originalTouches = event.getTouches(), mutableTouches = cc.copyArray(originalTouches);
- var oneByOneArgsObj = {event: event, needsMutableSet: (oneByOneListeners && allAtOnceListeners), touches: mutableTouches, selTouch: null};
- //
- // process the target handlers 1st
- //
- if (oneByOneListeners) {
- for (var i = 0; i < originalTouches.length; i++) {
- oneByOneArgsObj.selTouch = originalTouches[i];
- this._dispatchEventToListeners(oneByOneListeners, this._onTouchEventCallback, oneByOneArgsObj);
- if (event.isStopped())
- return;
- }
- }
- //
- // process standard handlers 2nd
- //
- if (allAtOnceListeners && mutableTouches.length > 0) {
- this._dispatchEventToListeners(allAtOnceListeners, this._onTouchesEventCallback, {event: event, touches: mutableTouches});
- if (event.isStopped())
- return;
- }
- this._updateListeners(event);
- },
- _onTouchesEventCallback: function (listener, callbackParams) {
- // Skip if the listener was removed.
- if (!listener._registered)
- return false;
- var eventCode = cc.EventTouch.EventCode, event = callbackParams.event, touches = callbackParams.touches, getCode = event.getEventCode();
- event._setCurrentTarget(listener._node);
- if(getCode == eventCode.BEGAN && listener.onTouchesBegan)
- listener.onTouchesBegan(touches, event);
- else if(getCode == eventCode.MOVED && listener.onTouchesMoved)
- listener.onTouchesMoved(touches, event);
- else if(getCode == eventCode.ENDED && listener.onTouchesEnded)
- listener.onTouchesEnded(touches, event);
- else if(getCode == eventCode.CANCELLED && listener.onTouchesCancelled)
- listener.onTouchesCancelled(touches, event);
- // If the event was stopped, return directly.
- if (event.isStopped()) {
- cc.eventManager._updateListeners(event);
- return true;
- }
- return false;
- },
- _associateNodeAndEventListener: function (node, listener) {
- var listeners = this._nodeListenersMap[node.__instanceId];
- if (!listeners) {
- listeners = [];
- this._nodeListenersMap[node.__instanceId] = listeners;
- }
- listeners.push(listener);
- },
- _dissociateNodeAndEventListener: function (node, listener) {
- var listeners = this._nodeListenersMap[node.__instanceId];
- if (listeners) {
- cc.arrayRemoveObject(listeners, listener);
- if (listeners.length === 0)
- delete this._nodeListenersMap[node.__instanceId];
- }
- },
- _dispatchEventToListeners: function (listeners, onEvent, eventOrArgs) {
- var shouldStopPropagation = false;
- var fixedPriorityListeners = listeners.getFixedPriorityListeners();
- var sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
- var i = 0, j, selListener;
- if (fixedPriorityListeners) { // priority < 0
- if (fixedPriorityListeners.length !== 0) {
- for (; i < listeners.gt0Index; ++i) {
- selListener = fixedPriorityListeners[i];
- if (selListener.isEnabled() && !selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
- shouldStopPropagation = true;
- break;
- }
- }
- }
- }
- if (sceneGraphPriorityListeners && !shouldStopPropagation) { // priority == 0, scene graph priority
- for (j = 0; j < sceneGraphPriorityListeners.length; j++) {
- selListener = sceneGraphPriorityListeners[j];
- if (selListener.isEnabled() && !selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
- shouldStopPropagation = true;
- break;
- }
- }
- }
- if (fixedPriorityListeners && !shouldStopPropagation) { // priority > 0
- for (; i < fixedPriorityListeners.length; ++i) {
- selListener = fixedPriorityListeners[i];
- if (selListener.isEnabled() && !selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
- shouldStopPropagation = true;
- break;
- }
- }
- }
- },
- _setDirty: function (listenerID, flag) {
- var locDirtyFlagMap = this._priorityDirtyFlagMap;
- if (locDirtyFlagMap[listenerID] == null)
- locDirtyFlagMap[listenerID] = flag;
- else
- locDirtyFlagMap[listenerID] = flag | locDirtyFlagMap[listenerID];
- },
- _visitTarget: function (node, isRootNode) {
- var children = node.getChildren(), i = 0;
- var childrenCount = children.length, locGlobalZOrderNodeMap = this._globalZOrderNodeMap, locNodeListenersMap = this._nodeListenersMap;
- if (childrenCount > 0) {
- var child;
- // visit children zOrder < 0
- for (; i < childrenCount; i++) {
- child = children[i];
- if (child && child.getLocalZOrder() < 0)
- this._visitTarget(child, false);
- else
- break;
- }
- if (locNodeListenersMap[node.__instanceId] != null) {
- if (!locGlobalZOrderNodeMap[node.getGlobalZOrder()])
- locGlobalZOrderNodeMap[node.getGlobalZOrder()] = [];
- locGlobalZOrderNodeMap[node.getGlobalZOrder()].push(node.__instanceId);
- }
- for (; i < childrenCount; i++) {
- child = children[i];
- if (child)
- this._visitTarget(child, false);
- }
- } else {
- if (locNodeListenersMap[node.__instanceId] != null) {
- if (!locGlobalZOrderNodeMap[node.getGlobalZOrder()])
- locGlobalZOrderNodeMap[node.getGlobalZOrder()] = [];
- locGlobalZOrderNodeMap[node.getGlobalZOrder()].push(node.__instanceId);
- }
- }
- if (isRootNode) {
- var globalZOrders = [];
- for (var selKey in locGlobalZOrderNodeMap)
- globalZOrders.push(selKey);
- globalZOrders.sort(this._sortNumberAsc);
- var zOrdersLen = globalZOrders.length, selZOrders, j, locNodePriorityMap = this._nodePriorityMap;
- for (i = 0; i < zOrdersLen; i++) {
- selZOrders = locGlobalZOrderNodeMap[globalZOrders[i]];
- for (j = 0; j < selZOrders.length; j++)
- locNodePriorityMap[selZOrders[j]] = ++this._nodePriorityIndex;
- }
- this._globalZOrderNodeMap = {};
- }
- },
- _sortNumberAsc : function (a, b) {
- return a - b;
- },
- /**
- * <p>
- * Adds a event listener for a specified event. <br/>
- * if the parameter "nodeOrPriority" is a node, it means to add a event listener for a specified event with the priority of scene graph. <br/>
- * if the parameter "nodeOrPriority" is a Number, it means to add a event listener for a specified event with the fixed priority. <br/>
- * </p>
- * @param {cc.EventListener|Object} listener The listener of a specified event or a object of some event parameters.
- * @param {cc.Node|Number} nodeOrPriority The priority of the listener is based on the draw order of this node or fixedPriority The fixed priority of the listener.
- * @note The priority of scene graph will be fixed value 0. So the order of listener item in the vector will be ' <0, scene graph (0 priority), >0'.
- * A lower priority will be called before the ones that have a higher value. 0 priority is forbidden for fixed priority since it's used for scene graph based priority.
- * The listener must be a cc.EventListener object when adding a fixed priority listener, because we can't remove a fixed priority listener without the listener handler,
- * except calls removeAllListeners().
- */
- addListener: function (listener, nodeOrPriority) {
- cc.assert(listener && nodeOrPriority, cc._LogInfos.eventManager_addListener_2);
- if(!(listener instanceof cc.EventListener)){
- cc.assert(typeof nodeOrPriority !== "number", cc._LogInfos.eventManager_addListener_3);
- listener = cc.EventListener.create(listener);
- } else {
- if(listener._isRegistered()){
- cc.log(cc._LogInfos.eventManager_addListener_4);
- return;
- }
- }
- if (!listener.checkAvailable())
- return;
- if (typeof nodeOrPriority == "number") {
- if (nodeOrPriority == 0) {
- cc.log(cc._LogInfos.eventManager_addListener);
- return;
- }
- listener._setSceneGraphPriority(null);
- listener._setFixedPriority(nodeOrPriority);
- listener._setRegistered(true);
- listener._setPaused(false);
- this._addListener(listener);
- } else {
- listener._setSceneGraphPriority(nodeOrPriority);
- listener._setFixedPriority(0);
- listener._setRegistered(true);
- this._addListener(listener);
- }
- },
- /**
- * Adds a Custom event listener. It will use a fixed priority of 1.
- * @param {string} eventName
- * @param {function} callback
- * @return {cc.EventListener} the generated event. Needed in order to remove the event from the dispatcher
- */
- addCustomListener: function (eventName, callback) {
- var listener = cc._EventListenerCustom.create(eventName, callback);
- this.addListener(listener, 1);
- return listener;
- },
- /**
- * Remove a listener
- * @param {cc.EventListener} listener an event listener or a registered node target
- */
- removeListener: function (listener) {
- if (listener == null)
- return;
- var isFound, locListener = this._listenersMap;
- for (var selKey in locListener) {
- var listeners = locListener[selKey];
- var fixedPriorityListeners = listeners.getFixedPriorityListeners(), sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
- isFound = this._removeListenerInVector(sceneGraphPriorityListeners, listener);
- if (isFound){
- // fixed #4160: Dirty flag need to be updated after listeners were removed.
- this._setDirty(listener._getListenerID(), this.DIRTY_SCENE_GRAPH_PRIORITY);
- }else{
- isFound = this._removeListenerInVector(fixedPriorityListeners, listener);
- if (isFound)
- this._setDirty(listener._getListenerID(), this.DIRTY_FIXED_PRIORITY);
- }
- if (listeners.empty()) {
- delete this._priorityDirtyFlagMap[listener._getListenerID()];
- delete locListener[selKey];
- }
- if (isFound)
- break;
- }
- if (!isFound) {
- var locToAddedListeners = this._toAddedListeners;
- for (var i = 0, len = locToAddedListeners.length; i < len; i++) {
- var selListener = locToAddedListeners[i];
- if (selListener == listener) {
- cc.arrayRemoveObject(locToAddedListeners, selListener);
- break;
- }
- }
- }
- },
- _removeListenerInVector : function(listeners, listener){
- if (listeners == null)
- return false;
- for (var i = 0, len = listeners.length; i < len; i++) {
- var selListener = listeners[i];
- if (selListener == listener) {
- selListener._setRegistered(false);
- if (selListener._getSceneGraphPriority() != null){
- this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
- selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
- }
- if (this._inDispatch == 0)
- cc.arrayRemoveObject(listeners, selListener);
- return true;
- }
- }
- return false;
- },
- /**
- * Removes all listeners with the same event listener type or removes all listeners of a node
- * @param {Number|cc.Node} listenerType listenerType or a node
- * @param {Boolean} [recursive=false]
- */
- removeListeners: function (listenerType, recursive) {
- var _t = this;
- if (listenerType instanceof cc.Node) {
- // Ensure the node is removed from these immediately also.
- // Don't want any dangling pointers or the possibility of dealing with deleted objects..
- delete _t._nodePriorityMap[listenerType.__instanceId];
- cc.arrayRemoveObject(_t._dirtyNodes, listenerType);
- var listeners = _t._nodeListenersMap[listenerType.__instanceId], i;
- if (listeners) {
- var listenersCopy = cc.copyArray(listeners);
- for (i = 0; i < listenersCopy.length; i++)
- _t.removeListener(listenersCopy[i]);
- listenersCopy.length = 0;
- }
- // Bug fix: ensure there are no references to the node in the list of listeners to be added.
- // If we find any listeners associated with the destroyed node in this list then remove them.
- // This is to catch the scenario where the node gets destroyed before it's listener
- // is added into the event dispatcher fully. This could happen if a node registers a listener
- // and gets destroyed while we are dispatching an event (touch etc.)
- var locToAddedListeners = _t._toAddedListeners;
- for (i = 0; i < locToAddedListeners.length; ) {
- var listener = locToAddedListeners[i];
- if (listener._getSceneGraphPriority() == listenerType) {
- listener._setSceneGraphPriority(null); // Ensure no dangling ptr to the target node.
- listener._setRegistered(false);
- locToAddedListeners.splice(i, 1);
- } else
- ++i;
- }
- if (recursive === true) {
- var locChildren = listenerType.getChildren(), len;
- for (i = 0, len = locChildren.length; i< len; i++)
- _t.removeListeners(locChildren[i], true);
- }
- } else {
- if (listenerType == cc.EventListener.TOUCH_ONE_BY_ONE)
- _t._removeListenersForListenerID(cc._EventListenerTouchOneByOne.LISTENER_ID);
- else if (listenerType == cc.EventListener.TOUCH_ALL_AT_ONCE)
- _t._removeListenersForListenerID(cc._EventListenerTouchAllAtOnce.LISTENER_ID);
- else if (listenerType == cc.EventListener.MOUSE)
- _t._removeListenersForListenerID(cc._EventListenerMouse.LISTENER_ID);
- else if (listenerType == cc.EventListener.ACCELERATION)
- _t._removeListenersForListenerID(cc._EventListenerAcceleration.LISTENER_ID);
- else if (listenerType == cc.EventListener.KEYBOARD)
- _t._removeListenersForListenerID(cc._EventListenerKeyboard.LISTENER_ID);
- else
- cc.log(cc._LogInfos.eventManager_removeListeners);
- }
- },
- /**
- * Removes all custom listeners with the same event name
- * @param {string} customEventName
- */
- removeCustomListeners: function (customEventName) {
- this._removeListenersForListenerID(customEventName);
- },
- /**
- * Removes all listeners
- */
- removeAllListeners: function () {
- var locListeners = this._listenersMap, locInternalCustomEventIDs = this._internalCustomListenerIDs;
- for (var selKey in locListeners){
- if(locInternalCustomEventIDs.indexOf(selKey) === -1)
- this._removeListenersForListenerID(selKey);
- }
- },
- /**
- * Sets listener's priority with fixed value.
- * @param {cc.EventListener} listener
- * @param {Number} fixedPriority
- */
- setPriority: function (listener, fixedPriority) {
- if (listener == null)
- return;
- var locListeners = this._listenersMap;
- for (var selKey in locListeners) {
- var selListeners = locListeners[selKey];
- var fixedPriorityListeners = selListeners.getFixedPriorityListeners();
- if (fixedPriorityListeners) {
- var found = fixedPriorityListeners.indexOf(listener);
- if (found != -1) {
- if(listener._getSceneGraphPriority() != null)
- cc.log(cc._LogInfos.eventManager_setPriority);
- if (listener._getFixedPriority() !== fixedPriority) {
- listener._setFixedPriority(fixedPriority);
- this._setDirty(listener._getListenerID(), this.DIRTY_FIXED_PRIORITY);
- }
- return;
- }
- }
- }
- },
- /**
- * Whether to enable dispatching events
- * @param {boolean} enabled
- */
- setEnabled: function (enabled) {
- this._isEnabled = enabled;
- },
- /**
- * Checks whether dispatching events is enabled
- * @returns {boolean}
- */
- isEnabled: function () {
- return this._isEnabled;
- },
- /**
- * Dispatches the event, also removes all EventListeners marked for deletion from the event dispatcher list.
- * @param {cc.Event} event
- */
- dispatchEvent: function (event) {
- if (!this._isEnabled)
- return;
- this._updateDirtyFlagForSceneGraph();
- this._inDispatch++;
- if(!event || !event.getType)
- throw "event is undefined";
- if (event.getType() == cc.Event.TOUCH) {
- this._dispatchTouchEvent(event);
- this._inDispatch--;
- return;
- }
- var listenerID = cc.__getListenerID(event);
- this._sortEventListeners(listenerID);
- var selListeners = this._listenersMap[listenerID];
- if (selListeners != null)
- this._dispatchEventToListeners(selListeners, this._onListenerCallback, event);
- this._updateListeners(event);
- this._inDispatch--;
- },
- _onListenerCallback: function(listener, event){
- event._setCurrentTarget(listener._getSceneGraphPriority());
- listener._onEvent(event);
- return event.isStopped();
- },
- /**
- * Dispatches a Custom Event with a event name an optional user data
- * @param {string} eventName
- * @param {*} optionalUserData
- */
- dispatchCustomEvent: function (eventName, optionalUserData) {
- var ev = new cc.EventCustom(eventName);
- ev.setUserData(optionalUserData);
- this.dispatchEvent(ev);
- }
- };
|