2013-09-20 22:23:13 +08:00
/****************************************************************************
Copyright ( c ) 2013 cocos2d - x . org
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "CCEventDispatcher.h"
# include "CCEvent.h"
2013-09-21 14:40:54 +08:00
# include "CCEventTouch.h"
2013-10-28 16:00:01 +08:00
# include "CCEventCustom.h"
2013-09-21 14:40:54 +08:00
# include "CCEventListenerTouch.h"
2013-10-14 14:01:00 +08:00
# include "CCNode.h"
2013-09-20 22:23:13 +08:00
# include "CCDirector.h"
# include <algorithm>
2013-10-24 20:50:21 +08:00
# define DUMP_LISTENER_ITEM_PRIORITY_INFO 0
2013-09-20 22:23:13 +08:00
namespace
{
class DispatchGuard
{
public :
DispatchGuard ( int & count ) :
_count ( count )
{
+ + _count ;
}
~ DispatchGuard ( )
{
- - _count ;
}
private :
int & _count ;
} ;
}
NS_CC_BEGIN
2013-10-28 16:00:01 +08:00
static EventListener : : ListenerID getListenerID ( Event * event )
{
EventListener : : ListenerID ret ;
switch ( event - > getType ( ) )
{
case Event : : Type : : ACCELERATION :
ret = static_cast < EventListener : : ListenerID > ( EventListener : : Type : : ACCELERATION ) ;
break ;
case Event : : Type : : CUSTOM :
{
auto customEvent = static_cast < EventCustom * > ( event ) ;
auto listenerID = std : : hash < std : : string > ( ) ( customEvent - > getEventName ( ) ) ;
ret = static_cast < EventListener : : ListenerID > ( listenerID ) ;
}
break ;
case Event : : Type : : KEYBOARD :
ret = static_cast < EventListener : : ListenerID > ( EventListener : : Type : : KEYBOARD ) ;
break ;
2013-10-31 14:19:36 +08:00
case Event : : Type : : MOUSE :
ret = static_cast < EventListener : : ListenerID > ( EventListener : : Type : : MOUSE ) ;
break ;
2013-10-28 16:00:01 +08:00
case Event : : Type : : TOUCH :
// Touch listener is very special, it contains two kinds of listeners, EventListenerTouchOneByOne and EventListenerTouchAllAtOnce.
// return UNKNOW instead.
ret = static_cast < EventListener : : ListenerID > ( EventListener : : Type : : UNKNOWN ) ;
break ;
default :
CCASSERT ( false , " Invalid type! " ) ;
break ;
}
return ret ;
}
2013-10-23 11:27:24 +08:00
EventDispatcher : : EventListenerVector : : EventListenerVector ( )
: _sceneGraphListeners ( nullptr )
, _fixedListeners ( nullptr )
, _gt0Index ( 0 )
2013-10-21 17:22:42 +08:00
{
}
2013-10-23 11:27:24 +08:00
EventDispatcher : : EventListenerVector : : ~ EventListenerVector ( )
2013-10-21 17:22:42 +08:00
{
2013-10-23 11:27:24 +08:00
CC_SAFE_DELETE ( _sceneGraphListeners ) ;
CC_SAFE_DELETE ( _fixedListeners ) ;
2013-10-21 17:22:42 +08:00
}
2013-10-23 11:27:24 +08:00
size_t EventDispatcher : : EventListenerVector : : size ( ) const
2013-10-21 17:22:42 +08:00
{
2013-10-23 11:27:24 +08:00
size_t ret = 0 ;
if ( _sceneGraphListeners )
ret + = _sceneGraphListeners - > size ( ) ;
if ( _fixedListeners )
ret + = _fixedListeners - > size ( ) ;
return ret ;
2013-10-21 17:22:42 +08:00
}
2013-10-23 11:27:24 +08:00
bool EventDispatcher : : EventListenerVector : : empty ( ) const
2013-10-21 17:22:42 +08:00
{
2013-10-23 11:27:24 +08:00
return ( _sceneGraphListeners = = nullptr | | _sceneGraphListeners - > empty ( ) )
& & ( _fixedListeners = = nullptr | | _fixedListeners - > empty ( ) ) ;
2013-10-21 17:22:42 +08:00
}
2013-10-23 11:27:24 +08:00
void EventDispatcher : : EventListenerVector : : push_back ( EventListener * listener )
2013-10-21 17:22:42 +08:00
{
2013-10-28 16:00:01 +08:00
if ( listener - > getFixedPriority ( ) = = 0 )
2013-10-21 17:22:42 +08:00
{
2013-10-23 11:27:24 +08:00
if ( _sceneGraphListeners = = nullptr )
2013-10-21 17:22:42 +08:00
{
2013-10-23 11:27:24 +08:00
_sceneGraphListeners = new std : : vector < EventListener * > ( ) ;
_sceneGraphListeners - > reserve ( 100 ) ;
2013-10-21 17:22:42 +08:00
}
2013-10-23 11:27:24 +08:00
_sceneGraphListeners - > push_back ( listener ) ;
2013-10-21 17:22:42 +08:00
}
else
{
2013-10-23 11:27:24 +08:00
if ( _fixedListeners = = nullptr )
2013-10-21 17:22:42 +08:00
{
2013-10-23 11:27:24 +08:00
_fixedListeners = new std : : vector < EventListener * > ( ) ;
_fixedListeners - > reserve ( 100 ) ;
2013-10-21 17:22:42 +08:00
}
2013-10-23 11:27:24 +08:00
_fixedListeners - > push_back ( listener ) ;
2013-10-21 17:22:42 +08:00
}
}
2013-10-24 17:27:22 +08:00
void EventDispatcher : : EventListenerVector : : clearSceneGraphListeners ( )
2013-10-21 17:22:42 +08:00
{
2013-10-23 11:27:24 +08:00
if ( _sceneGraphListeners )
2013-10-21 17:22:42 +08:00
{
2013-10-23 11:27:24 +08:00
_sceneGraphListeners - > clear ( ) ;
delete _sceneGraphListeners ;
_sceneGraphListeners = nullptr ;
2013-10-21 17:22:42 +08:00
}
2013-10-24 17:27:22 +08:00
}
void EventDispatcher : : EventListenerVector : : clearFixedListeners ( )
{
2013-10-23 11:27:24 +08:00
if ( _fixedListeners )
2013-10-21 17:22:42 +08:00
{
2013-10-23 11:27:24 +08:00
_fixedListeners - > clear ( ) ;
delete _fixedListeners ;
_fixedListeners = nullptr ;
2013-10-21 17:22:42 +08:00
}
2013-09-20 22:23:13 +08:00
}
2013-10-24 17:27:22 +08:00
void EventDispatcher : : EventListenerVector : : clear ( )
{
clearSceneGraphListeners ( ) ;
clearFixedListeners ( ) ;
}
2013-10-23 11:27:24 +08:00
2013-09-20 22:23:13 +08:00
EventDispatcher : : EventDispatcher ( )
: _inDispatch ( 0 )
, _isEnabled ( true )
2013-10-25 17:03:50 +08:00
, _nodePriorityIndex ( 0 )
2013-09-20 22:23:13 +08:00
{
_toAddedListeners . reserve ( 50 ) ;
}
EventDispatcher : : ~ EventDispatcher ( )
{
2013-10-25 16:34:26 +08:00
removeAllEventListeners ( ) ;
2013-09-20 22:23:13 +08:00
}
2013-10-23 16:14:03 +08:00
void EventDispatcher : : visitTarget ( Node * node )
2013-10-23 17:26:14 +08:00
{
2013-12-05 17:19:01 +08:00
int i = 0 ;
2013-11-29 10:37:40 +08:00
auto & children = node - > getChildren ( ) ;
2013-11-28 17:57:13 +08:00
2013-12-05 17:19:01 +08:00
auto childrenCount = children . size ( ) ;
2013-10-23 16:14:03 +08:00
if ( childrenCount > 0 )
{
Node * child = nullptr ;
// visit children zOrder < 0
for ( ; i < childrenCount ; i + + )
{
2013-12-05 10:35:10 +08:00
child = children . at ( i ) ;
2013-10-23 16:14:03 +08:00
if ( child & & child - > getZOrder ( ) < 0 )
visitTarget ( child ) ;
else
break ;
}
2013-10-25 17:03:50 +08:00
_nodePriorityMap . insert ( std : : make_pair ( node , + + _nodePriorityIndex ) ) ;
2013-10-23 16:14:03 +08:00
for ( ; i < childrenCount ; i + + )
{
2013-12-05 10:35:10 +08:00
child = children . at ( i ) ;
2013-10-23 16:14:03 +08:00
if ( child )
visitTarget ( child ) ;
}
}
else
{
2013-10-25 17:03:50 +08:00
_nodePriorityMap . insert ( std : : make_pair ( node , + + _nodePriorityIndex ) ) ;
2013-10-23 16:14:03 +08:00
}
}
void EventDispatcher : : pauseTarget ( Node * node )
{
auto listenerIter = _nodeListenersMap . find ( node ) ;
if ( listenerIter ! = _nodeListenersMap . end ( ) )
{
auto listeners = listenerIter - > second ;
for ( auto & l : * listeners )
{
2013-10-28 16:00:01 +08:00
l - > setPaused ( true ) ;
2013-10-23 16:14:03 +08:00
}
}
}
void EventDispatcher : : resumeTarget ( Node * node )
{
auto listenerIter = _nodeListenersMap . find ( node ) ;
if ( listenerIter ! = _nodeListenersMap . end ( ) )
{
auto listeners = listenerIter - > second ;
for ( auto & l : * listeners )
{
2013-10-28 16:00:01 +08:00
l - > setPaused ( false ) ;
2013-10-23 16:14:03 +08:00
}
}
2013-10-24 20:50:21 +08:00
setDirtyForNode ( node ) ;
2013-10-23 16:14:03 +08:00
}
void EventDispatcher : : cleanTarget ( Node * node )
{
auto listenerIter = _nodeListenersMap . find ( node ) ;
if ( listenerIter ! = _nodeListenersMap . end ( ) )
{
auto listeners = listenerIter - > second ;
2013-10-23 17:13:03 +08:00
auto listenersCopy = * listeners ;
for ( auto & l : listenersCopy )
2013-10-23 16:14:03 +08:00
{
removeEventListener ( l ) ;
}
}
}
2013-10-23 11:27:24 +08:00
void EventDispatcher : : associateNodeAndEventListener ( Node * node , EventListener * listener )
{
std : : vector < EventListener * > * listeners = nullptr ;
auto found = _nodeListenersMap . find ( node ) ;
if ( found ! = _nodeListenersMap . end ( ) )
{
listeners = found - > second ;
}
else
{
listeners = new std : : vector < EventListener * > ( ) ;
}
listeners - > push_back ( listener ) ;
_nodeListenersMap . insert ( std : : make_pair ( node , listeners ) ) ;
}
void EventDispatcher : : dissociateNodeAndEventListener ( Node * node , EventListener * listener )
{
std : : vector < EventListener * > * listeners = nullptr ;
auto found = _nodeListenersMap . find ( node ) ;
if ( found ! = _nodeListenersMap . end ( ) )
{
listeners = found - > second ;
auto iter = std : : find ( listeners - > begin ( ) , listeners - > end ( ) , listener ) ;
if ( iter ! = listeners - > end ( ) )
{
listeners - > erase ( iter ) ;
}
if ( listeners - > empty ( ) )
{
_nodeListenersMap . erase ( found ) ;
2013-10-24 17:27:22 +08:00
delete listeners ;
2013-10-23 11:27:24 +08:00
}
}
}
void EventDispatcher : : addEventListener ( EventListener * listener )
2013-09-20 22:23:13 +08:00
{
if ( _inDispatch = = 0 )
{
2013-10-23 11:27:24 +08:00
EventListenerVector * listenerList = nullptr ;
2013-09-20 22:23:13 +08:00
2013-10-28 16:00:01 +08:00
auto iter = _listeners . find ( listener - > getListenerID ( ) ) ;
2013-09-20 22:23:13 +08:00
if ( iter = = _listeners . end ( ) )
{
2013-10-23 11:27:24 +08:00
listenerList = new EventListenerVector ( ) ;
2013-10-28 16:00:01 +08:00
_listeners . insert ( std : : make_pair ( listener - > getListenerID ( ) , listenerList ) ) ;
2013-09-20 22:23:13 +08:00
}
else
{
listenerList = iter - > second ;
}
2013-10-23 11:27:24 +08:00
listenerList - > push_back ( listener ) ;
2013-10-28 16:00:01 +08:00
if ( listener - > getFixedPriority ( ) = = 0 )
2013-10-23 11:27:24 +08:00
{
2013-10-28 16:00:01 +08:00
setDirty ( listener - > getListenerID ( ) , DirtyFlag : : SCENE_GRAPH_PRIORITY ) ;
2013-10-23 11:27:24 +08:00
}
else
{
2013-10-28 16:00:01 +08:00
setDirty ( listener - > getListenerID ( ) , DirtyFlag : : FIXED_PRITORY ) ;
2013-10-23 11:27:24 +08:00
}
2013-09-20 22:23:13 +08:00
}
else
{
2013-10-23 11:27:24 +08:00
_toAddedListeners . push_back ( listener ) ;
2013-09-20 22:23:13 +08:00
}
}
void EventDispatcher : : addEventListenerWithSceneGraphPriority ( EventListener * listener , Node * node )
{
CCASSERT ( listener & & node , " Invalid parameters. " ) ;
2013-10-28 16:00:01 +08:00
CCASSERT ( ! listener - > isRegistered ( ) , " The listener has been registered. " ) ;
2013-09-20 22:23:13 +08:00
2013-10-12 11:25:28 +08:00
if ( ! listener - > checkAvailable ( ) )
2013-09-20 22:23:13 +08:00
return ;
2013-10-28 16:00:01 +08:00
listener - > setSceneGraphPriority ( node ) ;
listener - > setFixedPriority ( 0 ) ;
listener - > setRegistered ( true ) ;
2013-10-23 11:27:24 +08:00
listener - > retain ( ) ;
addEventListener ( listener ) ;
associateNodeAndEventListener ( node , listener ) ;
if ( node - > isRunning ( ) )
{
resumeTarget ( node ) ;
}
2013-09-20 22:23:13 +08:00
}
void EventDispatcher : : addEventListenerWithFixedPriority ( EventListener * listener , int fixedPriority )
{
CCASSERT ( listener , " Invalid parameters. " ) ;
2013-10-28 16:00:01 +08:00
CCASSERT ( ! listener - > isRegistered ( ) , " The listener has been registered. " ) ;
2013-09-20 22:23:13 +08:00
CCASSERT ( fixedPriority ! = 0 , " 0 priority is forbidden for fixed priority since it's used for scene graph based priority. " ) ;
2013-10-12 11:25:28 +08:00
if ( ! listener - > checkAvailable ( ) )
2013-09-20 22:23:13 +08:00
return ;
2013-10-28 16:00:01 +08:00
listener - > setSceneGraphPriority ( nullptr ) ;
listener - > setFixedPriority ( fixedPriority ) ;
listener - > setRegistered ( true ) ;
listener - > setPaused ( false ) ;
2013-10-23 11:27:24 +08:00
listener - > retain ( ) ;
2013-09-20 22:23:13 +08:00
2013-10-23 11:27:24 +08:00
addEventListener ( listener ) ;
2013-09-20 22:23:13 +08:00
}
void EventDispatcher : : removeEventListener ( EventListener * listener )
{
if ( listener = = nullptr )
return ;
bool isFound = false ;
2013-10-23 11:27:24 +08:00
auto removeListenerInVector = [ & ] ( std : : vector < EventListener * > * listeners ) {
if ( listeners = = nullptr )
return ;
2013-10-21 17:22:42 +08:00
2013-10-23 11:27:24 +08:00
for ( auto iter = listeners - > begin ( ) ; iter ! = listeners - > end ( ) ; + + iter )
{
auto l = * iter ;
if ( l = = listener )
2013-09-20 22:23:13 +08:00
{
2013-10-24 11:17:29 +08:00
CC_SAFE_RETAIN ( l ) ;
2013-10-28 16:00:01 +08:00
l - > setRegistered ( false ) ;
if ( l - > getSceneGraphPriority ( ) ! = nullptr )
2013-09-20 22:23:13 +08:00
{
2013-10-28 16:00:01 +08:00
dissociateNodeAndEventListener ( l - > getSceneGraphPriority ( ) , l ) ;
2013-09-20 22:23:13 +08:00
}
if ( _inDispatch = = 0 )
{
2013-10-23 11:27:24 +08:00
listeners - > erase ( iter ) ;
2013-10-24 17:27:22 +08:00
CC_SAFE_RELEASE ( l ) ;
2013-09-20 22:23:13 +08:00
}
2013-10-21 17:22:42 +08:00
2013-09-20 22:23:13 +08:00
isFound = true ;
2013-10-23 11:27:24 +08:00
break ;
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
}
} ;
for ( auto iter = _listeners . begin ( ) ; iter ! = _listeners . end ( ) ; )
{
auto listeners = iter - > second ;
auto fixedPriorityListeners = listeners - > getFixedPriorityListeners ( ) ;
auto sceneGraphPriorityListeners = listeners - > getSceneGraphPriorityListeners ( ) ;
2013-10-24 11:17:29 +08:00
2013-10-23 11:27:24 +08:00
removeListenerInVector ( sceneGraphPriorityListeners ) ;
if ( ! isFound )
{
removeListenerInVector ( fixedPriorityListeners ) ;
}
2013-09-20 22:23:13 +08:00
if ( iter - > second - > empty ( ) )
{
2013-10-28 16:00:01 +08:00
_priorityDirtyFlagMap . erase ( listener - > getListenerID ( ) ) ;
2013-09-20 22:23:13 +08:00
auto list = iter - > second ;
iter = _listeners . erase ( iter ) ;
CC_SAFE_DELETE ( list ) ;
}
else
{
+ + iter ;
}
if ( isFound )
break ;
}
2013-11-02 22:08:08 +08:00
if ( isFound )
{
2013-09-20 22:23:13 +08:00
CC_SAFE_RELEASE ( listener ) ;
2013-11-02 22:08:08 +08:00
}
else
{
for ( auto iter = _toAddedListeners . begin ( ) ; iter ! = _toAddedListeners . end ( ) ; + + iter )
{
if ( * iter = = listener )
2013-11-02 15:03:54 +08:00
{
_toAddedListeners . erase ( iter ) ;
break ;
}
}
2013-09-20 22:23:13 +08:00
}
}
void EventDispatcher : : setPriority ( EventListener * listener , int fixedPriority )
{
if ( listener = = nullptr )
return ;
for ( auto iter = _listeners . begin ( ) ; iter ! = _listeners . end ( ) ; + + iter )
{
2013-10-23 11:27:24 +08:00
auto fixedPriorityListeners = iter - > second - > getFixedPriorityListeners ( ) ;
if ( fixedPriorityListeners )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
auto found = std : : find ( fixedPriorityListeners - > begin ( ) , fixedPriorityListeners - > end ( ) , listener ) ;
if ( found ! = fixedPriorityListeners - > end ( ) )
2013-09-20 22:23:13 +08:00
{
2013-10-28 16:00:01 +08:00
CCASSERT ( listener - > getSceneGraphPriority ( ) = = nullptr , " Can't set fixed priority with scene graph based listener. " ) ;
2013-09-20 22:23:13 +08:00
2013-10-28 16:00:01 +08:00
if ( listener - > getFixedPriority ( ) ! = fixedPriority )
2013-09-20 22:23:13 +08:00
{
2013-10-28 16:00:01 +08:00
listener - > setFixedPriority ( fixedPriority ) ;
setDirty ( listener - > getListenerID ( ) , DirtyFlag : : FIXED_PRITORY ) ;
2013-09-20 22:23:13 +08:00
}
return ;
}
}
}
}
2013-10-23 11:27:24 +08:00
void EventDispatcher : : dispatchEventToListeners ( EventListenerVector * listeners , std : : function < bool ( EventListener * ) > onEvent )
{
bool shouldStopPropagation = false ;
auto fixedPriorityListeners = listeners - > getFixedPriorityListeners ( ) ;
auto sceneGraphPriorityListeners = listeners - > getSceneGraphPriorityListeners ( ) ;
2013-12-05 17:19:01 +08:00
int i = 0 ;
2013-10-23 11:27:24 +08:00
// priority < 0
if ( fixedPriorityListeners )
{
for ( ; ! fixedPriorityListeners - > empty ( ) & & i < listeners - > getGt0Index ( ) ; + + i )
{
auto l = fixedPriorityListeners - > at ( i ) ;
2013-10-24 11:17:29 +08:00
if ( ! l - > isPaused ( ) & & l - > isRegistered ( ) & & onEvent ( l ) )
2013-10-23 11:27:24 +08:00
{
shouldStopPropagation = true ;
break ;
}
}
}
if ( sceneGraphPriorityListeners )
{
if ( ! shouldStopPropagation )
{
// priority == 0, scene graph priority
2013-10-24 11:17:29 +08:00
for ( auto & l : * sceneGraphPriorityListeners )
2013-10-23 11:27:24 +08:00
{
2013-10-24 11:17:29 +08:00
if ( ! l - > isPaused ( ) & & l - > isRegistered ( ) & & onEvent ( l ) )
2013-10-23 11:27:24 +08:00
{
shouldStopPropagation = true ;
break ;
}
}
}
}
if ( fixedPriorityListeners )
{
if ( ! shouldStopPropagation )
{
// priority > 0
2013-12-05 17:19:01 +08:00
for ( ; i < fixedPriorityListeners - > size ( ) ; + + i )
2013-10-23 11:27:24 +08:00
{
auto l = fixedPriorityListeners - > at ( i ) ;
2013-10-24 11:17:29 +08:00
if ( ! l - > isPaused ( ) & & l - > isRegistered ( ) & & onEvent ( fixedPriorityListeners - > at ( i ) ) )
2013-10-23 11:27:24 +08:00
{
shouldStopPropagation = true ;
break ;
}
}
}
}
}
void EventDispatcher : : dispatchEvent ( Event * event )
2013-09-20 22:23:13 +08:00
{
if ( ! _isEnabled )
return ;
2013-10-23 11:27:24 +08:00
updateDirtyFlagForSceneGraph ( ) ;
2013-10-25 10:35:48 +08:00
DispatchGuard guard ( _inDispatch ) ;
2013-09-20 22:23:13 +08:00
2013-10-28 16:00:01 +08:00
if ( event - > getType ( ) = = Event : : Type : : TOUCH )
2013-09-20 22:23:13 +08:00
{
2013-10-25 10:35:48 +08:00
dispatchTouchEvent ( static_cast < EventTouch * > ( event ) ) ;
return ;
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
2013-10-28 16:00:01 +08:00
auto listenerID = getListenerID ( event ) ;
sortEventListeners ( listenerID ) ;
2013-09-20 22:23:13 +08:00
2013-10-28 16:00:01 +08:00
auto iter = _listeners . find ( listenerID ) ;
2013-09-20 22:23:13 +08:00
if ( iter ! = _listeners . end ( ) )
{
2013-10-23 11:27:24 +08:00
auto listeners = iter - > second ;
auto onEvent = [ & event ] ( EventListener * listener ) - > bool {
2013-10-28 16:00:01 +08:00
event - > setCurrentTarget ( listener - > getSceneGraphPriority ( ) ) ;
2013-10-23 11:27:24 +08:00
listener - > _onEvent ( event ) ;
return event - > isStopped ( ) ;
} ;
dispatchEventToListeners ( listeners , onEvent ) ;
2013-09-20 22:23:13 +08:00
}
2013-10-28 16:00:01 +08:00
updateListeners ( event ) ;
2013-09-20 22:23:13 +08:00
}
void EventDispatcher : : dispatchTouchEvent ( EventTouch * event )
{
2013-10-28 16:00:01 +08:00
auto touchOneByOneID = static_cast < EventListener : : ListenerID > ( EventListener : : Type : : TOUCH_ONE_BY_ONE ) ;
auto touchAllAtOnceID = static_cast < EventListener : : ListenerID > ( EventListener : : Type : : TOUCH_ALL_AT_ONCE ) ;
sortEventListeners ( touchOneByOneID ) ;
sortEventListeners ( touchAllAtOnceID ) ;
2013-10-23 11:27:24 +08:00
2013-10-28 16:00:01 +08:00
auto oneByOnelisteners = getListeners ( touchOneByOneID ) ;
auto allAtOncelisteners = getListeners ( touchAllAtOnceID ) ;
2013-09-20 22:23:13 +08:00
2013-10-12 11:25:28 +08:00
// If there aren't any touch listeners, return directly.
if ( nullptr = = oneByOnelisteners & & nullptr = = allAtOncelisteners )
return ;
2013-09-20 22:23:13 +08:00
2013-10-12 11:25:28 +08:00
bool isNeedsMutableSet = ( oneByOnelisteners & & allAtOncelisteners ) ;
2013-09-20 22:23:13 +08:00
std : : vector < Touch * > orignalTouches = event - > getTouches ( ) ;
std : : vector < Touch * > mutableTouches ( orignalTouches . size ( ) ) ;
std : : copy ( orignalTouches . begin ( ) , orignalTouches . end ( ) , mutableTouches . begin ( ) ) ;
2013-10-23 11:27:24 +08:00
2013-09-20 22:23:13 +08:00
//
// process the target handlers 1st
//
2013-10-12 11:25:28 +08:00
if ( oneByOnelisteners )
2013-09-20 22:23:13 +08:00
{
auto mutableTouchesIter = mutableTouches . begin ( ) ;
auto touchesIter = orignalTouches . begin ( ) ;
for ( ; touchesIter ! = orignalTouches . end ( ) ; + + touchesIter )
{
bool isSwallowed = false ;
2013-10-23 11:27:24 +08:00
auto onTouchEvent = [ & ] ( EventListener * l ) - > bool { // Return true to break
EventListenerTouchOneByOne * listener = static_cast < EventListenerTouchOneByOne * > ( l ) ;
2013-09-20 22:23:13 +08:00
// Skip if the listener was removed.
2013-10-23 11:27:24 +08:00
if ( ! listener - > _isRegistered )
return false ;
2013-09-20 22:23:13 +08:00
2013-10-23 11:27:24 +08:00
event - > setCurrentTarget ( listener - > _node ) ;
2013-09-20 22:23:13 +08:00
bool isClaimed = false ;
std : : vector < Touch * > : : iterator removedIter ;
EventTouch : : EventCode eventCode = event - > getEventCode ( ) ;
if ( eventCode = = EventTouch : : EventCode : : BEGAN )
{
2013-10-23 11:27:24 +08:00
if ( listener - > onTouchBegan )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
isClaimed = listener - > onTouchBegan ( * touchesIter , event ) ;
if ( isClaimed & & listener - > _isRegistered )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > _claimedTouches . push_back ( * touchesIter ) ;
2013-09-20 22:23:13 +08:00
}
}
}
2013-10-23 11:27:24 +08:00
else if ( listener - > _claimedTouches . size ( ) > 0
& & ( ( removedIter = std : : find ( listener - > _claimedTouches . begin ( ) , listener - > _claimedTouches . end ( ) , * touchesIter ) ) ! = listener - > _claimedTouches . end ( ) ) )
2013-09-20 22:23:13 +08:00
{
isClaimed = true ;
switch ( eventCode )
{
case EventTouch : : EventCode : : MOVED :
2013-10-23 11:27:24 +08:00
if ( listener - > onTouchMoved )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > onTouchMoved ( * touchesIter , event ) ;
2013-09-20 22:23:13 +08:00
}
break ;
case EventTouch : : EventCode : : ENDED :
2013-10-23 11:27:24 +08:00
if ( listener - > onTouchEnded )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > onTouchEnded ( * touchesIter , event ) ;
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
if ( listener - > _isRegistered )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > _claimedTouches . erase ( removedIter ) ;
2013-09-20 22:23:13 +08:00
}
break ;
case EventTouch : : EventCode : : CANCELLED :
2013-10-23 11:27:24 +08:00
if ( listener - > onTouchCancelled )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > onTouchCancelled ( * touchesIter , event ) ;
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
if ( listener - > _isRegistered )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > _claimedTouches . erase ( removedIter ) ;
2013-09-20 22:23:13 +08:00
}
break ;
default :
CCASSERT ( false , " The eventcode is invalid. " ) ;
break ;
}
}
// If the event was stopped, return directly.
if ( event - > isStopped ( ) )
{
2013-10-28 16:00:01 +08:00
updateListeners ( event ) ;
2013-10-23 11:27:24 +08:00
return true ;
2013-09-20 22:23:13 +08:00
}
CCASSERT ( ( * touchesIter ) - > getID ( ) = = ( * mutableTouchesIter ) - > getID ( ) , " " ) ;
2013-10-23 11:27:24 +08:00
if ( isClaimed & & listener - > _isRegistered & & listener - > _needSwallow )
2013-09-20 22:23:13 +08:00
{
if ( isNeedsMutableSet )
{
mutableTouchesIter = mutableTouches . erase ( mutableTouchesIter ) ;
isSwallowed = true ;
}
2013-10-23 11:27:24 +08:00
return true ;
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
return false ;
} ;
//
dispatchEventToListeners ( oneByOnelisteners , onTouchEvent ) ;
if ( event - > isStopped ( ) )
{
return ;
2013-09-20 22:23:13 +08:00
}
if ( ! isSwallowed )
+ + mutableTouchesIter ;
}
}
//
// process standard handlers 2nd
//
2013-10-12 11:25:28 +08:00
if ( allAtOncelisteners & & mutableTouches . size ( ) > 0 )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
auto onTouchesEvent = [ & ] ( EventListener * l ) - > bool {
EventListenerTouchAllAtOnce * listener = static_cast < EventListenerTouchAllAtOnce * > ( l ) ;
2013-09-20 22:23:13 +08:00
// Skip if the listener was removed.
2013-10-23 11:27:24 +08:00
if ( ! listener - > _isRegistered )
return false ;
2013-09-20 22:23:13 +08:00
2013-10-23 11:27:24 +08:00
event - > setCurrentTarget ( listener - > _node ) ;
2013-09-20 22:23:13 +08:00
switch ( event - > getEventCode ( ) )
{
case EventTouch : : EventCode : : BEGAN :
2013-10-23 11:27:24 +08:00
if ( listener - > onTouchesBegan )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > onTouchesBegan ( mutableTouches , event ) ;
2013-09-20 22:23:13 +08:00
}
break ;
case EventTouch : : EventCode : : MOVED :
2013-10-23 11:27:24 +08:00
if ( listener - > onTouchesMoved )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > onTouchesMoved ( mutableTouches , event ) ;
2013-09-20 22:23:13 +08:00
}
break ;
case EventTouch : : EventCode : : ENDED :
2013-10-23 11:27:24 +08:00
if ( listener - > onTouchesEnded )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > onTouchesEnded ( mutableTouches , event ) ;
2013-09-20 22:23:13 +08:00
}
break ;
case EventTouch : : EventCode : : CANCELLED :
2013-10-23 11:27:24 +08:00
if ( listener - > onTouchesCancelled )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
listener - > onTouchesCancelled ( mutableTouches , event ) ;
2013-09-20 22:23:13 +08:00
}
break ;
default :
CCASSERT ( false , " The eventcode is invalid. " ) ;
break ;
}
// If the event was stopped, return directly.
if ( event - > isStopped ( ) )
{
2013-10-28 16:00:01 +08:00
updateListeners ( event ) ;
2013-10-23 11:27:24 +08:00
return false ;
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
return false ;
} ;
dispatchEventToListeners ( allAtOncelisteners , onTouchesEvent ) ;
if ( event - > isStopped ( ) )
{
return ;
2013-09-20 22:23:13 +08:00
}
}
2013-10-28 16:00:01 +08:00
updateListeners ( event ) ;
2013-09-20 22:23:13 +08:00
}
2013-10-28 16:00:01 +08:00
void EventDispatcher : : updateListeners ( Event * event )
2013-09-20 22:23:13 +08:00
{
2013-10-28 16:00:01 +08:00
auto onUpdateListeners = [ this ] ( EventListener : : ListenerID listenerID )
2013-09-20 22:23:13 +08:00
{
2013-10-28 16:00:01 +08:00
auto listenersIter = _listeners . find ( listenerID ) ;
2013-10-25 10:35:48 +08:00
if ( listenersIter = = _listeners . end ( ) )
return ;
2013-10-23 11:27:24 +08:00
auto listeners = listenersIter - > second ;
auto fixedPriorityListeners = listeners - > getFixedPriorityListeners ( ) ;
auto sceneGraphPriorityListeners = listeners - > getSceneGraphPriorityListeners ( ) ;
if ( sceneGraphPriorityListeners )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
for ( auto iter = sceneGraphPriorityListeners - > begin ( ) ; iter ! = sceneGraphPriorityListeners - > end ( ) ; )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
auto l = * iter ;
2013-10-28 16:00:01 +08:00
if ( ! l - > isRegistered ( ) )
2013-10-23 11:27:24 +08:00
{
iter = sceneGraphPriorityListeners - > erase ( iter ) ;
2013-10-24 11:17:29 +08:00
l - > release ( ) ;
2013-10-23 11:27:24 +08:00
}
else
{
+ + iter ;
}
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
}
if ( fixedPriorityListeners )
{
for ( auto iter = fixedPriorityListeners - > begin ( ) ; iter ! = fixedPriorityListeners - > end ( ) ; )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
auto l = * iter ;
2013-10-28 16:00:01 +08:00
if ( ! l - > isRegistered ( ) )
2013-10-23 11:27:24 +08:00
{
iter = fixedPriorityListeners - > erase ( iter ) ;
2013-10-24 11:17:29 +08:00
l - > release ( ) ;
2013-10-23 11:27:24 +08:00
}
else
{
+ + iter ;
}
2013-09-20 22:23:13 +08:00
}
}
2013-10-24 17:27:22 +08:00
if ( sceneGraphPriorityListeners & & sceneGraphPriorityListeners - > empty ( ) )
{
listeners - > clearSceneGraphListeners ( ) ;
}
if ( fixedPriorityListeners & & fixedPriorityListeners - > empty ( ) )
{
listeners - > clearFixedListeners ( ) ;
}
2013-10-23 11:27:24 +08:00
if ( listenersIter - > second - > empty ( ) )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
_priorityDirtyFlagMap . erase ( listenersIter - > first ) ;
delete listenersIter - > second ;
listenersIter = _listeners . erase ( listenersIter ) ;
2013-09-20 22:23:13 +08:00
}
else
{
2013-10-23 11:27:24 +08:00
+ + listenersIter ;
2013-09-20 22:23:13 +08:00
}
2013-10-25 10:35:48 +08:00
} ;
2013-10-28 16:00:01 +08:00
if ( event - > getType ( ) = = Event : : Type : : TOUCH )
2013-10-25 10:35:48 +08:00
{
2013-10-28 16:00:01 +08:00
onUpdateListeners ( static_cast < EventListener : : ListenerID > ( EventListener : : Type : : TOUCH_ONE_BY_ONE ) ) ;
onUpdateListeners ( static_cast < EventListener : : ListenerID > ( EventListener : : Type : : TOUCH_ALL_AT_ONCE ) ) ;
2013-10-25 10:35:48 +08:00
}
else
{
2013-10-28 16:00:01 +08:00
onUpdateListeners ( getListenerID ( event ) ) ;
2013-09-20 22:23:13 +08:00
}
2013-10-25 10:35:48 +08:00
2013-09-20 22:23:13 +08:00
if ( ! _toAddedListeners . empty ( ) )
{
2013-10-23 11:27:24 +08:00
EventListenerVector * listeners = nullptr ;
2013-09-20 22:23:13 +08:00
2013-10-23 11:27:24 +08:00
for ( auto & listener : _toAddedListeners )
2013-09-20 22:23:13 +08:00
{
2013-10-28 16:00:01 +08:00
EventListener : : ListenerID listenerID = listener - > getListenerID ( ) ;
auto itr = _listeners . find ( listenerID ) ;
2013-09-20 22:23:13 +08:00
if ( itr = = _listeners . end ( ) )
{
2013-10-23 11:27:24 +08:00
listeners = new EventListenerVector ( ) ;
2013-10-28 16:00:01 +08:00
_listeners . insert ( std : : make_pair ( listenerID , listeners ) ) ;
2013-09-20 22:23:13 +08:00
}
else
{
2013-10-23 11:27:24 +08:00
listeners = itr - > second ;
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
listeners - > push_back ( listener ) ;
2013-09-20 22:23:13 +08:00
2013-10-28 16:00:01 +08:00
if ( listener - > getFixedPriority ( ) = = 0 )
2013-10-23 11:27:24 +08:00
{
2013-10-28 16:00:01 +08:00
setDirty ( listenerID , DirtyFlag : : SCENE_GRAPH_PRIORITY ) ;
2013-10-23 11:27:24 +08:00
}
else
{
2013-10-28 16:00:01 +08:00
setDirty ( listenerID , DirtyFlag : : FIXED_PRITORY ) ;
2013-10-23 11:27:24 +08:00
}
2013-09-20 22:23:13 +08:00
}
_toAddedListeners . clear ( ) ;
}
}
2013-10-23 11:27:24 +08:00
void EventDispatcher : : updateDirtyFlagForSceneGraph ( )
{
if ( ! _dirtyNodes . empty ( ) )
{
for ( auto & node : _dirtyNodes )
{
auto iter = _nodeListenersMap . find ( node ) ;
if ( iter ! = _nodeListenersMap . end ( ) )
{
for ( auto & l : * iter - > second )
{
2013-10-28 16:00:01 +08:00
setDirty ( l - > getListenerID ( ) , DirtyFlag : : SCENE_GRAPH_PRIORITY ) ;
2013-10-23 11:27:24 +08:00
}
}
}
_dirtyNodes . clear ( ) ;
}
}
2013-10-28 16:00:01 +08:00
void EventDispatcher : : sortEventListeners ( EventListener : : ListenerID listenerID )
2013-10-23 11:27:24 +08:00
{
2013-10-25 10:35:48 +08:00
DirtyFlag dirtyFlag = DirtyFlag : : NONE ;
2013-10-23 11:27:24 +08:00
2013-10-28 16:00:01 +08:00
auto dirtyIter = _priorityDirtyFlagMap . find ( listenerID ) ;
2013-10-25 10:35:48 +08:00
if ( dirtyIter ! = _priorityDirtyFlagMap . end ( ) )
{
dirtyFlag = dirtyIter - > second ;
}
if ( dirtyFlag ! = DirtyFlag : : NONE )
{
if ( ( int ) dirtyFlag & ( int ) DirtyFlag : : FIXED_PRITORY )
{
2013-10-28 16:00:01 +08:00
sortEventListenersOfFixedPriority ( listenerID ) ;
2013-10-25 10:35:48 +08:00
}
if ( ( int ) dirtyFlag & ( int ) DirtyFlag : : SCENE_GRAPH_PRIORITY )
{
2013-10-28 16:00:01 +08:00
sortEventListenersOfSceneGraphPriority ( listenerID ) ;
2013-10-25 10:35:48 +08:00
}
dirtyIter - > second = DirtyFlag : : NONE ;
}
}
2013-10-28 16:00:01 +08:00
void EventDispatcher : : sortEventListenersOfSceneGraphPriority ( EventListener : : ListenerID listenerID )
2013-10-25 10:35:48 +08:00
{
2013-10-28 16:00:01 +08:00
auto listeners = getListeners ( listenerID ) ;
2013-10-23 11:27:24 +08:00
if ( listeners = = nullptr )
return ;
Node * rootNode = ( Node * ) Director : : getInstance ( ) - > getRunningScene ( ) ;
2013-10-23 17:26:14 +08:00
// Reset priority index
2013-10-25 17:03:50 +08:00
_nodePriorityIndex = 0 ;
2013-10-23 17:26:14 +08:00
_nodePriorityMap . clear ( ) ;
2013-10-23 11:27:24 +08:00
visitTarget ( rootNode ) ;
// After sort: priority < 0, > 0
auto sceneGraphlisteners = listeners - > getSceneGraphPriorityListeners ( ) ;
std : : sort ( sceneGraphlisteners - > begin ( ) , sceneGraphlisteners - > end ( ) , [ this ] ( const EventListener * l1 , const EventListener * l2 ) {
2013-10-28 16:00:01 +08:00
return _nodePriorityMap [ l1 - > getSceneGraphPriority ( ) ] > _nodePriorityMap [ l2 - > getSceneGraphPriority ( ) ] ;
2013-10-23 11:27:24 +08:00
} ) ;
# if DUMP_LISTENER_ITEM_PRIORITY_INFO
log ( " ----------------------------------- " ) ;
for ( auto & l : * sceneGraphlisteners )
{
2013-10-23 17:26:14 +08:00
log ( " listener priority: node ([%s]%p), priority (%d) " , typeid ( * l - > _node ) . name ( ) , l - > _node , _nodePriorityMap [ l - > _node ] ) ;
2013-10-23 11:27:24 +08:00
}
# endif
}
2013-10-28 16:00:01 +08:00
void EventDispatcher : : sortEventListenersOfFixedPriority ( EventListener : : ListenerID listenerID )
2013-09-20 22:23:13 +08:00
{
2013-10-28 16:00:01 +08:00
auto listeners = getListeners ( listenerID ) ;
2013-09-20 22:23:13 +08:00
2013-10-23 11:27:24 +08:00
if ( listeners = = nullptr )
2013-09-20 22:23:13 +08:00
return ;
2013-10-23 11:27:24 +08:00
// After sort: priority < 0, > 0
auto fixedlisteners = listeners - > getFixedPriorityListeners ( ) ;
std : : sort ( fixedlisteners - > begin ( ) , fixedlisteners - > end ( ) , [ ] ( const EventListener * l1 , const EventListener * l2 ) {
2013-10-28 16:00:01 +08:00
return l1 - > getFixedPriority ( ) < l2 - > getFixedPriority ( ) ;
2013-09-20 22:23:13 +08:00
} ) ;
2013-10-23 11:27:24 +08:00
// FIXME: Should use binary search
2013-12-05 17:19:01 +08:00
int index = 0 ;
2013-10-23 11:27:24 +08:00
for ( auto & listener : * fixedlisteners )
{
2013-10-28 16:00:01 +08:00
if ( listener - > getFixedPriority ( ) > = 0 )
2013-10-23 11:27:24 +08:00
break ;
+ + index ;
}
listeners - > setGt0Index ( index ) ;
2013-09-20 22:23:13 +08:00
# if DUMP_LISTENER_ITEM_PRIORITY_INFO
log ( " ----------------------------------- " ) ;
2013-10-23 11:27:24 +08:00
for ( auto & l : * fixedlisteners )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
log ( " listener priority: node (%p), fixed (%d) " , l - > _node , l - > _fixedPriority ) ;
2013-09-20 22:23:13 +08:00
}
# endif
}
2013-10-28 16:00:01 +08:00
EventDispatcher : : EventListenerVector * EventDispatcher : : getListeners ( EventListener : : ListenerID listenerID )
2013-09-20 22:23:13 +08:00
{
2013-10-28 16:00:01 +08:00
auto iter = _listeners . find ( listenerID ) ;
2013-09-20 22:23:13 +08:00
if ( iter ! = _listeners . end ( ) )
{
return iter - > second ;
}
return nullptr ;
}
2013-10-29 14:57:16 +08:00
void EventDispatcher : : removeEventListenersForListenerID ( EventListener : : ListenerID listenerID )
2013-09-20 22:23:13 +08:00
{
2013-10-28 16:00:01 +08:00
auto listenerItemIter = _listeners . find ( listenerID ) ;
2013-09-20 22:23:13 +08:00
if ( listenerItemIter ! = _listeners . end ( ) )
{
2013-10-23 11:27:24 +08:00
auto listeners = listenerItemIter - > second ;
auto fixedPriorityListeners = listeners - > getFixedPriorityListeners ( ) ;
auto sceneGraphPriorityListeners = listeners - > getSceneGraphPriorityListeners ( ) ;
auto removeAllListenersInVector = [ & ] ( std : : vector < EventListener * > * listenerVector ) {
if ( listenerVector = = nullptr )
return ;
2013-09-20 22:23:13 +08:00
2013-10-23 11:27:24 +08:00
for ( auto iter = listenerVector - > begin ( ) ; iter ! = listenerVector - > end ( ) ; )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
auto l = * iter ;
2013-10-28 16:00:01 +08:00
l - > setRegistered ( false ) ;
if ( l - > getSceneGraphPriority ( ) ! = nullptr )
2013-10-23 11:27:24 +08:00
{
2013-10-28 16:00:01 +08:00
dissociateNodeAndEventListener ( l - > getSceneGraphPriority ( ) , l ) ;
2013-10-23 11:27:24 +08:00
}
if ( _inDispatch = = 0 )
{
iter = listenerVector - > erase ( iter ) ;
2013-10-25 10:35:48 +08:00
CC_SAFE_RELEASE ( l ) ;
2013-10-23 11:27:24 +08:00
}
else
{
+ + iter ;
}
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
} ;
removeAllListenersInVector ( sceneGraphPriorityListeners ) ;
removeAllListenersInVector ( fixedPriorityListeners ) ;
2013-09-20 22:23:13 +08:00
if ( ! _inDispatch )
{
2013-10-23 11:27:24 +08:00
listeners - > clear ( ) ;
delete listeners ;
2013-09-20 22:23:13 +08:00
_listeners . erase ( listenerItemIter ) ;
2013-10-28 16:00:01 +08:00
_priorityDirtyFlagMap . erase ( listenerID ) ;
2013-09-20 22:23:13 +08:00
}
}
2013-11-02 22:08:08 +08:00
for ( auto iter = _toAddedListeners . begin ( ) ; iter ! = _toAddedListeners . end ( ) ; )
{
if ( ( * iter ) - > getListenerID ( ) = = listenerID )
{
iter = _toAddedListeners . erase ( iter ) ;
}
else
{
+ + iter ;
}
}
2013-09-20 22:23:13 +08:00
}
2013-10-29 14:57:16 +08:00
void EventDispatcher : : removeEventListeners ( EventListener : : Type listenerType )
{
CCASSERT ( listenerType ! = EventListener : : Type : : CUSTOM , " Not support custom event listener type, please use EventDispatcher::removeCustomEventListeners instead. " ) ;
removeEventListenersForListenerID ( static_cast < EventListener : : ListenerID > ( listenerType ) ) ;
}
void EventDispatcher : : removeCustomEventListeners ( const std : : string & customEventName )
{
removeEventListenersForListenerID ( std : : hash < std : : string > ( ) ( customEventName ) ) ;
}
2013-10-25 16:34:26 +08:00
void EventDispatcher : : removeAllEventListeners ( )
2013-09-20 22:23:13 +08:00
{
2013-12-06 16:32:06 +08:00
std : : vector < EventListener : : ListenerID > types ( _listeners . size ( ) ) ;
2013-10-23 11:27:24 +08:00
for ( auto iter = _listeners . begin ( ) ; iter ! = _listeners . end ( ) ; + + iter )
2013-09-20 22:23:13 +08:00
{
2013-10-23 11:27:24 +08:00
types . push_back ( iter - > first ) ;
2013-09-20 22:23:13 +08:00
}
2013-10-23 11:27:24 +08:00
for ( auto & type : types )
{
2013-10-29 14:57:16 +08:00
removeEventListenersForListenerID ( type ) ;
2013-10-23 11:27:24 +08:00
}
2013-09-20 22:23:13 +08:00
if ( ! _inDispatch )
{
_listeners . clear ( ) ;
}
}
void EventDispatcher : : setEnabled ( bool isEnabled )
{
_isEnabled = isEnabled ;
}
bool EventDispatcher : : isEnabled ( ) const
{
return _isEnabled ;
}
2013-10-23 11:27:24 +08:00
void EventDispatcher : : setDirtyForNode ( Node * node )
{
2013-10-24 17:27:22 +08:00
// Mark the node dirty only when there was an eventlistener associates with it.
if ( _nodeListenersMap . find ( node ) ! = _nodeListenersMap . end ( ) )
{
_dirtyNodes . insert ( node ) ;
}
2013-10-23 11:27:24 +08:00
}
2013-10-28 16:00:01 +08:00
void EventDispatcher : : setDirty ( EventListener : : ListenerID listenerID , DirtyFlag flag )
2013-10-25 10:35:48 +08:00
{
2013-10-28 16:00:01 +08:00
auto iter = _priorityDirtyFlagMap . find ( listenerID ) ;
2013-09-20 22:23:13 +08:00
if ( iter = = _priorityDirtyFlagMap . end ( ) )
{
2013-10-28 16:00:01 +08:00
_priorityDirtyFlagMap . insert ( std : : make_pair ( listenerID , flag ) ) ;
2013-09-20 22:23:13 +08:00
}
else
{
2013-10-23 11:27:24 +08:00
int ret = ( int ) flag | ( int ) iter - > second ;
iter - > second = ( DirtyFlag ) ret ;
2013-09-20 22:23:13 +08:00
}
}
NS_CC_END