cocos2dx-3.0 : EventDispatcher

cocos2dx-3.0 : EventDispatcher,第1张

概述http://blog.csdn.net/u012085988/article/details/16881387 <pre name="code" class="cpp"></pre><pre name="code" class="cpp"><pre name="code" class="cpp"><pre name="code" class="cpp"><pre name="code" clas

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> 总结

以上是内存溢出为你收集整理的cocos2dx-3.0 : EventDispatcher全部内容,希望文章能够帮你解决cocos2dx-3.0 : EventDispatcher所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1060339.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存