CCEventDispatcher.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636
  1. /****************************************************************************
  2. Copyright (c) 2013-2017 Chukong Technologies Inc.
  3. http://www.cocos2d-x.org
  4. Permission is hereby granted, free of charge, to any person obtaining a copy
  5. of this software and associated documentation files (the "Software"), to deal
  6. in the Software without restriction, including without limitation the rights
  7. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. copies of the Software, and to permit persons to whom the Software is
  9. furnished to do so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in
  11. all copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  18. THE SOFTWARE.
  19. ****************************************************************************/
  20. #include "base/CCEventDispatcher.h"
  21. #include <algorithm>
  22. #include "base/CCEventCustom.h"
  23. #include "base/CCEventListenerTouch.h"
  24. #include "base/CCEventListenerAcceleration.h"
  25. #include "base/CCEventListenerMouse.h"
  26. #include "base/CCEventListenerGyroscope.h"
  27. #include "base/CCEventListenerKeyboard.h"
  28. #include "base/CCEventListenerCustom.h"
  29. #include "base/CCEventListenerFocus.h"
  30. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
  31. #include "base/CCEventListenerController.h"
  32. #endif
  33. #include "2d/CCScene.h"
  34. #include "base/CCDirector.h"
  35. #include "base/CCEventType.h"
  36. #include "2d/CCCamera.h"
  37. #define DUMP_LISTENER_ITEM_PRIORITY_INFO 0
  38. namespace
  39. {
  40. class DispatchGuard
  41. {
  42. public:
  43. DispatchGuard(int& count):
  44. _count(count)
  45. {
  46. ++_count;
  47. }
  48. ~DispatchGuard()
  49. {
  50. --_count;
  51. }
  52. private:
  53. int& _count;
  54. };
  55. }
  56. NS_CC_BEGIN
  57. static EventListener::ListenerID __getListenerID(Event* event)
  58. {
  59. EventListener::ListenerID ret;
  60. switch (event->getType())
  61. {
  62. case Event::Type::ACCELERATION:
  63. ret = EventListenerAcceleration::LISTENER_ID;
  64. break;
  65. case Event::Type::GYROSCOPE:
  66. ret = EventListenerGyroscope::LISTENER_ID;
  67. break;
  68. case Event::Type::CUSTOM:
  69. {
  70. auto customEvent = static_cast<EventCustom*>(event);
  71. ret = customEvent->getEventName();
  72. }
  73. break;
  74. case Event::Type::KEYBOARD:
  75. ret = EventListenerKeyboard::LISTENER_ID;
  76. break;
  77. case Event::Type::MOUSE:
  78. ret = EventListenerMouse::LISTENER_ID;
  79. break;
  80. case Event::Type::FOCUS:
  81. ret = EventListenerFocus::LISTENER_ID;
  82. break;
  83. case Event::Type::TOUCH:
  84. // Touch listener is very special, it contains two kinds of listeners, EventListenerTouchOneByOne and EventListenerTouchAllAtOnce.
  85. // return UNKNOWN instead.
  86. CCASSERT(false, "Don't call this method if the event is for touch.");
  87. break;
  88. #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
  89. case Event::Type::GAME_CONTROLLER:
  90. ret = EventListenerController::LISTENER_ID;
  91. break;
  92. #endif
  93. default:
  94. CCASSERT(false, "Invalid type!");
  95. break;
  96. }
  97. return ret;
  98. }
  99. EventDispatcher::EventListenerVector::EventListenerVector() :
  100. _fixedListeners(nullptr),
  101. _sceneGraphListeners(nullptr),
  102. _gt0Index(0)
  103. {
  104. }
  105. EventDispatcher::EventListenerVector::~EventListenerVector()
  106. {
  107. CC_SAFE_DELETE(_sceneGraphListeners);
  108. CC_SAFE_DELETE(_fixedListeners);
  109. }
  110. size_t EventDispatcher::EventListenerVector::size() const
  111. {
  112. size_t ret = 0;
  113. if (_sceneGraphListeners)
  114. ret += _sceneGraphListeners->size();
  115. if (_fixedListeners)
  116. ret += _fixedListeners->size();
  117. return ret;
  118. }
  119. bool EventDispatcher::EventListenerVector::empty() const
  120. {
  121. return (_sceneGraphListeners == nullptr || _sceneGraphListeners->empty())
  122. && (_fixedListeners == nullptr || _fixedListeners->empty());
  123. }
  124. void EventDispatcher::EventListenerVector::push_back(EventListener* listener)
  125. {
  126. #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS
  127. CCASSERT(_sceneGraphListeners == nullptr ||
  128. std::count(_sceneGraphListeners->begin(), _sceneGraphListeners->end(), listener) == 0,
  129. "Listener should not be added twice!");
  130. CCASSERT(_fixedListeners == nullptr ||
  131. std::count(_fixedListeners->begin(), _fixedListeners->end(), listener) == 0,
  132. "Listener should not be added twice!");
  133. #endif
  134. if (listener->getFixedPriority() == 0)
  135. {
  136. if (_sceneGraphListeners == nullptr)
  137. {
  138. _sceneGraphListeners = new (std::nothrow) std::vector<EventListener*>();
  139. _sceneGraphListeners->reserve(100);
  140. }
  141. _sceneGraphListeners->push_back(listener);
  142. }
  143. else
  144. {
  145. if (_fixedListeners == nullptr)
  146. {
  147. _fixedListeners = new std::vector<EventListener*>();
  148. _fixedListeners->reserve(100);
  149. }
  150. _fixedListeners->push_back(listener);
  151. }
  152. }
  153. void EventDispatcher::EventListenerVector::clearSceneGraphListeners()
  154. {
  155. if (_sceneGraphListeners)
  156. {
  157. _sceneGraphListeners->clear();
  158. delete _sceneGraphListeners;
  159. _sceneGraphListeners = nullptr;
  160. }
  161. }
  162. void EventDispatcher::EventListenerVector::clearFixedListeners()
  163. {
  164. if (_fixedListeners)
  165. {
  166. _fixedListeners->clear();
  167. delete _fixedListeners;
  168. _fixedListeners = nullptr;
  169. }
  170. }
  171. void EventDispatcher::EventListenerVector::clear()
  172. {
  173. clearSceneGraphListeners();
  174. clearFixedListeners();
  175. }
  176. EventDispatcher::EventDispatcher()
  177. : _inDispatch(0)
  178. , _isEnabled(false)
  179. , _nodePriorityIndex(0)
  180. {
  181. _toAddedListeners.reserve(50);
  182. _toRemovedListeners.reserve(50);
  183. // fixed #4129: Mark the following listener IDs for internal use.
  184. // Therefore, internal listeners would not be cleaned when removeAllEventListeners is invoked.
  185. _internalCustomListenerIDs.insert(EVENT_COME_TO_FOREGROUND);
  186. _internalCustomListenerIDs.insert(EVENT_COME_TO_BACKGROUND);
  187. _internalCustomListenerIDs.insert(EVENT_RENDERER_RECREATED);
  188. }
  189. EventDispatcher::~EventDispatcher()
  190. {
  191. // Clear internal custom listener IDs from set,
  192. // so removeAllEventListeners would clean internal custom listeners.
  193. _internalCustomListenerIDs.clear();
  194. removeAllEventListeners();
  195. }
  196. void EventDispatcher::visitTarget(Node* node, bool isRootNode)
  197. {
  198. node->sortAllChildren();
  199. int i = 0;
  200. auto& children = node->getChildren();
  201. auto childrenCount = children.size();
  202. if(childrenCount > 0)
  203. {
  204. Node* child = nullptr;
  205. // visit children zOrder < 0
  206. for( ; i < childrenCount; i++ )
  207. {
  208. child = children.at(i);
  209. if ( child && child->getLocalZOrder() < 0 )
  210. visitTarget(child, false);
  211. else
  212. break;
  213. }
  214. if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
  215. {
  216. _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);
  217. }
  218. for( ; i < childrenCount; i++ )
  219. {
  220. child = children.at(i);
  221. if (child)
  222. visitTarget(child, false);
  223. }
  224. }
  225. else
  226. {
  227. if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
  228. {
  229. _globalZOrderNodeMap[node->getGlobalZOrder()].push_back(node);
  230. }
  231. }
  232. if (isRootNode)
  233. {
  234. std::vector<float> globalZOrders;
  235. globalZOrders.reserve(_globalZOrderNodeMap.size());
  236. for (const auto& e : _globalZOrderNodeMap)
  237. {
  238. globalZOrders.push_back(e.first);
  239. }
  240. std::stable_sort(globalZOrders.begin(), globalZOrders.end(), [](const float a, const float b){
  241. return a < b;
  242. });
  243. for (const auto& globalZ : globalZOrders)
  244. {
  245. for (const auto& n : _globalZOrderNodeMap[globalZ])
  246. {
  247. _nodePriorityMap[n] = ++_nodePriorityIndex;
  248. }
  249. }
  250. _globalZOrderNodeMap.clear();
  251. }
  252. }
  253. void EventDispatcher::pauseEventListenersForTarget(Node* target, bool recursive/* = false */)
  254. {
  255. auto listenerIter = _nodeListenersMap.find(target);
  256. if (listenerIter != _nodeListenersMap.end())
  257. {
  258. auto listeners = listenerIter->second;
  259. for (auto& l : *listeners)
  260. {
  261. l->setPaused(true);
  262. }
  263. }
  264. for (auto& listener : _toAddedListeners)
  265. {
  266. if (listener->getAssociatedNode() == target)
  267. {
  268. listener->setPaused(true);
  269. }
  270. }
  271. if (recursive)
  272. {
  273. const auto& children = target->getChildren();
  274. for (const auto& child : children)
  275. {
  276. pauseEventListenersForTarget(child, true);
  277. }
  278. }
  279. }
  280. void EventDispatcher::resumeEventListenersForTarget(Node* target, bool recursive/* = false */)
  281. {
  282. auto listenerIter = _nodeListenersMap.find(target);
  283. if (listenerIter != _nodeListenersMap.end())
  284. {
  285. auto listeners = listenerIter->second;
  286. for (auto& l : *listeners)
  287. {
  288. l->setPaused(false);
  289. }
  290. }
  291. for (auto& listener : _toAddedListeners)
  292. {
  293. if (listener->getAssociatedNode() == target)
  294. {
  295. listener->setPaused(false);
  296. }
  297. }
  298. setDirtyForNode(target);
  299. if (recursive)
  300. {
  301. const auto& children = target->getChildren();
  302. for (const auto& child : children)
  303. {
  304. resumeEventListenersForTarget(child, true);
  305. }
  306. }
  307. }
  308. void EventDispatcher::removeEventListenersForTarget(Node* target, bool recursive/* = false */)
  309. {
  310. // Ensure the node is removed from these immediately also.
  311. // Don't want any dangling pointers or the possibility of dealing with deleted objects..
  312. _nodePriorityMap.erase(target);
  313. _dirtyNodes.erase(target);
  314. auto listenerIter = _nodeListenersMap.find(target);
  315. if (listenerIter != _nodeListenersMap.end())
  316. {
  317. auto listeners = listenerIter->second;
  318. auto listenersCopy = *listeners;
  319. for (auto& l : listenersCopy)
  320. {
  321. removeEventListener(l);
  322. }
  323. }
  324. // Bug fix: ensure there are no references to the node in the list of listeners to be added.
  325. // If we find any listeners associated with the destroyed node in this list then remove them.
  326. // This is to catch the scenario where the node gets destroyed before it's listener
  327. // is added into the event dispatcher fully. This could happen if a node registers a listener
  328. // and gets destroyed while we are dispatching an event (touch etc.)
  329. for (auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end(); )
  330. {
  331. EventListener * listener = *iter;
  332. if (listener->getAssociatedNode() == target)
  333. {
  334. listener->setAssociatedNode(nullptr); // Ensure no dangling ptr to the target node.
  335. listener->setRegistered(false);
  336. releaseListener(listener);
  337. iter = _toAddedListeners.erase(iter);
  338. }
  339. else
  340. {
  341. ++iter;
  342. }
  343. }
  344. if (recursive)
  345. {
  346. const auto& children = target->getChildren();
  347. for (const auto& child : children)
  348. {
  349. removeEventListenersForTarget(child, true);
  350. }
  351. }
  352. }
  353. void EventDispatcher::associateNodeAndEventListener(Node* node, EventListener* listener)
  354. {
  355. std::vector<EventListener*>* listeners = nullptr;
  356. auto found = _nodeListenersMap.find(node);
  357. if (found != _nodeListenersMap.end())
  358. {
  359. listeners = found->second;
  360. }
  361. else
  362. {
  363. listeners = new (std::nothrow) std::vector<EventListener*>();
  364. _nodeListenersMap.emplace(node, listeners);
  365. }
  366. listeners->push_back(listener);
  367. }
  368. void EventDispatcher::dissociateNodeAndEventListener(Node* node, EventListener* listener)
  369. {
  370. std::vector<EventListener*>* listeners = nullptr;
  371. auto found = _nodeListenersMap.find(node);
  372. if (found != _nodeListenersMap.end())
  373. {
  374. listeners = found->second;
  375. auto iter = std::find(listeners->begin(), listeners->end(), listener);
  376. if (iter != listeners->end())
  377. {
  378. listeners->erase(iter);
  379. }
  380. if (listeners->empty())
  381. {
  382. _nodeListenersMap.erase(found);
  383. delete listeners;
  384. }
  385. }
  386. }
  387. void EventDispatcher::addEventListener(EventListener* listener)
  388. {
  389. if (_inDispatch == 0)
  390. {
  391. forceAddEventListener(listener);
  392. }
  393. else
  394. {
  395. _toAddedListeners.push_back(listener);
  396. }
  397. #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  398. auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
  399. if (sEngine)
  400. {
  401. sEngine->retainScriptObject(this, listener);
  402. }
  403. #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  404. listener->retain();
  405. }
  406. void EventDispatcher::forceAddEventListener(EventListener* listener)
  407. {
  408. EventListenerVector* listeners = nullptr;
  409. EventListener::ListenerID listenerID = listener->getListenerID();
  410. auto itr = _listenerMap.find(listenerID);
  411. if (itr == _listenerMap.end())
  412. {
  413. listeners = new (std::nothrow) EventListenerVector();
  414. _listenerMap.emplace(listenerID, listeners);
  415. }
  416. else
  417. {
  418. listeners = itr->second;
  419. }
  420. listeners->push_back(listener);
  421. if (listener->getFixedPriority() == 0)
  422. {
  423. setDirty(listenerID, DirtyFlag::SCENE_GRAPH_PRIORITY);
  424. auto node = listener->getAssociatedNode();
  425. CCASSERT(node != nullptr, "Invalid scene graph priority!");
  426. associateNodeAndEventListener(node, listener);
  427. if (!node->isRunning())
  428. {
  429. listener->setPaused(true);
  430. }
  431. }
  432. else
  433. {
  434. setDirty(listenerID, DirtyFlag::FIXED_PRIORITY);
  435. }
  436. }
  437. void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)
  438. {
  439. CCASSERT(listener && node, "Invalid parameters.");
  440. CCASSERT(!listener->isRegistered(), "The listener has been registered.");
  441. if (!listener->checkAvailable())
  442. return;
  443. listener->setAssociatedNode(node);
  444. listener->setFixedPriority(0);
  445. listener->setRegistered(true);
  446. addEventListener(listener);
  447. }
  448. #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS && COCOS2D_DEBUG > 0
  449. void EventDispatcher::debugCheckNodeHasNoEventListenersOnDestruction(Node* node)
  450. {
  451. // Check the listeners map
  452. for (const auto & keyValuePair : _listenerMap)
  453. {
  454. const EventListenerVector * eventListenerVector = keyValuePair.second;
  455. if (eventListenerVector)
  456. {
  457. if (eventListenerVector->getSceneGraphPriorityListeners())
  458. {
  459. for (EventListener * listener : *eventListenerVector->getSceneGraphPriorityListeners())
  460. {
  461. CCASSERT(!listener ||
  462. listener->getAssociatedNode() != node,
  463. "Node should have no event listeners registered for it upon destruction!");
  464. }
  465. }
  466. }
  467. }
  468. // Check the node listeners map
  469. for (const auto & keyValuePair : _nodeListenersMap)
  470. {
  471. CCASSERT(keyValuePair.first != node, "Node should have no event listeners registered for it upon destruction!");
  472. if (keyValuePair.second)
  473. {
  474. for (EventListener * listener : *keyValuePair.second)
  475. {
  476. CCASSERT(listener->getAssociatedNode() != node,
  477. "Node should have no event listeners registered for it upon destruction!");
  478. }
  479. }
  480. }
  481. // Check the node priority map
  482. for (const auto & keyValuePair : _nodePriorityMap)
  483. {
  484. CCASSERT(keyValuePair.first != node,
  485. "Node should have no event listeners registered for it upon destruction!");
  486. }
  487. // Check the to be added list
  488. for (EventListener * listener : _toAddedListeners)
  489. {
  490. CCASSERT(listener->getAssociatedNode() != node,
  491. "Node should have no event listeners registered for it upon destruction!");
  492. }
  493. // Check the dirty nodes set
  494. for (Node * dirtyNode : _dirtyNodes)
  495. {
  496. CCASSERT(dirtyNode != node,
  497. "Node should have no event listeners registered for it upon destruction!");
  498. }
  499. }
  500. #endif // #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS && COCOS2D_DEBUG > 0
  501. void EventDispatcher::addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority)
  502. {
  503. CCASSERT(listener, "Invalid parameters.");
  504. CCASSERT(!listener->isRegistered(), "The listener has been registered.");
  505. CCASSERT(fixedPriority != 0, "0 priority is forbidden for fixed priority since it's used for scene graph based priority.");
  506. if (!listener->checkAvailable())
  507. return;
  508. listener->setAssociatedNode(nullptr);
  509. listener->setFixedPriority(fixedPriority);
  510. listener->setRegistered(true);
  511. listener->setPaused(false);
  512. addEventListener(listener);
  513. }
  514. EventListenerCustom* EventDispatcher::addCustomEventListener(const std::string &eventName, const std::function<void(EventCustom*)>& callback)
  515. {
  516. EventListenerCustom *listener = EventListenerCustom::create(eventName, callback);
  517. addEventListenerWithFixedPriority(listener, 1);
  518. return listener;
  519. }
  520. void EventDispatcher::removeEventListener(EventListener* listener)
  521. {
  522. if (listener == nullptr)
  523. return;
  524. // just return if listener is in _toRemovedListeners to avoid remove listeners more than once
  525. if (std::find(_toRemovedListeners.begin(), _toRemovedListeners.end(), listener) != _toRemovedListeners.end())
  526. return;
  527. bool isFound = false;
  528. auto removeListenerInVector = [&](std::vector<EventListener*>* listeners){
  529. if (listeners == nullptr)
  530. return;
  531. for (auto iter = listeners->begin(); iter != listeners->end(); ++iter)
  532. {
  533. auto l = *iter;
  534. if (l == listener)
  535. {
  536. CC_SAFE_RETAIN(l);
  537. l->setRegistered(false);
  538. if (l->getAssociatedNode() != nullptr)
  539. {
  540. dissociateNodeAndEventListener(l->getAssociatedNode(), l);
  541. l->setAssociatedNode(nullptr); // nullptr out the node pointer so we don't have any dangling pointers to destroyed nodes.
  542. }
  543. if (_inDispatch == 0)
  544. {
  545. iter = listeners->erase(iter);
  546. releaseListener(l);
  547. }
  548. else
  549. {
  550. _toRemovedListeners.push_back(l);
  551. }
  552. isFound = true;
  553. break;
  554. }
  555. }
  556. };
  557. for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();)
  558. {
  559. auto listeners = iter->second;
  560. auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
  561. auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
  562. removeListenerInVector(sceneGraphPriorityListeners);
  563. if (isFound)
  564. {
  565. // fixed #4160: Dirty flag need to be updated after listeners were removed.
  566. setDirty(listener->getListenerID(), DirtyFlag::SCENE_GRAPH_PRIORITY);
  567. }
  568. else
  569. {
  570. removeListenerInVector(fixedPriorityListeners);
  571. if (isFound)
  572. {
  573. setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRIORITY);
  574. }
  575. }
  576. #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS
  577. CCASSERT(_inDispatch != 0 ||
  578. !sceneGraphPriorityListeners ||
  579. std::count(sceneGraphPriorityListeners->begin(), sceneGraphPriorityListeners->end(), listener) == 0,
  580. "Listener should be in no lists after this is done if we're not currently in dispatch mode.");
  581. CCASSERT(_inDispatch != 0 ||
  582. !fixedPriorityListeners ||
  583. std::count(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), listener) == 0,
  584. "Listener should be in no lists after this is done if we're not currently in dispatch mode.");
  585. #endif
  586. if (iter->second->empty())
  587. {
  588. _priorityDirtyFlagMap.erase(listener->getListenerID());
  589. auto list = iter->second;
  590. iter = _listenerMap.erase(iter);
  591. CC_SAFE_DELETE(list);
  592. }
  593. else
  594. {
  595. ++iter;
  596. }
  597. if (isFound)
  598. break;
  599. }
  600. if (isFound)
  601. {
  602. releaseListener(listener);
  603. }
  604. else
  605. {
  606. for(auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter)
  607. {
  608. if (*iter == listener)
  609. {
  610. listener->setRegistered(false);
  611. releaseListener(listener);
  612. _toAddedListeners.erase(iter);
  613. break;
  614. }
  615. }
  616. }
  617. }
  618. void EventDispatcher::setPriority(EventListener* listener, int fixedPriority)
  619. {
  620. if (listener == nullptr)
  621. return;
  622. for (auto& iter : _listenerMap)
  623. {
  624. auto fixedPriorityListeners = iter.second->getFixedPriorityListeners();
  625. if (fixedPriorityListeners)
  626. {
  627. auto found = std::find(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), listener);
  628. if (found != fixedPriorityListeners->end())
  629. {
  630. CCASSERT(listener->getAssociatedNode() == nullptr, "Can't set fixed priority with scene graph based listener.");
  631. if (listener->getFixedPriority() != fixedPriority)
  632. {
  633. listener->setFixedPriority(fixedPriority);
  634. setDirty(listener->getListenerID(), DirtyFlag::FIXED_PRIORITY);
  635. }
  636. return;
  637. }
  638. }
  639. }
  640. }
  641. void EventDispatcher::dispatchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent)
  642. {
  643. bool shouldStopPropagation = false;
  644. auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
  645. auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
  646. ssize_t i = 0;
  647. // priority < 0
  648. if (fixedPriorityListeners)
  649. {
  650. CCASSERT(listeners->getGt0Index() <= static_cast<ssize_t>(fixedPriorityListeners->size()), "Out of range exception!");
  651. if (!fixedPriorityListeners->empty())
  652. {
  653. for (; i < listeners->getGt0Index(); ++i)
  654. {
  655. auto l = fixedPriorityListeners->at(i);
  656. if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
  657. {
  658. shouldStopPropagation = true;
  659. break;
  660. }
  661. }
  662. }
  663. }
  664. if (sceneGraphPriorityListeners)
  665. {
  666. if (!shouldStopPropagation)
  667. {
  668. // priority == 0, scene graph priority
  669. for (auto& l : *sceneGraphPriorityListeners)
  670. {
  671. if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
  672. {
  673. shouldStopPropagation = true;
  674. break;
  675. }
  676. }
  677. }
  678. }
  679. if (fixedPriorityListeners)
  680. {
  681. if (!shouldStopPropagation)
  682. {
  683. // priority > 0
  684. ssize_t size = fixedPriorityListeners->size();
  685. for (; i < size; ++i)
  686. {
  687. auto l = fixedPriorityListeners->at(i);
  688. if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
  689. {
  690. shouldStopPropagation = true;
  691. break;
  692. }
  693. }
  694. }
  695. }
  696. }
  697. void EventDispatcher::dispatchTouchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent)
  698. {
  699. bool shouldStopPropagation = false;
  700. auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
  701. auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
  702. ssize_t i = 0;
  703. // priority < 0
  704. if (fixedPriorityListeners)
  705. {
  706. CCASSERT(listeners->getGt0Index() <= static_cast<ssize_t>(fixedPriorityListeners->size()), "Out of range exception!");
  707. if (!fixedPriorityListeners->empty())
  708. {
  709. for (; i < listeners->getGt0Index(); ++i)
  710. {
  711. auto l = fixedPriorityListeners->at(i);
  712. if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
  713. {
  714. shouldStopPropagation = true;
  715. break;
  716. }
  717. }
  718. }
  719. }
  720. auto scene = Director::getInstance()->getRunningScene();
  721. if (scene && sceneGraphPriorityListeners)
  722. {
  723. if (!shouldStopPropagation)
  724. {
  725. // priority == 0, scene graph priority
  726. // first, get all enabled, unPaused and registered listeners
  727. std::vector<EventListener*> sceneListeners;
  728. for (auto& l : *sceneGraphPriorityListeners)
  729. {
  730. if (l->isEnabled() && !l->isPaused() && l->isRegistered())
  731. {
  732. sceneListeners.push_back(l);
  733. }
  734. }
  735. // second, for all camera call all listeners
  736. // get a copy of cameras, prevent it's been modified in listener callback
  737. // if camera's depth is greater, process it earlier
  738. auto cameras = scene->getCameras();
  739. for (auto rit = cameras.rbegin(), ritRend = cameras.rend(); rit != ritRend; ++rit)
  740. {
  741. Camera* camera = *rit;
  742. if (camera->isVisible() == false)
  743. {
  744. continue;
  745. }
  746. Camera::_visitingCamera = camera;
  747. auto cameraFlag = (unsigned short)camera->getCameraFlag();
  748. for (auto& l : sceneListeners)
  749. {
  750. if (nullptr == l->getAssociatedNode() || 0 == (l->getAssociatedNode()->getCameraMask() & cameraFlag))
  751. {
  752. continue;
  753. }
  754. if (onEvent(l))
  755. {
  756. shouldStopPropagation = true;
  757. break;
  758. }
  759. }
  760. if (shouldStopPropagation)
  761. {
  762. break;
  763. }
  764. }
  765. Camera::_visitingCamera = nullptr;
  766. }
  767. }
  768. if (fixedPriorityListeners)
  769. {
  770. if (!shouldStopPropagation)
  771. {
  772. // priority > 0
  773. ssize_t size = fixedPriorityListeners->size();
  774. for (; i < size; ++i)
  775. {
  776. auto l = fixedPriorityListeners->at(i);
  777. if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))
  778. {
  779. shouldStopPropagation = true;
  780. break;
  781. }
  782. }
  783. }
  784. }
  785. }
  786. void EventDispatcher::dispatchEvent(Event* event)
  787. {
  788. if (!_isEnabled)
  789. return;
  790. updateDirtyFlagForSceneGraph();
  791. DispatchGuard guard(_inDispatch);
  792. if (event->getType() == Event::Type::TOUCH)
  793. {
  794. dispatchTouchEvent(static_cast<EventTouch*>(event));
  795. return;
  796. }
  797. auto listenerID = __getListenerID(event);
  798. sortEventListeners(listenerID);
  799. auto pfnDispatchEventToListeners = &EventDispatcher::dispatchEventToListeners;
  800. if (event->getType() == Event::Type::MOUSE) {
  801. pfnDispatchEventToListeners = &EventDispatcher::dispatchTouchEventToListeners;
  802. }
  803. auto iter = _listenerMap.find(listenerID);
  804. if (iter != _listenerMap.end())
  805. {
  806. auto listeners = iter->second;
  807. auto onEvent = [&event](EventListener* listener) -> bool{
  808. event->setCurrentTarget(listener->getAssociatedNode());
  809. listener->_onEvent(event);
  810. return event->isStopped();
  811. };
  812. (this->*pfnDispatchEventToListeners)(listeners, onEvent);
  813. }
  814. updateListeners(event);
  815. }
  816. void EventDispatcher::dispatchCustomEvent(const std::string &eventName, void *optionalUserData)
  817. {
  818. EventCustom ev(eventName);
  819. ev.setUserData(optionalUserData);
  820. dispatchEvent(&ev);
  821. }
  822. bool EventDispatcher::hasEventListener(const EventListener::ListenerID& listenerID) const
  823. {
  824. return getListeners(listenerID) != nullptr;
  825. }
  826. void EventDispatcher::dispatchTouchEvent(EventTouch* event)
  827. {
  828. sortEventListeners(EventListenerTouchOneByOne::LISTENER_ID);
  829. sortEventListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
  830. auto oneByOneListeners = getListeners(EventListenerTouchOneByOne::LISTENER_ID);
  831. auto allAtOnceListeners = getListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
  832. // If there aren't any touch listeners, return directly.
  833. if (nullptr == oneByOneListeners && nullptr == allAtOnceListeners)
  834. return;
  835. bool isNeedsMutableSet = (oneByOneListeners && allAtOnceListeners);
  836. const std::vector<Touch*>& originalTouches = event->getTouches();
  837. std::vector<Touch*> mutableTouches(originalTouches.size());
  838. std::copy(originalTouches.begin(), originalTouches.end(), mutableTouches.begin());
  839. //
  840. // process the target handlers 1st
  841. //
  842. if (oneByOneListeners)
  843. {
  844. auto mutableTouchesIter = mutableTouches.begin();
  845. for (auto& touches : originalTouches)
  846. {
  847. bool isSwallowed = false;
  848. auto onTouchEvent = [&](EventListener* l) -> bool { // Return true to break
  849. EventListenerTouchOneByOne* listener = static_cast<EventListenerTouchOneByOne*>(l);
  850. // Skip if the listener was removed.
  851. if (!listener->_isRegistered)
  852. return false;
  853. event->setCurrentTarget(listener->_node);
  854. bool isClaimed = false;
  855. std::vector<Touch*>::iterator removedIter;
  856. EventTouch::EventCode eventCode = event->getEventCode();
  857. if (eventCode == EventTouch::EventCode::BEGAN)
  858. {
  859. if (listener->onTouchBegan)
  860. {
  861. isClaimed = listener->onTouchBegan(touches, event);
  862. if (isClaimed && listener->_isRegistered)
  863. {
  864. listener->_claimedTouches.push_back(touches);
  865. }
  866. }
  867. }
  868. else if (listener->_claimedTouches.size() > 0
  869. && ((removedIter = std::find(listener->_claimedTouches.begin(), listener->_claimedTouches.end(), touches)) != listener->_claimedTouches.end()))
  870. {
  871. isClaimed = true;
  872. switch (eventCode)
  873. {
  874. case EventTouch::EventCode::MOVED:
  875. if (listener->onTouchMoved)
  876. {
  877. listener->onTouchMoved(touches, event);
  878. }
  879. break;
  880. case EventTouch::EventCode::ENDED:
  881. if (listener->onTouchEnded)
  882. {
  883. listener->onTouchEnded(touches, event);
  884. }
  885. if (listener->_isRegistered)
  886. {
  887. listener->_claimedTouches.erase(removedIter);
  888. }
  889. break;
  890. case EventTouch::EventCode::CANCELLED:
  891. if (listener->onTouchCancelled)
  892. {
  893. listener->onTouchCancelled(touches, event);
  894. }
  895. if (listener->_isRegistered)
  896. {
  897. listener->_claimedTouches.erase(removedIter);
  898. }
  899. break;
  900. default:
  901. CCASSERT(false, "The eventcode is invalid.");
  902. break;
  903. }
  904. }
  905. // If the event was stopped, return directly.
  906. if (event->isStopped())
  907. {
  908. updateListeners(event);
  909. return true;
  910. }
  911. CCASSERT(touches->getID() == (*mutableTouchesIter)->getID(),
  912. "touches ID should be equal to mutableTouchesIter's ID.");
  913. if (isClaimed && listener->_isRegistered && listener->_needSwallow)
  914. {
  915. if (isNeedsMutableSet)
  916. {
  917. mutableTouchesIter = mutableTouches.erase(mutableTouchesIter);
  918. isSwallowed = true;
  919. }
  920. return true;
  921. }
  922. return false;
  923. };
  924. //
  925. dispatchTouchEventToListeners(oneByOneListeners, onTouchEvent);
  926. if (event->isStopped())
  927. {
  928. return;
  929. }
  930. if (!isSwallowed)
  931. ++mutableTouchesIter;
  932. }
  933. }
  934. //
  935. // process standard handlers 2nd
  936. //
  937. if (allAtOnceListeners && mutableTouches.size() > 0)
  938. {
  939. auto onTouchesEvent = [&](EventListener* l) -> bool{
  940. EventListenerTouchAllAtOnce* listener = static_cast<EventListenerTouchAllAtOnce*>(l);
  941. // Skip if the listener was removed.
  942. if (!listener->_isRegistered)
  943. return false;
  944. event->setCurrentTarget(listener->_node);
  945. switch (event->getEventCode())
  946. {
  947. case EventTouch::EventCode::BEGAN:
  948. if (listener->onTouchesBegan)
  949. {
  950. listener->onTouchesBegan(mutableTouches, event);
  951. }
  952. break;
  953. case EventTouch::EventCode::MOVED:
  954. if (listener->onTouchesMoved)
  955. {
  956. listener->onTouchesMoved(mutableTouches, event);
  957. }
  958. break;
  959. case EventTouch::EventCode::ENDED:
  960. if (listener->onTouchesEnded)
  961. {
  962. listener->onTouchesEnded(mutableTouches, event);
  963. }
  964. break;
  965. case EventTouch::EventCode::CANCELLED:
  966. if (listener->onTouchesCancelled)
  967. {
  968. listener->onTouchesCancelled(mutableTouches, event);
  969. }
  970. break;
  971. default:
  972. CCASSERT(false, "The eventcode is invalid.");
  973. break;
  974. }
  975. // If the event was stopped, return directly.
  976. if (event->isStopped())
  977. {
  978. updateListeners(event);
  979. return true;
  980. }
  981. return false;
  982. };
  983. dispatchTouchEventToListeners(allAtOnceListeners, onTouchesEvent);
  984. if (event->isStopped())
  985. {
  986. return;
  987. }
  988. }
  989. updateListeners(event);
  990. }
  991. void EventDispatcher::updateListeners(Event* event)
  992. {
  993. CCASSERT(_inDispatch > 0, "If program goes here, there should be event in dispatch.");
  994. if (_inDispatch > 1)
  995. return;
  996. auto onUpdateListeners = [this](const EventListener::ListenerID& listenerID)
  997. {
  998. auto listenersIter = _listenerMap.find(listenerID);
  999. if (listenersIter == _listenerMap.end())
  1000. return;
  1001. auto listeners = listenersIter->second;
  1002. auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
  1003. auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
  1004. if (sceneGraphPriorityListeners)
  1005. {
  1006. for (auto iter = sceneGraphPriorityListeners->begin(); iter != sceneGraphPriorityListeners->end();)
  1007. {
  1008. auto l = *iter;
  1009. if (!l->isRegistered())
  1010. {
  1011. iter = sceneGraphPriorityListeners->erase(iter);
  1012. // if item in toRemove list, remove it from the list
  1013. auto matchIter = std::find(_toRemovedListeners.begin(), _toRemovedListeners.end(), l);
  1014. if (matchIter != _toRemovedListeners.end())
  1015. _toRemovedListeners.erase(matchIter);
  1016. releaseListener(l);
  1017. }
  1018. else
  1019. {
  1020. ++iter;
  1021. }
  1022. }
  1023. }
  1024. if (fixedPriorityListeners)
  1025. {
  1026. for (auto iter = fixedPriorityListeners->begin(); iter != fixedPriorityListeners->end();)
  1027. {
  1028. auto l = *iter;
  1029. if (!l->isRegistered())
  1030. {
  1031. iter = fixedPriorityListeners->erase(iter);
  1032. // if item in toRemove list, remove it from the list
  1033. auto matchIter = std::find(_toRemovedListeners.begin(), _toRemovedListeners.end(), l);
  1034. if (matchIter != _toRemovedListeners.end())
  1035. _toRemovedListeners.erase(matchIter);
  1036. releaseListener(l);
  1037. }
  1038. else
  1039. {
  1040. ++iter;
  1041. }
  1042. }
  1043. }
  1044. if (sceneGraphPriorityListeners && sceneGraphPriorityListeners->empty())
  1045. {
  1046. listeners->clearSceneGraphListeners();
  1047. }
  1048. if (fixedPriorityListeners && fixedPriorityListeners->empty())
  1049. {
  1050. listeners->clearFixedListeners();
  1051. }
  1052. };
  1053. if (event->getType() == Event::Type::TOUCH)
  1054. {
  1055. onUpdateListeners(EventListenerTouchOneByOne::LISTENER_ID);
  1056. onUpdateListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
  1057. }
  1058. else
  1059. {
  1060. onUpdateListeners(__getListenerID(event));
  1061. }
  1062. CCASSERT(_inDispatch == 1, "_inDispatch should be 1 here.");
  1063. for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();)
  1064. {
  1065. if (iter->second->empty())
  1066. {
  1067. _priorityDirtyFlagMap.erase(iter->first);
  1068. delete iter->second;
  1069. iter = _listenerMap.erase(iter);
  1070. }
  1071. else
  1072. {
  1073. ++iter;
  1074. }
  1075. }
  1076. if (!_toAddedListeners.empty())
  1077. {
  1078. for (auto& listener : _toAddedListeners)
  1079. {
  1080. forceAddEventListener(listener);
  1081. }
  1082. _toAddedListeners.clear();
  1083. }
  1084. if (!_toRemovedListeners.empty())
  1085. {
  1086. cleanToRemovedListeners();
  1087. }
  1088. }
  1089. void EventDispatcher::updateDirtyFlagForSceneGraph()
  1090. {
  1091. if (!_dirtyNodes.empty())
  1092. {
  1093. for (auto& node : _dirtyNodes)
  1094. {
  1095. auto iter = _nodeListenersMap.find(node);
  1096. if (iter != _nodeListenersMap.end())
  1097. {
  1098. for (auto& l : *iter->second)
  1099. {
  1100. setDirty(l->getListenerID(), DirtyFlag::SCENE_GRAPH_PRIORITY);
  1101. }
  1102. }
  1103. }
  1104. _dirtyNodes.clear();
  1105. }
  1106. }
  1107. void EventDispatcher::sortEventListeners(const EventListener::ListenerID& listenerID)
  1108. {
  1109. DirtyFlag dirtyFlag = DirtyFlag::NONE;
  1110. auto dirtyIter = _priorityDirtyFlagMap.find(listenerID);
  1111. if (dirtyIter != _priorityDirtyFlagMap.end())
  1112. {
  1113. dirtyFlag = dirtyIter->second;
  1114. }
  1115. if (dirtyFlag != DirtyFlag::NONE)
  1116. {
  1117. // Clear the dirty flag first, if `rootNode` is nullptr, then set its dirty flag of scene graph priority
  1118. dirtyIter->second = DirtyFlag::NONE;
  1119. if ((int)dirtyFlag & (int)DirtyFlag::FIXED_PRIORITY)
  1120. {
  1121. sortEventListenersOfFixedPriority(listenerID);
  1122. }
  1123. if ((int)dirtyFlag & (int)DirtyFlag::SCENE_GRAPH_PRIORITY)
  1124. {
  1125. auto rootNode = Director::getInstance()->getRunningScene();
  1126. if (rootNode)
  1127. {
  1128. sortEventListenersOfSceneGraphPriority(listenerID, rootNode);
  1129. }
  1130. else
  1131. {
  1132. dirtyIter->second = DirtyFlag::SCENE_GRAPH_PRIORITY;
  1133. }
  1134. }
  1135. }
  1136. }
  1137. void EventDispatcher::sortEventListenersOfSceneGraphPriority(const EventListener::ListenerID& listenerID, Node* rootNode)
  1138. {
  1139. auto listeners = getListeners(listenerID);
  1140. if (listeners == nullptr)
  1141. return;
  1142. auto sceneGraphListeners = listeners->getSceneGraphPriorityListeners();
  1143. if (sceneGraphListeners == nullptr)
  1144. return;
  1145. // Reset priority index
  1146. _nodePriorityIndex = 0;
  1147. _nodePriorityMap.clear();
  1148. visitTarget(rootNode, true);
  1149. // After sort: priority < 0, > 0
  1150. std::stable_sort(sceneGraphListeners->begin(), sceneGraphListeners->end(), [this](const EventListener* l1, const EventListener* l2) {
  1151. return _nodePriorityMap[l1->getAssociatedNode()] > _nodePriorityMap[l2->getAssociatedNode()];
  1152. });
  1153. #if DUMP_LISTENER_ITEM_PRIORITY_INFO
  1154. log("-----------------------------------");
  1155. for (auto& l : *sceneGraphListeners)
  1156. {
  1157. log("listener priority: node ([%s]%p), priority (%d)", typeid(*l->_node).name(), l->_node, _nodePriorityMap[l->_node]);
  1158. }
  1159. #endif
  1160. }
  1161. void EventDispatcher::sortEventListenersOfFixedPriority(const EventListener::ListenerID& listenerID)
  1162. {
  1163. auto listeners = getListeners(listenerID);
  1164. if (listeners == nullptr)
  1165. return;
  1166. auto fixedListeners = listeners->getFixedPriorityListeners();
  1167. if (fixedListeners == nullptr)
  1168. return;
  1169. // After sort: priority < 0, > 0
  1170. std::stable_sort(fixedListeners->begin(), fixedListeners->end(), [](const EventListener* l1, const EventListener* l2) {
  1171. return l1->getFixedPriority() < l2->getFixedPriority();
  1172. });
  1173. // FIXME: Should use binary search
  1174. int index = 0;
  1175. for (auto& listener : *fixedListeners)
  1176. {
  1177. if (listener->getFixedPriority() >= 0)
  1178. break;
  1179. ++index;
  1180. }
  1181. listeners->setGt0Index(index);
  1182. #if DUMP_LISTENER_ITEM_PRIORITY_INFO
  1183. log("-----------------------------------");
  1184. for (auto& l : *fixedListeners)
  1185. {
  1186. log("listener priority: node (%p), fixed (%d)", l->_node, l->_fixedPriority);
  1187. }
  1188. #endif
  1189. }
  1190. EventDispatcher::EventListenerVector* EventDispatcher::getListeners(const EventListener::ListenerID& listenerID) const
  1191. {
  1192. auto iter = _listenerMap.find(listenerID);
  1193. if (iter != _listenerMap.end())
  1194. {
  1195. return iter->second;
  1196. }
  1197. return nullptr;
  1198. }
  1199. void EventDispatcher::removeEventListenersForListenerID(const EventListener::ListenerID& listenerID)
  1200. {
  1201. auto listenerItemIter = _listenerMap.find(listenerID);
  1202. if (listenerItemIter != _listenerMap.end())
  1203. {
  1204. auto listeners = listenerItemIter->second;
  1205. auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
  1206. auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
  1207. auto removeAllListenersInVector = [&](std::vector<EventListener*>* listenerVector){
  1208. if (listenerVector == nullptr)
  1209. return;
  1210. for (auto iter = listenerVector->begin(); iter != listenerVector->end();)
  1211. {
  1212. auto l = *iter;
  1213. l->setRegistered(false);
  1214. if (l->getAssociatedNode() != nullptr)
  1215. {
  1216. dissociateNodeAndEventListener(l->getAssociatedNode(), l);
  1217. l->setAssociatedNode(nullptr); // nullptr out the node pointer so we don't have any dangling pointers to destroyed nodes.
  1218. }
  1219. if (_inDispatch == 0)
  1220. {
  1221. iter = listenerVector->erase(iter);
  1222. releaseListener(l);
  1223. }
  1224. else
  1225. {
  1226. ++iter;
  1227. }
  1228. }
  1229. };
  1230. removeAllListenersInVector(sceneGraphPriorityListeners);
  1231. removeAllListenersInVector(fixedPriorityListeners);
  1232. // Remove the dirty flag according the 'listenerID'.
  1233. // No need to check whether the dispatcher is dispatching event.
  1234. _priorityDirtyFlagMap.erase(listenerID);
  1235. if (!_inDispatch)
  1236. {
  1237. listeners->clear();
  1238. delete listeners;
  1239. _listenerMap.erase(listenerItemIter);
  1240. }
  1241. }
  1242. for (auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end();)
  1243. {
  1244. if ((*iter)->getListenerID() == listenerID)
  1245. {
  1246. (*iter)->setRegistered(false);
  1247. releaseListener(*iter);
  1248. iter = _toAddedListeners.erase(iter);
  1249. }
  1250. else
  1251. {
  1252. ++iter;
  1253. }
  1254. }
  1255. }
  1256. void EventDispatcher::removeEventListenersForType(EventListener::Type listenerType)
  1257. {
  1258. if (listenerType == EventListener::Type::TOUCH_ONE_BY_ONE)
  1259. {
  1260. removeEventListenersForListenerID(EventListenerTouchOneByOne::LISTENER_ID);
  1261. }
  1262. else if (listenerType == EventListener::Type::TOUCH_ALL_AT_ONCE)
  1263. {
  1264. removeEventListenersForListenerID(EventListenerTouchAllAtOnce::LISTENER_ID);
  1265. }
  1266. else if (listenerType == EventListener::Type::MOUSE)
  1267. {
  1268. removeEventListenersForListenerID(EventListenerMouse::LISTENER_ID);
  1269. }
  1270. else if (listenerType == EventListener::Type::ACCELERATION)
  1271. {
  1272. removeEventListenersForListenerID(EventListenerAcceleration::LISTENER_ID);
  1273. }
  1274. else if(listenerType == EventListener::Type::GYROSCOPE)
  1275. {
  1276. removeEventListenersForListenerID(EventListenerGyroscope::LISTENER_ID);
  1277. }
  1278. else if (listenerType == EventListener::Type::KEYBOARD)
  1279. {
  1280. removeEventListenersForListenerID(EventListenerKeyboard::LISTENER_ID);
  1281. }
  1282. else
  1283. {
  1284. CCASSERT(false, "Invalid listener type!");
  1285. }
  1286. }
  1287. void EventDispatcher::removeCustomEventListeners(const std::string& customEventName)
  1288. {
  1289. removeEventListenersForListenerID(customEventName);
  1290. }
  1291. void EventDispatcher::removeAllEventListeners()
  1292. {
  1293. bool cleanMap = true;
  1294. std::vector<EventListener::ListenerID> types;
  1295. types.reserve(_listenerMap.size());
  1296. for (const auto& e : _listenerMap)
  1297. {
  1298. if (_internalCustomListenerIDs.find(e.first) != _internalCustomListenerIDs.end())
  1299. {
  1300. cleanMap = false;
  1301. }
  1302. else
  1303. {
  1304. types.push_back(e.first);
  1305. }
  1306. }
  1307. for (const auto& type : types)
  1308. {
  1309. removeEventListenersForListenerID(type);
  1310. }
  1311. if (!_inDispatch && cleanMap)
  1312. {
  1313. _listenerMap.clear();
  1314. }
  1315. }
  1316. void EventDispatcher::setEnabled(bool isEnabled)
  1317. {
  1318. _isEnabled = isEnabled;
  1319. }
  1320. bool EventDispatcher::isEnabled() const
  1321. {
  1322. return _isEnabled;
  1323. }
  1324. void EventDispatcher::setDirtyForNode(Node* node)
  1325. {
  1326. // Mark the node dirty only when there is an eventlistener associated with it.
  1327. if (_nodeListenersMap.find(node) != _nodeListenersMap.end())
  1328. {
  1329. _dirtyNodes.insert(node);
  1330. }
  1331. // Also set the dirty flag for node's children
  1332. const auto& children = node->getChildren();
  1333. for (const auto& child : children)
  1334. {
  1335. setDirtyForNode(child);
  1336. }
  1337. }
  1338. void EventDispatcher::setDirty(const EventListener::ListenerID& listenerID, DirtyFlag flag)
  1339. {
  1340. auto iter = _priorityDirtyFlagMap.find(listenerID);
  1341. if (iter == _priorityDirtyFlagMap.end())
  1342. {
  1343. _priorityDirtyFlagMap.emplace(listenerID, flag);
  1344. }
  1345. else
  1346. {
  1347. int ret = (int)flag | (int)iter->second;
  1348. iter->second = (DirtyFlag) ret;
  1349. }
  1350. }
  1351. void EventDispatcher::cleanToRemovedListeners()
  1352. {
  1353. for (auto& l : _toRemovedListeners)
  1354. {
  1355. auto listenersIter = _listenerMap.find(l->getListenerID());
  1356. if (listenersIter == _listenerMap.end())
  1357. {
  1358. releaseListener(l);
  1359. continue;
  1360. }
  1361. bool find = false;
  1362. auto listeners = listenersIter->second;
  1363. auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
  1364. auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
  1365. if (sceneGraphPriorityListeners)
  1366. {
  1367. auto machedIter = std::find(sceneGraphPriorityListeners->begin(), sceneGraphPriorityListeners->end(), l);
  1368. if (machedIter != sceneGraphPriorityListeners->end())
  1369. {
  1370. find = true;
  1371. releaseListener(l);
  1372. sceneGraphPriorityListeners->erase(machedIter);
  1373. }
  1374. }
  1375. if (fixedPriorityListeners)
  1376. {
  1377. auto machedIter = std::find(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), l);
  1378. if (machedIter != fixedPriorityListeners->end())
  1379. {
  1380. find = true;
  1381. releaseListener(l);
  1382. fixedPriorityListeners->erase(machedIter);
  1383. }
  1384. }
  1385. if (find)
  1386. {
  1387. if (sceneGraphPriorityListeners && sceneGraphPriorityListeners->empty())
  1388. {
  1389. listeners->clearSceneGraphListeners();
  1390. }
  1391. if (fixedPriorityListeners && fixedPriorityListeners->empty())
  1392. {
  1393. listeners->clearFixedListeners();
  1394. }
  1395. }
  1396. else
  1397. CC_SAFE_RELEASE(l);
  1398. }
  1399. _toRemovedListeners.clear();
  1400. }
  1401. void EventDispatcher::releaseListener(EventListener* listener)
  1402. {
  1403. #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  1404. auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
  1405. if (listener && sEngine)
  1406. {
  1407. sEngine->releaseScriptObject(this, listener);
  1408. }
  1409. #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  1410. CC_SAFE_RELEASE(listener);
  1411. }
  1412. NS_CC_END