http://blog.csdn.net/u012085988/article/details/16881387
- <prename="code"class="cpp"></pre><prename="code"class="cpp"><prename="code"class="cpp">.h
- #ifndef__CC_EVENT_DISPATCHER_H__
- #define__CC_EVENT_DISPATCHER_H__
- #include"CCPlatformMacros.h"
- #include"CCEventListener.h"
- #include"CCEvent.h"
- #include<functional>
- #include<string>
- #include<unordered_map>
- #include<list>
- #include<vector>
- NS_CC_BEGIN
- classEvent;
- classEventTouch;
- classNode;
- /**
- 管理eventlistener服务以及事件分发(eventdispatching).
- TheEventListenerlistismanagedinsuchawaythat
- eventlistenerscanbeaddedandremovedeven
- fromwithinanEventListener,whileeventsarebeing
- dispatched.
- */
- classEventDispatcher:publicObject
- {
- public:
- /**注册监听事件(优先级基于Node绘制顺序)
- *在消息路由时,先处理优先级<0的,在处理优先级=0(按Node绘制顺序),最后处理优先级>0的
- *@paramlistener监听器
- *@paramnode监听的node
- *@notefixedProprity必须是0
- */
- voidaddEventListenerWithSceneGraPHPriority(EventListener*listener,Node*node);
- /**注册监听事件(指定优先级)
- *@paramlistenerThelistenerofaspecifiedevent.
- *@paramfixedPriorityThefixedpriorityofthelistener.
- *@noteAlowerprioritywillbecalledbeforetheonesthathaveahighervalue.
- *0priorityisforbiddenforfixedprioritysinceit'susedforscenegraphbasedpriority.
- voidaddEventListenerWithFixedPriority(EventListener*listener,intfixedPriority);
- /**删除某一个监听器
- *@paramlistenerThespecifiedeventlistenerwhichneedstoberemoved.
- voidremoveEventListener(EventListener*listener);
- /**删除某一类监听器*/
- voidremoveEventListeners(EventListener::TypelistenerType);
- /**Removesallcustomlistenerswiththesameeventname*/
- voidremoveCustomEventListeners(conststd::string&customEventName);
- /**删除所有监听器*/
- voidremoveAllEventListeners();
- /**修改某监听器的优先级*/
- voidsetPriority(EventListener*listener,87); background-color:inherit; font-weight:bold">intfixedPriority);
- /**设置事件分发器是否可用*/
- voidsetEnabled(boolisEnabled);
- /**Checkswhetherdispatchingeventsisenabled*/
- boolisEnabled()const;
- /**分发事件
- *同时从dispatcherlist中删除标记为deletion的监听器
- voiddispatchEvent(Event*event);
- /**ConstructorofEventDispatcher*/
- EventDispatcher();
- /**DestructorofEventDispatcher*/
- ~EventDispatcher();
- private:
- friendclassNode;
- /**将Node记为Dirty
- 即将Node加入_dirtyNodes*/
- voidsetDirtyForNode(Node*node);
- /**跟node相关联的所有listener都暂停*/
- voidpauseTarget(Node*node);
- /**跟node相关联的所有listener都唤醒*/
- voidresuMetarget(Node*node);
- /**删除所有跟node相关联的listener*/
- voidcleanTarget(Node*node);
- *Thevectortostoreeventlistenerswithscenegraphbasedpriorityandfixedpriority.
- classEventListenerVector
- {
- public:
- EventListenerVector();
- ~EventListenerVector();
- size_tsize() boolempty()const;
- voidpush_back(EventListener*item);
- voidclearSceneGraphListeners();
- voidclearFixedListeners();
- voidclear();
- inlinestd::vector<EventListener*>*getFixedPriorityListeners()const{return_fixedListeners;};
- inlinestd::vector<EventListener*>*getSceneGraPHPriorityListeners()return_sceneGraphListeners;};
- inlinelonggetGt0Index()return_gt0Index;};
- inlinevoidsetGt0Index(longindex){_gt0Index=index;};
- std::vector<EventListener*>*_fixedListeners;
- std::vector<EventListener*>*_sceneGraphListeners;
- long_gt0Index;
- };
- /**Addseventlistenerwithitem*/
- voidaddEventListener(EventListener*listener);
- /**Getseventthelistenerlistfortheeventlistenertype.*/
- EventListenerVector*getListeners(EventListener::ListenerIDlistenerID);
- /**Updatedirtyflag*/
- voidupdateDirtyFlagForSceneGraph();
- /**RemovesalllistenerswiththesameeventlistenerID*/
- voidremoveEventListenersForListenerID(EventListener::ListenerIDlistenerID);
- /**排序*/
- voidsortEventListeners(EventListener::ListenerIDlistenerID);
- /**根据node优先级排序*/
- voidsortEventListenersOfSceneGraPHPriority(EventListener::ListenerIDlistenerID);
- /**根据优先级排序*/
- voidsortEventListenersOfFixedPriority(EventListener::ListenerIDlistenerID);
- /**Updatesalllisteners
- *1)删除所有标记为deleted的监听器.
- *2)添加_toAddedListeners中的监听器.
- voidupdateListeners(Event*event);
- /**ToucheventneedstobeprocesseddifferentwithothereventssinceitneedssupportALL_AT_ONCEandONE_BY_NONEmode.*/
- voiddispatchTouchEvent(EventTouch*event);
- /**Associatesnodewitheventlistener*/
- voidassociateNodeAndEventListener(Node*node,EventListener*listener);
- /**Dissociatesnodewitheventlistener*/
- voiddissociateNodeAndEventListener(Node*node,EventListener*listener);
- /**Dispatcheseventtolistenerswithaspecifiedlistenertype*/
- voiddispatchEventToListeners(EventListenerVector*listeners,std::function<bool(EventListener*)>onEvent);
- ///Prioritydirtyflag
- enumclassDirtyFlag
- NONE=0,
- FIXED_PRITORY=1<<0,
- SCENE_GRAPH_PRIORITY=1<<1,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> ALL=FIXED_PRITORY|SCENE_GRAPH_PRIORITY
- /**SetsthedirtyflagforaspecifiedlistenerID*/
- voidsetDirty(EventListener::ListenerIDlistenerID,DirtyFlagflag);
- /**遍历场景,获取每个Node的绘制顺序;
- 此函数在sortEventListenersOfSceneGraPHPriority之前调用*/
- voidvisitTarget(Node*node);
- private:
- /**map存储所有监听器map::key监听器类型*/
- std::unordered_map<EventListener::ListenerID,EventListenerVector*>_listeners;
- /**map存储一类监听器是否被污染。
- 即:按优先级分类,可以把所有监听器分为两类(Node,fixdpriority)。
- 如果_listenner[type]里的监听器全是Nodepriority,则DirtyFlag为SCENE_GRAPH_PRIORITY;
- 若全为fixdpriority则为FIXED_PRITORY;若两种都有,则为ALL=FIXED_PRITORY|SCENE_GRAPH_PRIORITY*/
- /**map关联Node与监听器*/
- std::unordered_map<Node*,std::vector<EventListener*>*>_nodeListenersMap;
- /**存储每个Node的优先级(即绘制顺序);
- 在visitTarge中更新该值,
- 在sortEventListenersOfSceneGraPHPriority中使用该值*/
- std::unordered_map<Node*,int>_nodePriorityMap;
- /**如果注册监听器时正在dispathchevent,则将该监听器加到_toAddedListeners中,
- 等dispatch完成后,在将其从_toAddedListeners中移到其他容器,*/
- std::vector<EventListener*>_toAddedListeners;
- /**优先级发生改变的Node
- 此集合中的Node所对应的Listener所在的那个vector(_listeners[ID])将会重排序*/
- std::set<Node*>_dirtyNodes;
- /**判断是否正在dispatch*/
- int_inDispatch;
- /**Whethertoenabledispatchingevent*/
- bool_isEnabled;
- int_nodePriorityIndex;
- NS_CC_END
- #endif//__CC_EVENT_DISPATCHER_H__
- cpp
- #include"CCEventDispatcher.h"
- #include"CCEventTouch.h"
- #include"CCEventCustom.h"
- #include"CCEventListenerTouch.h"
- #include"CCNode.h"
- #include"CCDirector.h"
- #include<algorithm>
- #defineDUMP_LISTENER_ITEM_PRIORITY_INFO0
- namespace
- /************************************************************************/
- /*用于自动处理count。一般用于构造一个局部变量。与指针计数器原理相同。
- 构造时+1,
- 析构时-1.
- 若函数中有多处return,而每次renturn前都要处理某变量的值,则可以采用此机制优化代码;
- 此机制只需利用变量a构造一个局部变量,无需在每次返回前再处理变量a。
- classDispatchGuard
- DispatchGuard(int&count):
- _count(count)
- ++_count;
- }
- ~DispatchGuard()
- --_count;
- }
- int&_count;
- //根据Event的type确定EventListener的Type
- //关于EventListener的ListenerId与EventListener的Type(注意这里不是Event::Type)映射关系
- //出自定制类型外,其他类型都是用枚举一一映射的,而自定制类型则是计算hash值
- staticEventListener::ListenerIDgetListenerID(Event*event)
- EventListener::ListenerIDret;
- switch(event->getType())
- caseEvent::Type::ACCELERATION:
- ret=static_cast<EventListener::ListenerID>(EventListener::Type::ACCELERATION);
- break;
- caseEvent::Type::CUSTOM:
- autocustomEvent=static_cast<EventCustom*>(event);
- autolistenerID=std::hash<std::string>()(customEvent->getEventName());
- static_cast<EventListener::ListenerID>(listenerID);
- break;
- caseEvent::Type::KEYBOARD:
- static_cast<EventListener::ListenerID>(EventListener::Type::KEYBOARD);
- caseEvent::Type::MOUSE:
- ret=static_cast<EventListener::ListenerID>(EventListener::Type::MOUSE);
- caseEvent::Type::TOUCH:
- //Touchlistenerisveryspecial,itcontainstwokindsoflisteners,EventListenerTouchOneByOneandEventListenerTouchAllAtOnce.
- //returnUNKNOWinstead.
- static_cast<EventListener::ListenerID>(EventListener::Type::UNKNOWN);
- default:
- CCASSERT(false,"Invalidtype!");
- returnret;
- EventDispatcher::EventListenerVector::EventListenerVector()
- :_sceneGraphListeners(nullptr)
- ,_fixedListeners(nullptr)
- ,_gt0Index(0)
- EventDispatcher::EventListenerVector::~EventListenerVector()
- CC_SAFE_DELETE(_sceneGraphListeners);
- CC_SAFE_DELETE(_fixedListeners);
- size_tEventDispatcher::EventListenerVector::size()const
- size_tret=0;
- if(_sceneGraphListeners)
- ret+=_sceneGraphListeners->size();
- if(_fixedListeners)
- ret+=_fixedListeners->size();
- boolEventDispatcher::EventListenerVector::empty()const
- return(_sceneGraphListeners==nullptr||_sceneGraphListeners->empty())
- &&(_fixedListeners==nullptr||_fixedListeners->empty());
- voidEventDispatcher::EventListenerVector::push_back(EventListener*listener)
- if(listener->getFixedPriority()==0)
- if(_sceneGraphListeners==nullptr)
- _sceneGraphListeners=newstd::vector<EventListener*>();
- _sceneGraphListeners->reserve(100);
- _sceneGraphListeners->push_back(listener);
- else
- if(_fixedListeners==nullptr)
- _fixedListeners= _fixedListeners->reserve(100);
- _fixedListeners->push_back(listener);
- voidEventDispatcher::EventListenerVector::clearSceneGraphListeners()
- _sceneGraphListeners->clear();
- delete_sceneGraphListeners;
- _sceneGraphListeners=nullptr;
- voidEventDispatcher::EventListenerVector::clearFixedListeners()
- _fixedListeners->clear();
- delete_fixedListeners;
- _fixedListeners=nullptr;
- voidEventDispatcher::EventListenerVector::clear()
- clearSceneGraphListeners();
- clearFixedListeners();
- EventDispatcher::EventDispatcher()
- :_inDispatch(0)
- true)
- _toAddedListeners.reserve(50);
- EventDispatcher::~EventDispatcher()
- removeAllEventListeners();
- voidEventDispatcher::visitTarget(Node*node)
- inti=0;
- Array*children=node->getChildren();
- intchildrenCount=children?children->count():0;
- if(childrenCount>0)
- Node*child=nullptr;
- //只计算子节点中zOrder<0的
- for(;i<childrenCount;i++)
- child=static_cast<Node*>(children->getObjectAtIndex(i));
- if(child&&child->getZOrder()<0)
- visitTarget(child);
- else
- //记录Node的优先级
- _nodePriorityMap.insert(std::make_pair(node,++_nodePriorityIndex));
- for(;i<childrenCount;i++)
- child=static_cast<Node*>(children->getObjectAtIndex(i));
- if(child)
- _nodePriorityMap.insert(std::make_pair(node,++_nodePriorityIndex));
- voidEventDispatcher::pauseTarget(Node*node)
- autolistenerIter=_nodeListenersMap.find(node);
- if(listenerIter!=_nodeListenersMap.end())
- autolisteners=listenerIter->second;
- for(auto&l:*listeners)
- l->setPaused(true);
- voidEventDispatcher::resuMetarget(Node*node)
- autolistenerIter=_nodeListenersMap.find(node);
- if(listenerIter!=_nodeListenersMap.end())
- autolisteners=listenerIter->second;
- for(auto&l:*listeners)
- l->setPaused(false);
- setDirtyForNode(node);
- voidEventDispatcher::cleanTarget(Node*node)
- autolistenersCopy=*listeners;
- for(auto&l:listenersCopy)
- removeEventListener(l);
- voidEventDispatcher::associateNodeAndEventListener(Node*node,EventListener*listener)
- std::vector<EventListener*>*listeners=nullptr;
- autofound=_nodeListenersMap.find(node);
- if(found!=_nodeListenersMap.end())
- listeners=found->second;
- listeners= listeners->push_back(listener);
- _nodeListenersMap.insert(std::make_pair(node,listeners));
- voidEventDispatcher::dissociateNodeAndEventListener(Node*node,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> autoiter=std::find(listeners->begin(),listeners->end(),listener);
- if(iter!=listeners->end())
- listeners->erase(iter);
- if(listeners->empty())
- _nodeListenersMap.erase(found);
- deletelisteners;
- voidEventDispatcher::addEventListener(EventListener*listener)
- //如果不是正在路由事件
- if(_inDispatch==0)
- EventListenerVector*listenerList=nullptr;
- //根据listenerID获取相应vector
- autoiter=_listeners.find(listener->getListenerID());
- if(iter==_listeners.end())
- listenerList=newEventListenerVector();
- _listeners.insert(std::make_pair(listener->getListenerID(),listenerList));
- listenerList=iter->second;
- listenerList->push_back(listener);
- if(listener->getFixedPriority()==0)
- //如果优先级根据Node而定
- setDirty(listener->getListenerID(),DirtyFlag::SCENE_GRAPH_PRIORITY);
- //如果优先级根据Fixed而定
- setDirty(listener->getListenerID(),DirtyFlag::FIXED_PRITORY);
- //如果正在路由事件,则直接加入_toAddedListeners
- _toAddedListeners.push_back(listener);
- voidEventDispatcher::addEventListenerWithSceneGraPHPriority(EventListener*listener,Node*node)
- CCASSERT(listener&&node,"Invalidparameters.");
- CCASSERT(!listener->isRegistered(),"Thelistenerhasbeenregistered.");
- if(!listener->checkAvailable())
- return;
- listener->setSceneGraPHPriority(node);
- listener->setFixedPriority(0);
- listener->setRegistered( listener->retain();
- //存储listener,
- addEventListener(listener);
- //关联node与listener
- associateNodeAndEventListener(node,listener);
- if(node->isRunning())
- resuMetarget(node);
- voidEventDispatcher::addEventListenerWithFixedPriority(EventListener*listener,87); background-color:inherit; font-weight:bold">intfixedPriority)
- CCASSERT(listener,"Invalidparameters.");
- CCASSERT(!listener->isRegistered(),"Thelistenerhasbeenregistered.");
- CCASSERT(fixedPriority!=0,"0priorityisforbiddenforfixedprioritysinceit'susedforscenegraphbasedpriority.");
- listener->setSceneGraPHPriority(nullptr);
- listener->setFixedPriority(fixedPriority);
- listener->setPaused( listener->retain();
- addEventListener(listener);
- voidEventDispatcher::removeEventListener(EventListener*listener)
- if(listener==nullptr)
- return;
- boolisFound=false;
- autoremoveListenerInVector=[&](std::vector<EventListener*>*listeners){
- if(listeners==nullptr)
- for(autoiter=listeners->begin();iter!=listeners->end();++iter)
- autol=*iter;
- if(l==listener)
- CC_SAFE_RETAIN(l);
- l->setRegistered(if(l->getSceneGraPHPriority()!=nullptr)
- //撤销node与listener的关联
- dissociateNodeAndEventListener(l->getSceneGraPHPriority(),l);
- if(_inDispatch==0)
- listeners->erase(iter);
- CC_SAFE_RELEASE(l);
- isFound=true;
- for(autoiter=_listeners.begin();iter!=_listeners.end();)
- autolisteners=iter->second;
- autofixedPriorityListeners=listeners->getFixedPriorityListeners();
- autosceneGraPHPriorityListeners=listeners->getSceneGraPHPriorityListeners();
- removeListenerInVector(sceneGraPHPriorityListeners);
- if(!isFound)
- removeListenerInVector(fixedPriorityListeners);
- if(iter->second->empty())
- _priorityDirtyFlagMap.erase(listener->getListenerID());
- autolist=iter->second;
- iter=_listeners.erase(iter);
- CC_SAFE_DELETE(list);
- ++iter;
- if(isFound)
- CC_SAFE_RELEASE(listener);
- //若没有找到,则在_toAddedListeners中找
- for(autoiter=_toAddedListeners.begin();iter!=_toAddedListeners.end();++iter)
- if(*iter==listener)
- _toAddedListeners.erase(iter);
- voidEventDispatcher::setPriority(EventListener*listener,87); background-color:inherit; font-weight:bold">intfixedPriority)
- for(autoiter=_listeners.begin();iter!=_listeners.end();++iter)
- autofixedPriorityListeners=iter->second->getFixedPriorityListeners();
- if(fixedPriorityListeners)
- autofound=std::find(fixedPriorityListeners->begin(),fixedPriorityListeners->end(),153); background-color:inherit; font-weight:bold">if(found!=fixedPriorityListeners->end())
- CCASSERT(listener->getSceneGraPHPriority()==nullptr,"Can'tsetfixedprioritywithscenegraphbasedlistener.");
- if(listener->getFixedPriority()!=fixedPriority)
- voidEventDispatcher::dispatchEventToListeners(EventListenerVector*listeners,87); background-color:inherit; font-weight:bold">bool(EventListener*)>onEvent)
- boolshouldStopPropagation=false;
- longi=0;
- //priority<0
- for(;!fixedPriorityListeners->empty()&&i<listeners->getGt0Index();++i)
- autol=fixedPriorityListeners->at(i);
- if(!l->isPaused()&&l->isRegistered()&&onEvent(l))
- shouldStopPropagation=true;
- if(sceneGraPHPriorityListeners)
- if(!shouldStopPropagation)
- //priority==0,scenegraPHPriority
- for(auto&l:*sceneGraPHPriorityListeners)
- if(!l->isPaused()&&l->isRegistered()&&onEvent(l))
- shouldStopPropagation=if(fixedPriorityListeners)
- //priority>0
- for(;i<static_cast<long>(fixedPriorityListeners->size());++i)
- if(!l->isPaused()&&l->isRegistered()&&onEvent(fixedPriorityListeners->at(i)))
- voidEventDispatcher::dispatchEvent(Event*event)
- if(!_isEnabled)
- updateDirtyFlagForSceneGraph();
- DispatchGuardguard(_inDispatch);
- if(event->getType()==Event::Type::TOUCH)
- dispatchTouchEvent(static_cast<EventTouch*>(event));
- autolistenerID=getListenerID(event);
- sortEventListeners(listenerID);
- autoiter=_listeners.find(listenerID);
- if(iter!=_listeners.end())
- autolisteners=iter->second;
- autoonEvent=[&event](EventListener*listener)->bool{
- event->setCurrentTarget(listener->getSceneGraPHPriority());
- listener->_onEvent(event);
- returnevent->isStopped();
- };
- dispatchEventToListeners(listeners,onEvent);
- updateListeners(event);
- voidEventDispatcher::dispatchTouchEvent(EventTouch*event)
- autotouchOneByOneID=static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ONE_BY_ONE);
- autotouchAllAtOnceID=static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ALL_AT_ONCE);
- sortEventListeners(touchOneByOneID);
- sortEventListeners(touchAllAtOnceID);
- autooneByOnelisteners=getListeners(touchOneByOneID);
- autoallAtOncelisteners=getListeners(touchAllAtOnceID);
- //Iftherearen'tanytouchlisteners,returndirectly.
- if(nullptr==oneByOnelisteners&&nullptr==allAtOncelisteners)
- boolisNeedsMutableSet=(oneByOnelisteners&&allAtOncelisteners);
- std::vector<Touch*>orignalTouches=event->getTouches();
- std::vector<Touch*>mutableTouches(orignalTouches.size());
- std::copy(orignalTouches.begin(),orignalTouches.end(),mutableTouches.begin());
- //
- //processthetargethandlers1st
- if(oneByOnelisteners)
- automutableTouchesIter=mutableTouches.begin();
- autotouchesIter=orignalTouches.begin();
- for(;touchesIter!=orignalTouches.end();++touchesIter)
- boolisSwallowed= autoonTouchEvent=[&](EventListener*l)->bool{//Returntruetobreak
- EventListenerTouchOneByOne*listener=static_cast<EventListenerTouchOneByOne*>(l);
- //Skipifthelistenerwasremoved.
- if(!listener->_isRegistered)
- return event->setCurrentTarget(listener->_node);
- boolisClaimed= std::vector<Touch*>::iteratorremovedIter;
- EventTouch::EventCodeeventCode=event->getEventCode();
- if(eventCode==EventTouch::EventCode::BEGAN)
- if(listener->onTouchBegan)
- isClaimed=listener->onTouchBegan(*touchesIter,event);
- if(isClaimed&&listener->_isRegistered)
- listener->_claimedTouches.push_back(*touchesIter);
- elseif(listener->_claimedTouches.size()>0
- &&((removedIter=std::find(listener->_claimedTouches.begin(),listener->_claimedTouches.end(),*touchesIter))!=listener->_claimedTouches.end()))
- isClaimed=switch(eventCode)
- caseEventTouch::EventCode::MOVED:
- if(listener->onTouchMoved)
- listener->onTouchMoved(*touchesIter,event);
- caseEventTouch::EventCode::ENDED:
- if(listener->onTouchEnded)
- listener->onTouchEnded(*touchesIter,153); background-color:inherit; font-weight:bold">if(listener->_isRegistered)
- listener->_claimedTouches.erase(removedIter);
- caseEventTouch::EventCode::CANCELLED:
- if(listener->onTouchCancelled)
- listener->onTouchCancelled(*touchesIter,153); background-color:inherit; font-weight:bold">default:
- CCASSERT("Theeventcodeisinvalid.");
- //Iftheeventwasstopped,153); background-color:inherit; font-weight:bold">if(event->isStopped())
- updateListeners(event);
- CCASSERT((*touchesIter)->getID()==(*mutableTouchesIter)->getID(),"");
- if(isClaimed&&listener->_isRegistered&&listener->_needSwallow)
- if(isNeedsMutableSet)
- mutableTouchesIter=mutableTouches.erase(mutableTouchesIter);
- isSwallowed= dispatchEventToListeners(oneByOnelisteners,onTouchEvent);
- if(event->isStopped())
- if(!isSwallowed)
- ++mutableTouchesIter;
- //processstandardhandlers2nd
- if(allAtOncelisteners&&mutableTouches.size()>0)
- autoonTouchesEvent=[&](EventListener*l)->bool{
- EventListenerTouchAllAtOnce*listener=static_cast<EventListenerTouchAllAtOnce*>(l);
- //Skipifthelistenerwasremoved.
- if(!listener->_isRegistered)
- event->setCurrentTarget(listener->_node);
- switch(event->getEventCode())
- caseEventTouch::EventCode::BEGAN:
- if(listener->onTouchesBegan)
- listener->onTouchesBegan(mutableTouches,153); background-color:inherit; font-weight:bold">if(listener->onTouchesMoved)
- listener->onTouchesMoved(mutableTouches,153); background-color:inherit; font-weight:bold">if(listener->onTouchesEnded)
- listener->onTouchesEnded(mutableTouches,153); background-color:inherit; font-weight:bold">if(listener->onTouchesCancelled)
- listener->onTouchesCancelled(mutableTouches,returndirectly.
- dispatchEventToListeners(allAtOncelisteners,onTouchesEvent);
- voidEventDispatcher::updateListeners(Event*event)
- autoonUpdateListeners=[this](EventListener::ListenerIDlistenerID)
- autolistenersIter=_listeners.find(listenerID);
- if(listenersIter==_listeners.end())
- autolisteners=listenersIter->second;
- autofixedPriorityListeners=listeners->getFixedPriorityListeners();
- autosceneGraPHPriorityListeners=listeners->getSceneGraPHPriorityListeners();
- for(autoiter=sceneGraPHPriorityListeners->begin();iter!=sceneGraPHPriorityListeners->end();)
- if(!l->isRegistered())
- iter=sceneGraPHPriorityListeners->erase(iter);
- l->release();
- for(autoiter=fixedPriorityListeners->begin();iter!=fixedPriorityListeners->end();)
- autol=*iter;
- if(!l->isRegistered())
- iter=fixedPriorityListeners->erase(iter);
- l->release();
- ++iter;
- if(sceneGraPHPriorityListeners&&sceneGraPHPriorityListeners->empty())
- listeners->clearSceneGraphListeners();
- if(fixedPriorityListeners&&fixedPriorityListeners->empty())
- listeners->clearFixedListeners();
- if(listenersIter->second->empty())
- _priorityDirtyFlagMap.erase(listenersIter->first);
- deletelistenersIter->second;
- listenersIter=_listeners.erase(listenersIter);
- ++listenersIter;
- if(event->getType()==Event::Type::TOUCH)
- onUpdateListeners(static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ONE_BY_ONE));
- onUpdateListeners(static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ALL_AT_ONCE));
- onUpdateListeners(getListenerID(event));
- if(!_toAddedListeners.empty())
- EventListenerVector*listeners=nullptr;
- for(auto&listener:_toAddedListeners)
- EventListener::ListenerIDlistenerID=listener->getListenerID();
- autoitr=_listeners.find(listenerID);
- if(itr==_listeners.end())
- newEventListenerVector();
- _listeners.insert(std::make_pair(listenerID,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> listeners=itr->second;
- listeners->push_back(listener);
- setDirty(listenerID,DirtyFlag::FIXED_PRITORY);
- _toAddedListeners.clear();
- voidEventDispatcher::updateDirtyFlagForSceneGraph()
- if(!_dirtyNodes.empty())
- for(auto&node:_dirtyNodes)
- autoiter=_nodeListenersMap.find(node);
- if(iter!=_nodeListenersMap.end())
- for(auto&l:*iter->second)
- setDirty(l->getListenerID(),108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> _dirtyNodes.clear();
- voidEventDispatcher::sortEventListeners(EventListener::ListenerIDlistenerID)
- DirtyFlagdirtyFlag=DirtyFlag::NONE;
- autodirtyIter=_priorityDirtyFlagMap.find(listenerID);
- if(dirtyIter!=_priorityDirtyFlagMap.end())
- dirtyFlag=dirtyIter->second;
- if(dirtyFlag!=DirtyFlag::NONE)
- if((int)dirtyFlag&(int)DirtyFlag::FIXED_PRITORY)
- sortEventListenersOfFixedPriority(listenerID);
- int)DirtyFlag::SCENE_GRAPH_PRIORITY)
- sortEventListenersOfSceneGraPHPriority(listenerID);
- dirtyIter->second=DirtyFlag::NONE;
- voidEventDispatcher::sortEventListenersOfSceneGraPHPriority(EventListener::ListenerIDlistenerID)
- autolisteners=getListeners(listenerID);
- Node*rootNode=(Node*)Director::getInstance()->getRunningScene();
- //Resetpriorityindex
- _nodePriorityIndex=0;
- _nodePriorityMap.clear();
- visitTarget(rootNode);
- //Aftersort:priority<0,>0
- autosceneGraphlisteners=listeners->getSceneGraPHPriorityListeners();
- std::sort(sceneGraphlisteners->begin(),sceneGraphlisteners->end(),[this](constEventListener*l1,constEventListener*l2){
- return_nodePriorityMap[l1->getSceneGraPHPriority()]>_nodePriorityMap[l2->getSceneGraPHPriority()];
- });
- #ifDUMP_LISTENER_ITEM_PRIORITY_INFO
- log("-----------------------------------");
- for(auto&l:*sceneGraphlisteners)
- log("listenerpriority:node([%s]%p),priority(%d)",153); background-color:inherit; font-weight:bold">typeid(*l->_node).name(),l->_node,_nodePriorityMap[l->_node]);
- #endif
- voidEventDispatcher::sortEventListenersOfFixedPriority(EventListener::ListenerIDlistenerID)
- autolisteners=getListeners(listenerID);
- if(listeners==nullptr)
- autofixedlisteners=listeners->getFixedPriorityListeners();
- std::sort(fixedlisteners->begin(),fixedlisteners->end(),[](returnl1->getFixedPriority()<l2->getFixedPriority();
- //FIXME:Shouldusebinarysearch
- longindex=0;
- for(auto&listener:*fixedlisteners)
- if(listener->getFixedPriority()>=0)
- ++index;
- listeners->setGt0Index(index);
- #ifDUMP_LISTENER_ITEM_PRIORITY_INFO
- log("-----------------------------------");
- for(auto&l:*fixedlisteners)
- log("listenerpriority:node(%p),fixed(%d)",l->_fixedPriority);
- #endif
- EventDispatcher::EventListenerVector*EventDispatcher::getListeners(EventListener::ListenerIDlistenerID)
- autoiter=_listeners.find(listenerID);
- if(iter!=_listeners.end())
- returniter->second;
- returnnullptr;
- voidEventDispatcher::removeEventListenersForListenerID(EventListener::ListenerIDlistenerID)
- autolistenerItemIter=_listeners.find(listenerID);
- if(listenerItemIter!=_listeners.end())
- autolisteners=listenerItemIter->second;
- autoremoveAllListenersInVector=[&](std::vector<EventListener*>*listenerVector){
- if(listenerVector==nullptr)
- for(autoiter=listenerVector->begin();iter!=listenerVector->end();)
- l->setRegistered(false);
- if(l->getSceneGraPHPriority()!=nullptr)
- iter=listenerVector->erase(iter);
- removeAllListenersInVector(sceneGraPHPriorityListeners);
- removeAllListenersInVector(fixedPriorityListeners);
- if(!_inDispatch)
- listeners->clear();
- deletelisteners;
- _listeners.erase(listenerItemIter);
- _priorityDirtyFlagMap.erase(listenerID);
- for(autoiter=_toAddedListeners.begin();iter!=_toAddedListeners.end();)
- if((*iter)->getListenerID()==listenerID)
- iter=_toAddedListeners.erase(iter);
- voidEventDispatcher::removeEventListeners(EventListener::TypelistenerType)
- CCASSERT(listenerType!=EventListener::Type::CUSTOM,"Notsupportcustomeventlistenertype,pleaseuseEventDispatcher::removeCustomEventListenersinstead.");
- removeEventListenersForListenerID(static_cast<EventListener::ListenerID>(listenerType));
- voidEventDispatcher::removeCustomEventListeners(conststd::string&customEventName)
- removeEventListenersForListenerID(std::hash<std::string>()(customEventName));
- voidEventDispatcher::removeAllEventListeners()
- std::vector<int>types(_listeners.size());
- types.push_back(iter->first);
- for(auto&type:types)
- removeEventListenersForListenerID(type);
- _listeners.clear();
- voidEventDispatcher::setEnabled(boolisEnabled)
- _isEnabled=isEnabled;
- boolEventDispatcher::isEnabled()return_isEnabled;
- voidEventDispatcher::setDirtyForNode(Node*node)
- //Markthenodedirtyonlywhentherewasaneventlistenerassociateswithit.
- if(_nodeListenersMap.find(node)!=_nodeListenersMap.end())
- _dirtyNodes.insert(node);
- voidEventDispatcher::setDirty(EventListener::ListenerIDlistenerID,DirtyFlagflag)
- autoiter=_priorityDirtyFlagMap.find(listenerID);
- if(iter==_priorityDirtyFlagMap.end())
- _priorityDirtyFlagMap.insert(std::make_pair(listenerID,flag));
- intret=(int)flag|(int)iter->second;
- iter->second=(DirtyFlag)ret;
- </pre><br>
- <br>
- <pre></pre>
- <pre></pre>
- </pre></pre></pre></pre></pre>