http://blog.csdn.net/u012085988/article/details/16881387

  1. <prename="code"class="cpp"></pre><prename="code"class="cpp"><prename="code"class="cpp">.h
  2. #ifndef__CC_EVENT_disPATCHER_H__
  3. #define__CC_EVENT_disPATCHER_H__
  4. #include"CCPlatformMacros.h"
  5. #include"CCEventListener.h"
  6. #include"CCEvent.h"
  7. #include<functional>
  8. #include<string>
  9. #include<unordered_map>
  10. #include<list>
  11. #include<vector>
  12. NS_CC_BEGIN
  13. classEvent;
  14. classEventTouch;
  15. classNode;
  16. /**
  17. 管理eventlistener服务以及事件分发(eventdispatching).
  18. TheEventListenerlistismanagedinsuchawaythat
  19. eventlistenerscanbeaddedandremovedeven
  20. fromwithinanEventListener,whileeventsarebeing
  21. dispatched.
  22. */
  23. classEventdispatcher:publicObject
  24. {
  25. public:
  26. /**注册监听事件(优先级基于Node绘制顺序)
  27. *在消息路由时,先处理优先级<0的,在处理优先级=0(按Node绘制顺序),最后处理优先级>0的
  28. *@paramlistener监听器
  29. *@paramnode监听的node
  30. *@notefixedProprity必须是0
  31. */
  32. voidaddEventListenerWithSceneGraPHPriority(EventListener*listener,Node*node);
  33. /**注册监听事件(指定优先级)
  34. *@paramlistenerThelistenerofaspecifiedevent.
  35. *@paramfixedPriorityThefixedpriorityofthelistener.
  36. *@notealowerprioritywillbecalledbeforetheonesthathaveahighervalue.
  37. *0priorityisforbiddenforfixedprioritysinceit'susedforscenegraphbasedpriority.
  38. voidaddEventListenerWithFixedPriority(EventListener*listener,intfixedPriority);
  39. /**删除某一个监听器
  40. *@paramlistenerThespecifiedeventlistenerwhichneedstoberemoved.
  41. voidremoveEventListener(EventListener*listener);
  42. /**删除某一类监听器*/
  43. voidremoveEventListeners(EventListener::TypelistenerType);
  44. /**Removesallcustomlistenerswiththesameeventname*/
  45. voidremoveCustomEventListeners(conststd::string&customEventName);
  46. /**删除所有监听器*/
  47. voidremoveAllEventListeners();
  48. /**修改某监听器的优先级*/
  49. voidsetPriority(EventListener*listener,87); background-color:inherit; font-weight:bold">intfixedPriority);
  50. /**设置事件分发器是否可用*/
  51. voidsetEnabled(boolisEnabled);
  52. /**Checkswhetherdispatchingeventsisenabled*/
  53. boolisEnabled()const;
  54. /**分发事件
  55. *同时从dispatcherlist中删除标记为deletion的监听器
  56. voiddispatchEvent(Event*event);
  57. /**ConstructorofEventdispatcher*/
  58. Eventdispatcher();
  59. /**DestructorofEventdispatcher*/
  60. ~Eventdispatcher();
  61. private:
  62. friendclassNode;
  63. /**将Node记为Dirty
  64. 即将Node加入_dirtyNodes*/
  65. voidsetDirtyForNode(Node*node);
  66. /**跟node相关联的所有listener都暂停*/
  67. voidpauseTarget(Node*node);
  68. /**跟node相关联的所有listener都唤醒*/
  69. voidresuMetarget(Node*node);
  70. /**删除所有跟node相关联的listener*/
  71. voidcleanTarget(Node*node);
  72. *Thevectortostoreeventlistenerswithscenegraphbasedpriorityandfixedpriority.
  73. classEventListenerVector
  74. {
  75. public:
  76. EventListenerVector();
  77. ~EventListenerVector();
  78. size_tsize() boolempty()const;
  79. voidpush_back(EventListener*item);
  80. voidclearSceneGraphListeners();
  81. voidclearFixedListeners();
  82. voidclear();
  83. inlinestd::vector<EventListener*>*getFixedPriorityListeners()const{return_fixedListeners;};
  84. inlinestd::vector<EventListener*>*getSceneGraPHPriorityListeners()return_sceneGraphListeners;};
  85. inlinelonggetGt0Index()return_gt0Index;};
  86. inlinevoidsetGt0Index(longindex){_gt0Index=index;};
  87. std::vector<EventListener*>*_fixedListeners;
  88. std::vector<EventListener*>*_sceneGraphListeners;
  89. long_gt0Index;
  90. };
  91. /**Addseventlistenerwithitem*/
  92. voidaddEventListener(EventListener*listener);
  93. /**Getseventthelistenerlistfortheeventlistenertype.*/
  94. EventListenerVector*getListeners(EventListener::ListenerIDlistenerID);
  95. /**Updatedirtyflag*/
  96. voidupdateDirtyFlagForSceneGraph();
  97. /**RemovesalllistenerswiththesameeventlistenerID*/
  98. voidremoveEventListenersForListenerID(EventListener::ListenerIDlistenerID);
  99. /**排序*/
  100. voidsortEventListeners(EventListener::ListenerIDlistenerID);
  101. /**根据node优先级排序*/
  102. voidsortEventListenersOfSceneGraPHPriority(EventListener::ListenerIDlistenerID);
  103. /**根据优先级排序*/
  104. voidsortEventListenersOfFixedPriority(EventListener::ListenerIDlistenerID);
  105. /**Updatesalllisteners
  106. *1)删除所有标记为deleted的监听器.
  107. *2)添加_toAddedListeners中的监听器.
  108. voidupdateListeners(Event*event);
  109. /**ToucheventneedstobeprocesseddifferentwithothereventssinceitneedssupportALL_AT_ONCEandONE_BY_NONEmode.*/
  110. voiddispatchTouchEvent(EventTouch*event);
  111. /**Associatesnodewitheventlistener*/
  112. voidassociateNodeAndEventListener(Node*node,EventListener*listener);
  113. /**dissociatesnodewitheventlistener*/
  114. voiddissociateNodeAndEventListener(Node*node,EventListener*listener);
  115. /**dispatcheseventtolistenerswithaspecifiedlistenertype*/
  116. voiddispatchEventToListeners(EventListenerVector*listeners,std::function<bool(EventListener*)>onEvent);
  117. ///Prioritydirtyflag
  118. enumclassDirtyFlag
  119. NONE=0,
  120. FIXED_PRITORY=1<<0,
  121. SCENE_GRAPH_PRIORITY=1<<1,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> ALL=FIXED_PRITORY|SCENE_GRAPH_PRIORITY
  122. /**SetsthedirtyflagforaspecifiedlistenerID*/
  123. voidsetDirty(EventListener::ListenerIDlistenerID,DirtyFlagflag);
  124. /**遍历场景,获取每个Node的绘制顺序;
  125. 此函数在sortEventListenersOfSceneGraPHPriority之前调用*/
  126. voidvisitTarget(Node*node);
  127. private:
  128. /**map存储所有监听器map::key监听器类型*/
  129. std::unordered_map<EventListener::ListenerID,EventListenerVector*>_listeners;
  130. /**map存储一类监听器是否被污染。
  131. 即:按优先级分类,可以把所有监听器分为两类(Node,fixdpriority)。
  132. 如果_listenner[type]里的监听器全是Nodepriority,则DirtyFlag为SCENE_GRAPH_PRIORITY;
  133. 若全为fixdpriority则为FIXED_PRITORY;若两种都有,则为ALL=FIXED_PRITORY|SCENE_GRAPH_PRIORITY*/
  134. /**map关联Node与监听器*/
  135. std::unordered_map<Node*,std::vector<EventListener*>*>_nodeListenersMap;
  136. /**存储每个Node的优先级(即绘制顺序);
  137. 在visitTarge中更新该值,
  138. 在sortEventListenersOfSceneGraPHPriority中使用该值*/
  139. std::unordered_map<Node*,int>_nodePriorityMap;
  140. /**如果注册监听器时正在dispathchevent,则将该监听器加到_toAddedListeners中,
  141. 等dispatch完成后,在将其从_toAddedListeners中移到其他容器,*/
  142. std::vector<EventListener*>_toAddedListeners;
  143. /**优先级发生改变的Node
  144. 此集合中的Node所对应的Listener所在的那个vector(_listeners[ID])将会重排序*/
  145. std::set<Node*>_dirtyNodes;
  146. /**判断是否正在dispatch*/
  147. int_indispatch;
  148. /**Whethertoenabledispatchingevent*/
  149. bool_isEnabled;
  150. int_nodePriorityIndex;
  151. NS_CC_END
  152. #endif//__CC_EVENT_disPATCHER_H__
  153. cpp
  154. #include"CCEventdispatcher.h"
  155. #include"CCEventTouch.h"
  156. #include"CCEventCustom.h"
  157. #include"CCEventListenerTouch.h"
  158. #include"CCNode.h"
  159. #include"CCDirector.h"
  160. #include<algorithm>
  161. #defineDUMP_LISTENER_ITEM_PRIORITY_INFO0
  162. namespace
  163. /************************************************************************/
  164. /*用于自动处理count。一般用于构造一个局部变量。与指针计数器原理相同。
  165. 构造时+1,
  166. 析构时-1.
  167. 若函数中有多处return,而每次renturn前都要处理某变量的值,则可以采用此机制优化代码;
  168. 此机制只需利用变量a构造一个局部变量,无需在每次返回前再处理变量a。
  169. classdispatchGuard
  170. dispatchGuard(int&count):
  171. _count(count)
  172. ++_count;
  173. }
  174. ~dispatchGuard()
  175. --_count;
  176. }
  177. int&_count;
  178. //根据Event的type确定EventListener的Type
  179. //关于EventListener的ListenerId与EventListener的Type(注意这里不是Event::Type)映射关系
  180. //出自定制类型外,其他类型都是用枚举一一映射的,而自定制类型则是计算hash值
  181. staticEventListener::ListenerIDgetListenerID(Event*event)
  182. EventListener::ListenerIDret;
  183. switch(event->getType())
  184. caseEvent::Type::acceleration:
  185. ret=static_cast<EventListener::ListenerID>(EventListener::Type::acceleration);
  186. break;
  187. caseEvent::Type::CUSTOM:
  188. autocustomEvent=static_cast<EventCustom*>(event);
  189. autolistenerID=std::hash<std::string>()(customEvent->getEventName());
  190. static_cast<EventListener::ListenerID>(listenerID);
  191. break;
  192. caseEvent::Type::KEYBOARD:
  193. static_cast<EventListener::ListenerID>(EventListener::Type::KEYBOARD);
  194. caseEvent::Type::MOUSE:
  195. ret=static_cast<EventListener::ListenerID>(EventListener::Type::MOUSE);
  196. caseEvent::Type::TOUCH:
  197. //Touchlistenerisveryspecial,itcontainstwokindsoflisteners,EventListenerTouchOneByOneandEventListenerTouchAllAtOnce.
  198. //returnUNKNowinstead.
  199. static_cast<EventListener::ListenerID>(EventListener::Type::UNKNowN);
  200. default:
  201. CCASSERT(false,"Invalidtype!");
  202. returnret;
  203. Eventdispatcher::EventListenerVector::EventListenerVector()
  204. :_sceneGraphListeners(nullptr)
  205. ,_fixedListeners(nullptr)
  206. ,_gt0Index(0)
  207. Eventdispatcher::EventListenerVector::~EventListenerVector()
  208. CC_SAFE_DELETE(_sceneGraphListeners);
  209. CC_SAFE_DELETE(_fixedListeners);
  210. size_tEventdispatcher::EventListenerVector::size()const
  211. size_tret=0;
  212. if(_sceneGraphListeners)
  213. ret+=_sceneGraphListeners->size();
  214. if(_fixedListeners)
  215. ret+=_fixedListeners->size();
  216. boolEventdispatcher::EventListenerVector::empty()const
  217. return(_sceneGraphListeners==nullptr||_sceneGraphListeners->empty())
  218. &&(_fixedListeners==nullptr||_fixedListeners->empty());
  219. voidEventdispatcher::EventListenerVector::push_back(EventListener*listener)
  220. if(listener->getFixedPriority()==0)
  221. if(_sceneGraphListeners==nullptr)
  222. _sceneGraphListeners=newstd::vector<EventListener*>();
  223. _sceneGraphListeners->reserve(100);
  224. _sceneGraphListeners->push_back(listener);
  225. else
  226. if(_fixedListeners==nullptr)
  227. _fixedListeners= _fixedListeners->reserve(100);
  228. _fixedListeners->push_back(listener);
  229. voidEventdispatcher::EventListenerVector::clearSceneGraphListeners()
  230. _sceneGraphListeners->clear();
  231. delete_sceneGraphListeners;
  232. _sceneGraphListeners=nullptr;
  233. voidEventdispatcher::EventListenerVector::clearFixedListeners()
  234. _fixedListeners->clear();
  235. delete_fixedListeners;
  236. _fixedListeners=nullptr;
  237. voidEventdispatcher::EventListenerVector::clear()
  238. clearSceneGraphListeners();
  239. clearFixedListeners();
  240. Eventdispatcher::Eventdispatcher()
  241. :_indispatch(0)
  242. true)
  243. _toAddedListeners.reserve(50);
  244. Eventdispatcher::~Eventdispatcher()
  245. removeAllEventListeners();
  246. voidEventdispatcher::visitTarget(Node*node)
  247. inti=0;
  248. Array*children=node->getChildren();
  249. intchildrenCount=children?children->count():0;
  250. if(childrenCount>0)
  251. Node*child=nullptr;
  252. //只计算子节点中zOrder<0的
  253. for(;i<childrenCount;i++)
  254. child=static_cast<Node*>(children->getobjectAtIndex(i));
  255. if(child&&child->getZOrder()<0)
  256. visitTarget(child);
  257. else
  258. //记录Node的优先级
  259. _nodePriorityMap.insert(std::make_pair(node,++_nodePriorityIndex));
  260. for(;i<childrenCount;i++)
  261. child=static_cast<Node*>(children->getobjectAtIndex(i));
  262. if(child)
  263. _nodePriorityMap.insert(std::make_pair(node,++_nodePriorityIndex));
  264. voidEventdispatcher::pauseTarget(Node*node)
  265. autolistenerIter=_nodeListenersMap.find(node);
  266. if(listenerIter!=_nodeListenersMap.end())
  267. autolisteners=listenerIter->second;
  268. for(auto&l:*listeners)
  269. l->setPaused(true);
  270. voidEventdispatcher::resuMetarget(Node*node)
  271. autolistenerIter=_nodeListenersMap.find(node);
  272. if(listenerIter!=_nodeListenersMap.end())
  273. autolisteners=listenerIter->second;
  274. for(auto&l:*listeners)
  275. l->setPaused(false);
  276. setDirtyForNode(node);
  277. voidEventdispatcher::cleanTarget(Node*node)
  278. autolistenerscopy=*listeners;
  279. for(auto&l:listenerscopy)
  280. removeEventListener(l);
  281. voidEventdispatcher::associateNodeAndEventListener(Node*node,EventListener*listener)
  282. std::vector<EventListener*>*listeners=nullptr;
  283. autofound=_nodeListenersMap.find(node);
  284. if(found!=_nodeListenersMap.end())
  285. listeners=found->second;
  286. listeners= listeners->push_back(listener);
  287. _nodeListenersMap.insert(std::make_pair(node,listeners));
  288. 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);
  289. if(iter!=listeners->end())
  290. listeners->erase(iter);
  291. if(listeners->empty())
  292. _nodeListenersMap.erase(found);
  293. deletelisteners;
  294. voidEventdispatcher::addEventListener(EventListener*listener)
  295. //如果不是正在路由事件
  296. if(_indispatch==0)
  297. EventListenerVector*listenerList=nullptr;
  298. //根据listenerID获取相应vector
  299. autoiter=_listeners.find(listener->getListenerID());
  300. if(iter==_listeners.end())
  301. listenerList=newEventListenerVector();
  302. _listeners.insert(std::make_pair(listener->getListenerID(),listenerList));
  303. listenerList=iter->second;
  304. listenerList->push_back(listener);
  305. if(listener->getFixedPriority()==0)
  306. //如果优先级根据Node而定
  307. setDirty(listener->getListenerID(),DirtyFlag::SCENE_GRAPH_PRIORITY);
  308. //如果优先级根据Fixed而定
  309. setDirty(listener->getListenerID(),DirtyFlag::FIXED_PRITORY);
  310. //如果正在路由事件,则直接加入_toAddedListeners
  311. _toAddedListeners.push_back(listener);
  312. voidEventdispatcher::addEventListenerWithSceneGraPHPriority(EventListener*listener,Node*node)
  313. CCASSERT(listener&&node,"Invalidparameters.");
  314. CCASSERT(!listener->isRegistered(),"Thelistenerhasbeenregistered.");
  315. if(!listener->checkAvailable())
  316. return;
  317. listener->setSceneGraPHPriority(node);
  318. listener->setFixedPriority(0);
  319. listener->setRegistered( listener->retain();
  320. //存储listener,
  321. addEventListener(listener);
  322. //关联node与listener
  323. associateNodeAndEventListener(node,listener);
  324. if(node->isRunning())
  325. resuMetarget(node);
  326. voidEventdispatcher::addEventListenerWithFixedPriority(EventListener*listener,87); background-color:inherit; font-weight:bold">intfixedPriority)
  327. CCASSERT(listener,"Invalidparameters.");
  328. CCASSERT(!listener->isRegistered(),"Thelistenerhasbeenregistered.");
  329. CCASSERT(fixedPriority!=0,"0priorityisforbiddenforfixedprioritysinceit'susedforscenegraphbasedpriority.");
  330. listener->setSceneGraPHPriority(nullptr);
  331. listener->setFixedPriority(fixedPriority);
  332. listener->setPaused( listener->retain();
  333. addEventListener(listener);
  334. voidEventdispatcher::removeEventListener(EventListener*listener)
  335. if(listener==nullptr)
  336. return;
  337. boolisFound=false;
  338. autoremoveListenerInVector=[&](std::vector<EventListener*>*listeners){
  339. if(listeners==nullptr)
  340. for(autoiter=listeners->begin();iter!=listeners->end();++iter)
  341. autol=*iter;
  342. if(l==listener)
  343. CC_SAFE_RETAIN(l);
  344. l->setRegistered(if(l->getSceneGraPHPriority()!=nullptr)
  345. //撤销node与listener的关联
  346. dissociateNodeAndEventListener(l->getSceneGraPHPriority(),l);
  347. if(_indispatch==0)
  348. listeners->erase(iter);
  349. CC_SAFE_RELEASE(l);
  350. isFound=true;
  351. for(autoiter=_listeners.begin();iter!=_listeners.end();)
  352. autolisteners=iter->second;
  353. autofixedPriorityListeners=listeners->getFixedPriorityListeners();
  354. autosceneGraPHPriorityListeners=listeners->getSceneGraPHPriorityListeners();
  355. removeListenerInVector(sceneGraPHPriorityListeners);
  356. if(!isFound)
  357. removeListenerInVector(fixedPriorityListeners);
  358. if(iter->second->empty())
  359. _priorityDirtyFlagMap.erase(listener->getListenerID());
  360. autolist=iter->second;
  361. iter=_listeners.erase(iter);
  362. CC_SAFE_DELETE(list);
  363. ++iter;
  364. if(isFound)
  365. CC_SAFE_RELEASE(listener);
  366. //若没有找到,则在_toAddedListeners中找
  367. for(autoiter=_toAddedListeners.begin();iter!=_toAddedListeners.end();++iter)
  368. if(*iter==listener)
  369. _toAddedListeners.erase(iter);
  370. voidEventdispatcher::setPriority(EventListener*listener,87); background-color:inherit; font-weight:bold">intfixedPriority)
  371. for(autoiter=_listeners.begin();iter!=_listeners.end();++iter)
  372. autofixedPriorityListeners=iter->second->getFixedPriorityListeners();
  373. if(fixedPriorityListeners)
  374. autofound=std::find(fixedPriorityListeners->begin(),fixedPriorityListeners->end(),153); background-color:inherit; font-weight:bold">if(found!=fixedPriorityListeners->end())
  375. CCASSERT(listener->getSceneGraPHPriority()==nullptr,"Can'tsetfixedprioritywithscenegraphbasedlistener.");
  376. if(listener->getFixedPriority()!=fixedPriority)
  377. voidEventdispatcher::dispatchEventToListeners(EventListenerVector*listeners,87); background-color:inherit; font-weight:bold">bool(EventListener*)>onEvent)
  378. boolshouldStopPropagation=false;
  379. longi=0;
  380. //priority<0
  381. for(;!fixedPriorityListeners->empty()&&i<listeners->getGt0Index();++i)
  382. autol=fixedPriorityListeners->at(i);
  383. if(!l->isPaused()&&l->isRegistered()&&onEvent(l))
  384. shouldStopPropagation=true;
  385. if(sceneGraPHPriorityListeners)
  386. if(!shouldStopPropagation)
  387. //priority==0,scenegraPHPriority
  388. for(auto&l:*sceneGraPHPriorityListeners)
  389. if(!l->isPaused()&&l->isRegistered()&&onEvent(l))
  390. shouldStopPropagation=if(fixedPriorityListeners)
  391. //priority>0
  392. for(;i<static_cast<long>(fixedPriorityListeners->size());++i)
  393. if(!l->isPaused()&&l->isRegistered()&&onEvent(fixedPriorityListeners->at(i)))
  394. voidEventdispatcher::dispatchEvent(Event*event)
  395. if(!_isEnabled)
  396. updateDirtyFlagForSceneGraph();
  397. dispatchGuardguard(_indispatch);
  398. if(event->getType()==Event::Type::TOUCH)
  399. dispatchTouchEvent(static_cast<EventTouch*>(event));
  400. autolistenerID=getListenerID(event);
  401. sortEventListeners(listenerID);
  402. autoiter=_listeners.find(listenerID);
  403. if(iter!=_listeners.end())
  404. autolisteners=iter->second;
  405. autoonEvent=[&event](EventListener*listener)->bool{
  406. event->setCurrentTarget(listener->getSceneGraPHPriority());
  407. listener->_onEvent(event);
  408. returnevent->isstopped();
  409. };
  410. dispatchEventToListeners(listeners,onEvent);
  411. updateListeners(event);
  412. voidEventdispatcher::dispatchTouchEvent(EventTouch*event)
  413. autotouchOneByOneID=static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ONE_BY_ONE);
  414. autotouchAllAtOnceID=static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ALL_AT_ONCE);
  415. sortEventListeners(touchOneByOneID);
  416. sortEventListeners(touchAllAtOnceID);
  417. autooneByOnelisteners=getListeners(touchOneByOneID);
  418. autoallAtOncelisteners=getListeners(touchAllAtOnceID);
  419. //Iftherearen'tanytouchlisteners,returndirectly.
  420. if(nullptr==oneByOnelisteners&&nullptr==allAtOncelisteners)
  421. boolisNeedsMutableSet=(oneByOnelisteners&&allAtOncelisteners);
  422. std::vector<Touch*>orignaltouches=event->gettouches();
  423. std::vector<Touch*>mutabletouches(orignaltouches.size());
  424. std::copy(orignaltouches.begin(),orignaltouches.end(),mutabletouches.begin());
  425. //
  426. //processthetargethandlers1st
  427. if(oneByOnelisteners)
  428. automutabletouchesIter=mutabletouches.begin();
  429. autotouchesIter=orignaltouches.begin();
  430. for(;touchesIter!=orignaltouches.end();++touchesIter)
  431. boolisSwallowed= autoonTouchEvent=[&](EventListener*l)->bool{//Returntruetobreak
  432. EventListenerTouchOneByOne*listener=static_cast<EventListenerTouchOneByOne*>(l);
  433. //Skipifthelistenerwasremoved.
  434. if(!listener->_isRegistered)
  435. return event->setCurrentTarget(listener->_node);
  436. boolisClaimed= std::vector<Touch*>::iteratorremovedIter;
  437. EventTouch::EventCodeeventCode=event->getEventCode();
  438. if(eventCode==EventTouch::EventCode::BEGAN)
  439. if(listener->onTouchBegan)
  440. isClaimed=listener->onTouchBegan(*touchesIter,event);
  441. if(isClaimed&&listener->_isRegistered)
  442. listener->_claimedtouches.push_back(*touchesIter);
  443. elseif(listener->_claimedtouches.size()>0
  444. &&((removedIter=std::find(listener->_claimedtouches.begin(),listener->_claimedtouches.end(),*touchesIter))!=listener->_claimedtouches.end()))
  445. isClaimed=switch(eventCode)
  446. caseEventTouch::EventCode::MOVED:
  447. if(listener->onTouchMoved)
  448. listener->onTouchMoved(*touchesIter,event);
  449. caseEventTouch::EventCode::ENDED:
  450. if(listener->onTouchEnded)
  451. listener->onTouchEnded(*touchesIter,153); background-color:inherit; font-weight:bold">if(listener->_isRegistered)
  452. listener->_claimedtouches.erase(removedIter);
  453. caseEventTouch::EventCode::CANCELLED:
  454. if(listener->onTouchCancelled)
  455. listener->onTouchCancelled(*touchesIter,153); background-color:inherit; font-weight:bold">default:
  456. CCASSERT("Theeventcodeisinvalid.");
  457. //Iftheeventwasstopped,153); background-color:inherit; font-weight:bold">if(event->isstopped())
  458. updateListeners(event);
  459. CCASSERT((*touchesIter)->getID()==(*mutabletouchesIter)->getID(),"");
  460. if(isClaimed&&listener->_isRegistered&&listener->_needSwallow)
  461. if(isNeedsMutableSet)
  462. mutabletouchesIter=mutabletouches.erase(mutabletouchesIter);
  463. isSwallowed= dispatchEventToListeners(oneByOnelisteners,onTouchEvent);
  464. if(event->isstopped())
  465. if(!isSwallowed)
  466. ++mutabletouchesIter;
  467. //processstandardhandlers2nd
  468. if(allAtOncelisteners&&mutabletouches.size()>0)
  469. autoontouchesEvent=[&](EventListener*l)->bool{
  470. EventListenerTouchAllAtOnce*listener=static_cast<EventListenerTouchAllAtOnce*>(l);
  471. //Skipifthelistenerwasremoved.
  472. if(!listener->_isRegistered)
  473. event->setCurrentTarget(listener->_node);
  474. switch(event->getEventCode())
  475. caseEventTouch::EventCode::BEGAN:
  476. if(listener->ontouchesBegan)
  477. listener->ontouchesBegan(mutabletouches,153); background-color:inherit; font-weight:bold">if(listener->ontouchesMoved)
  478. listener->ontouchesMoved(mutabletouches,153); background-color:inherit; font-weight:bold">if(listener->ontouchesEnded)
  479. listener->ontouchesEnded(mutabletouches,153); background-color:inherit; font-weight:bold">if(listener->ontouchesCancelled)
  480. listener->ontouchesCancelled(mutabletouches,returndirectly.
  481. dispatchEventToListeners(allAtOncelisteners,ontouchesEvent);
  482. voidEventdispatcher::updateListeners(Event*event)
  483. autoonUpdateListeners=[this](EventListener::ListenerIDlistenerID)
  484. autolistenersIter=_listeners.find(listenerID);
  485. if(listenersIter==_listeners.end())
  486. autolisteners=listenersIter->second;
  487. autofixedPriorityListeners=listeners->getFixedPriorityListeners();
  488. autosceneGraPHPriorityListeners=listeners->getSceneGraPHPriorityListeners();
  489. for(autoiter=sceneGraPHPriorityListeners->begin();iter!=sceneGraPHPriorityListeners->end();)
  490. if(!l->isRegistered())
  491. iter=sceneGraPHPriorityListeners->erase(iter);
  492. l->release();
  493. for(autoiter=fixedPriorityListeners->begin();iter!=fixedPriorityListeners->end();)
  494. autol=*iter;
  495. if(!l->isRegistered())
  496. iter=fixedPriorityListeners->erase(iter);
  497. l->release();
  498. ++iter;
  499. if(sceneGraPHPriorityListeners&&sceneGraPHPriorityListeners->empty())
  500. listeners->clearSceneGraphListeners();
  501. if(fixedPriorityListeners&&fixedPriorityListeners->empty())
  502. listeners->clearFixedListeners();
  503. if(listenersIter->second->empty())
  504. _priorityDirtyFlagMap.erase(listenersIter->first);
  505. deletelistenersIter->second;
  506. listenersIter=_listeners.erase(listenersIter);
  507. ++listenersIter;
  508. if(event->getType()==Event::Type::TOUCH)
  509. onUpdateListeners(static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ONE_BY_ONE));
  510. onUpdateListeners(static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ALL_AT_ONCE));
  511. onUpdateListeners(getListenerID(event));
  512. if(!_toAddedListeners.empty())
  513. EventListenerVector*listeners=nullptr;
  514. for(auto&listener:_toAddedListeners)
  515. EventListener::ListenerIDlistenerID=listener->getListenerID();
  516. autoitr=_listeners.find(listenerID);
  517. if(itr==_listeners.end())
  518. newEventListenerVector();
  519. _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;
  520. listeners->push_back(listener);
  521. setDirty(listenerID,DirtyFlag::FIXED_PRITORY);
  522. _toAddedListeners.clear();
  523. voidEventdispatcher::updateDirtyFlagForSceneGraph()
  524. if(!_dirtyNodes.empty())
  525. for(auto&node:_dirtyNodes)
  526. autoiter=_nodeListenersMap.find(node);
  527. if(iter!=_nodeListenersMap.end())
  528. for(auto&l:*iter->second)
  529. 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();
  530. voidEventdispatcher::sortEventListeners(EventListener::ListenerIDlistenerID)
  531. DirtyFlagdirtyFlag=DirtyFlag::NONE;
  532. autodirtyIter=_priorityDirtyFlagMap.find(listenerID);
  533. if(dirtyIter!=_priorityDirtyFlagMap.end())
  534. dirtyFlag=dirtyIter->second;
  535. if(dirtyFlag!=DirtyFlag::NONE)
  536. if((int)dirtyFlag&(int)DirtyFlag::FIXED_PRITORY)
  537. sortEventListenersOfFixedPriority(listenerID);
  538. int)DirtyFlag::SCENE_GRAPH_PRIORITY)
  539. sortEventListenersOfSceneGraPHPriority(listenerID);
  540. dirtyIter->second=DirtyFlag::NONE;
  541. voidEventdispatcher::sortEventListenersOfSceneGraPHPriority(EventListener::ListenerIDlistenerID)
  542. autolisteners=getListeners(listenerID);
  543. Node*rootNode=(Node*)Director::getInstance()->getRunningScene();
  544. //Resetpriorityindex
  545. _nodePriorityIndex=0;
  546. _nodePriorityMap.clear();
  547. visitTarget(rootNode);
  548. //Aftersort:priority<0,>0
  549. autosceneGraphlisteners=listeners->getSceneGraPHPriorityListeners();
  550. std::sort(sceneGraphlisteners->begin(),sceneGraphlisteners->end(),[this](constEventListener*l1,constEventListener*l2){
  551. return_nodePriorityMap[l1->getSceneGraPHPriority()]>_nodePriorityMap[l2->getSceneGraPHPriority()];
  552. });
  553. #ifDUMP_LISTENER_ITEM_PRIORITY_INFO
  554. log("-----------------------------------");
  555. for(auto&l:*sceneGraphlisteners)
  556. log("listenerpriority:node([%s]%p),priority(%d)",153); background-color:inherit; font-weight:bold">typeid(*l->_node).name(),l->_node,_nodePriorityMap[l->_node]);
  557. #endif
  558. voidEventdispatcher::sortEventListenersOfFixedPriority(EventListener::ListenerIDlistenerID)
  559. autolisteners=getListeners(listenerID);
  560. if(listeners==nullptr)
  561. autofixedlisteners=listeners->getFixedPriorityListeners();
  562. std::sort(fixedlisteners->begin(),fixedlisteners->end(),[](returnl1->getFixedPriority()<l2->getFixedPriority();
  563. //FIXME:Shouldusebinarysearch
  564. longindex=0;
  565. for(auto&listener:*fixedlisteners)
  566. if(listener->getFixedPriority()>=0)
  567. ++index;
  568. listeners->setGt0Index(index);
  569. #ifDUMP_LISTENER_ITEM_PRIORITY_INFO
  570. log("-----------------------------------");
  571. for(auto&l:*fixedlisteners)
  572. log("listenerpriority:node(%p),fixed(%d)",l->_fixedPriority);
  573. #endif
  574. Eventdispatcher::EventListenerVector*Eventdispatcher::getListeners(EventListener::ListenerIDlistenerID)
  575. autoiter=_listeners.find(listenerID);
  576. if(iter!=_listeners.end())
  577. returniter->second;
  578. returnnullptr;
  579. voidEventdispatcher::removeEventListenersForListenerID(EventListener::ListenerIDlistenerID)
  580. autolistenerItemIter=_listeners.find(listenerID);
  581. if(listenerItemIter!=_listeners.end())
  582. autolisteners=listenerItemIter->second;
  583. autoremoveAllListenersInVector=[&](std::vector<EventListener*>*listenerVector){
  584. if(listenerVector==nullptr)
  585. for(autoiter=listenerVector->begin();iter!=listenerVector->end();)
  586. l->setRegistered(false);
  587. if(l->getSceneGraPHPriority()!=nullptr)
  588. iter=listenerVector->erase(iter);
  589. removeAllListenersInVector(sceneGraPHPriorityListeners);
  590. removeAllListenersInVector(fixedPriorityListeners);
  591. if(!_indispatch)
  592. listeners->clear();
  593. deletelisteners;
  594. _listeners.erase(listenerItemIter);
  595. _priorityDirtyFlagMap.erase(listenerID);
  596. for(autoiter=_toAddedListeners.begin();iter!=_toAddedListeners.end();)
  597. if((*iter)->getListenerID()==listenerID)
  598. iter=_toAddedListeners.erase(iter);
  599. voidEventdispatcher::removeEventListeners(EventListener::TypelistenerType)
  600. CCASSERT(listenerType!=EventListener::Type::CUSTOM,"Notsupportcustomeventlistenertype,pleaseuseEventdispatcher::removeCustomEventListenersinstead.");
  601. removeEventListenersForListenerID(static_cast<EventListener::ListenerID>(listenerType));
  602. voidEventdispatcher::removeCustomEventListeners(conststd::string&customEventName)
  603. removeEventListenersForListenerID(std::hash<std::string>()(customEventName));
  604. voidEventdispatcher::removeAllEventListeners()
  605. std::vector<int>types(_listeners.size());
  606. types.push_back(iter->first);
  607. for(auto&type:types)
  608. removeEventListenersForListenerID(type);
  609. _listeners.clear();
  610. voidEventdispatcher::setEnabled(boolisEnabled)
  611. _isEnabled=isEnabled;
  612. boolEventdispatcher::isEnabled()return_isEnabled;
  613. voidEventdispatcher::setDirtyForNode(Node*node)
  614. //Markthenodedirtyonlywhentherewasaneventlistenerassociateswithit.
  615. if(_nodeListenersMap.find(node)!=_nodeListenersMap.end())
  616. _dirtyNodes.insert(node);
  617. voidEventdispatcher::setDirty(EventListener::ListenerIDlistenerID,DirtyFlagflag)
  618. autoiter=_priorityDirtyFlagMap.find(listenerID);
  619. if(iter==_priorityDirtyFlagMap.end())
  620. _priorityDirtyFlagMap.insert(std::make_pair(listenerID,flag));
  621. intret=(int)flag|(int)iter->second;
  622. iter->second=(DirtyFlag)ret;
  623. </pre><br>
  624. <br>
  625. <pre></pre>
  626. <pre></pre>
  627. </pre></pre></pre></pre></pre>

cocos2dx-3.0 : EventDispatcher的更多相关文章

  1. HTML5自定义视频播放器源码

    这篇文章主要介绍了HTML5自定义视频播放器源码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  2. HTML5自定义mp3播放器源码

    这篇文章主要介绍了HTML5自定义mp3播放器源码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  3. html5自定义video标签的海报与播放按钮功能

    这篇文章主要介绍了html5自定义video标签的海报与播放按钮功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  4. CSS中实现动画效果-附案例

    这篇文章主要介绍了 CSS中实现动画效果并附上案例代码及实现效果,就是CSS动画样式处理,动画声明需要使用@keyframes name,后面的name是人为定义的动画名称,下面我们来看看文章的具体实现内容吧,需要的小伙伴可以参考一下

  5. h5页面背景图很长要有滚动条滑动效果的实现

    这篇文章主要介绍了h5页面背景图很长要有滚动条滑动效果的实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. html5借用repeating-linear-gradient实现一把刻度尺(ruler)

    这篇文章主要介绍了html5借用repeating-linear-gradient实现一把刻度尺,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  7. 如何在Canvas中添加事件的方法示例

    这篇文章主要介绍了如何在Canvas中添加事件的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. HTML5自定义元素播放焦点图动画的实现

    这篇文章主要介绍了HTML5自定义元素播放焦点图动画的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  9. 有关HTML5页面在iPhoneX适配问题

    这篇文章主要介绍了有关HTML5页面在iPhoneX适配问题,需要的朋友可以参考下

  10. html5简介及新增功能介绍

    这篇文章主要介绍了html5简介及新增功能介绍,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部