Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions cocos2d/core/CCDirector.js
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,10 @@ cc.Director = cc.Class.extend(/** @lends cc.director# */{
//cleanup scheduler
this.getScheduler().unscheduleAllCallbacks();

// Disable event dispatching
if(cc.eventManager)
cc.eventManager.setEnabled(false);

// don't release the event handlers
// They are needed in case the director is run again

Expand Down Expand Up @@ -878,16 +882,15 @@ if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
};

_p.setDepthTest = function () {
return;
};

_p.setOpenGLView = function (openGLView) {
// set size
this._winSizeInPoints.width = cc._canvas.width; //this._openGLView.getDesignResolutionSize();
this._winSizeInPoints.height = cc._canvas.height;
this._openGLView = openGLView || cc.view;

return;
if(cc.eventManager)
cc.eventManager.setEnabled(true);
};

_p._clear = function() {
Expand Down
2 changes: 2 additions & 0 deletions cocos2d/core/CCDirectorWebGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ if (cc._renderType === cc._RENDER_TYPE_WEBGL) {
}*/

//}
if(cc.eventManager)
cc.eventManager.setEnabled(true);
};

_p._clear = function() {
Expand Down
84 changes: 83 additions & 1 deletion cocos2d/core/event-manager/CCEventListener.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/****************************************************************************
Copyright (c) 2010-2014 cocos2d-x.org
Copyright (c) 2010-2014 Chukong Technologies Inc.

http://www.cocos2d-x.org

Expand Down Expand Up @@ -41,6 +41,7 @@ cc.EventListener = cc.Class.extend(/** @lends cc.EventListener# */{
_fixedPriority: 0, // The higher the number, the higher the priority, 0 is for scene graph base priority.
_node: null, // scene graph based priority
_paused: false, // Whether the listener is paused
_isEnabled: true, // Whether the listener is enabled

/**
* Initializes event with type and callback function
Expand All @@ -54,42 +55,103 @@ cc.EventListener = cc.Class.extend(/** @lends cc.EventListener# */{
this._listenerID = listenerID || "";
},

/**
* <p>
* Sets paused state for the listener
* The paused state is only used for scene graph priority listeners.
* `EventDispatcher::resumeAllEventListenersForTarget(node)` will set the paused state to `true`,
* while `EventDispatcher::pauseAllEventListenersForTarget(node)` will set it to `false`.
* @note 1) Fixed priority listeners will never get paused. If a fixed priority doesn't want to receive events,
* call `setEnabled(false)` instead.
* 2) In `Node`'s onEnter and onExit, the `paused state` of the listeners which associated with that node will be automatically updated.
* </p>
* @param {boolean} paused
* @private
*/
_setPaused: function (paused) {
this._paused = paused;
},

/**
* Checks whether the listener is paused
* @returns {boolean}
* @private
*/
_isPaused: function () {
return this._paused;
},

/**
* Marks the listener was registered by EventDispatcher
* @param {boolean} registered
* @private
*/
_setRegistered: function (registered) {
this._registered = registered;
},

/**
* Checks whether the listener was registered by EventDispatcher
* @returns {boolean}
* @private
*/
_isRegistered: function () {
return this._registered;
},

/**
* Gets the type of this listener
* @note It's different from `EventType`, e.g. TouchEvent has two kinds of event listeners - EventListenerOneByOne, EventListenerAllAtOnce
* @returns {number}
* @private
*/
_getType: function () {
return this._type;
},

/**
* Gets the listener ID of this listener
* When event is being dispatched, listener ID is used as key for searching listeners according to event type.
* @returns {string}
* @private
*/
_getListenerID: function () {
return this._listenerID;
},

/**
* Sets the fixed priority for this listener
* @note This method is only used for `fixed priority listeners`, it needs to access a non-zero value. 0 is reserved for scene graph priority listeners
* @param {number} fixedPriority
* @private
*/
_setFixedPriority: function (fixedPriority) {
this._fixedPriority = fixedPriority;
},

/**
* Gets the fixed priority of this listener
* @returns {number} 0 if it's a scene graph priority listener, non-zero for fixed priority listener
* @private
*/
_getFixedPriority: function () {
return this._fixedPriority;
},

/**
* Sets scene graph priority for this listener
* @param {cc.Node} node
* @private
*/
_setSceneGraphPriority: function (node) {
this._node = node;
},

/**
* Gets scene graph priority of this listener
* @returns {cc.Node} if it's a fixed priority listener, non-null for scene graph priority listener
* @private
*/
_getSceneGraphPriority: function () {
return this._node;
},
Expand All @@ -110,6 +172,26 @@ cc.EventListener = cc.Class.extend(/** @lends cc.EventListener# */{
return null;
},

/**
* Enables or disables the listener
* @note Only listeners with `enabled` state will be able to receive events.
* When an listener was initialized, it's enabled by default.
* An event listener can receive events when it is enabled and is not paused.
* paused state is always false when it is a fixed priority listener.
* @param {boolean} enabled
*/
setEnabled: function(enabled){
this._isEnabled = enabled;
},

/**
* Checks whether the listener is enabled
* @returns {boolean}
*/
isEnabled: function(){
return this._isEnabled;
},

/**
* Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
* and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
Expand Down
51 changes: 38 additions & 13 deletions cocos2d/core/event-manager/CCEventManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
_toAddedListeners: [],
_dirtyNodes: [],
_inDispatch: 0,
_isEnabled: true,
_isEnabled: false,
_nodePriorityIndex: 0,

_internalCustomListenerIDs:[cc.game.EVENT_HIDE, cc.game.EVENT_SHOW],
Expand All @@ -131,6 +131,9 @@ cc.eventManager = /** @lends cc.eventManager# */{
// 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]);
},

/**
Expand Down Expand Up @@ -271,22 +274,28 @@ cc.eventManager = /** @lends cc.eventManager# */{
},

_sortEventListeners: function (listenerID) {
var dirtyFlag = this.DIRTY_NONE;
if (this._priorityDirtyFlagMap[listenerID])
dirtyFlag = this._priorityDirtyFlagMap[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)
this._sortListenersOfSceneGraphPriority(listenerID);

this._priorityDirtyFlagMap[listenerID] = this.DIRTY_NONE;
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) {
_sortListenersOfSceneGraphPriority: function (listenerID, rootNode) {
var listeners = this._getListeners(listenerID);
if (!listeners)
return;
Expand All @@ -295,7 +304,6 @@ cc.eventManager = /** @lends cc.eventManager# */{
if(!sceneGraphListener || sceneGraphListener.length === 0)
return;

var rootNode = cc.director.getRunningScene();
// Reset priority index
this._nodePriorityIndex = 0;
this._nodePriorityMap = {};
Expand Down Expand Up @@ -538,7 +546,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (fixedPriorityListeners.length !== 0) {
for (; i < listeners.gt0Index; ++i) {
selListener = fixedPriorityListeners[i];
if (!selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
if (selListener.isEnabled() && !selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
shouldStopPropagation = true;
break;
}
Expand All @@ -549,7 +557,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (sceneGraphPriorityListeners && !shouldStopPropagation) { // priority == 0, scene graph priority
for (j = 0; j < sceneGraphPriorityListeners.length; j++) {
selListener = sceneGraphPriorityListeners[j];
if (!selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
if (selListener.isEnabled() && !selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
shouldStopPropagation = true;
break;
}
Expand All @@ -559,7 +567,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (fixedPriorityListeners && !shouldStopPropagation) { // priority > 0
for (; i < fixedPriorityListeners.length; ++i) {
selListener = fixedPriorityListeners[i];
if (!selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
if (selListener.isEnabled() && !selListener._isPaused() && selListener._isRegistered() && onEvent(selListener, eventOrArgs)) {
shouldStopPropagation = true;
break;
}
Expand Down Expand Up @@ -777,6 +785,23 @@ cc.eventManager = /** @lends cc.eventManager# */{
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++)
Expand Down
Loading