From de645a7c9c53181b7745c29b38d08f9e58ecff5f Mon Sep 17 00:00:00 2001 From: WenhaiLin Date: Tue, 13 Jan 2015 18:35:32 +0800 Subject: [PATCH 1/2] Fixed crash if dispatch event after remove event listener in callback --- cocos/base/CCEventDispatcher.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cocos/base/CCEventDispatcher.cpp b/cocos/base/CCEventDispatcher.cpp index 6ca69ed9a2..10798145ee 100644 --- a/cocos/base/CCEventDispatcher.cpp +++ b/cocos/base/CCEventDispatcher.cpp @@ -1024,7 +1024,10 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event) void EventDispatcher::updateListeners(Event* event) { CCASSERT(_inDispatch > 0, "If program goes here, there should be event in dispatch."); - + + if (_inDispatch > 1) + return; + auto onUpdateListeners = [this](const EventListener::ListenerID& listenerID) { auto listenersIter = _listenerMap.find(listenerID); @@ -1081,7 +1084,6 @@ void EventDispatcher::updateListeners(Event* event) } }; - if (event->getType() == Event::Type::TOUCH) { onUpdateListeners(EventListenerTouchOneByOne::LISTENER_ID); @@ -1092,9 +1094,6 @@ void EventDispatcher::updateListeners(Event* event) onUpdateListeners(__getListenerID(event)); } - if (_inDispatch > 1) - return; - CCASSERT(_inDispatch == 1, "_inDispatch should be 1 here."); for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();) From 13481ea5c2959f7c2d5c55a4d3969acfbe7b61ff Mon Sep 17 00:00:00 2001 From: WenhaiLin Date: Tue, 13 Jan 2015 18:37:45 +0800 Subject: [PATCH 2/2] Add test case for issue#9898 --- .../NewEventDispatcherTest.cpp | 36 ++++++++++++++++++- .../NewEventDispatcherTest.h | 13 +++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index 572fb7f3e8..a6b0532442 100644 --- a/tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -28,7 +28,8 @@ std::function createFunctions[] = CL(Issue4129), CL(Issue4160), CL(DanglingNodePointersTest), - CL(RegisterAndUnregisterWhileEventHanldingTest) + CL(RegisterAndUnregisterWhileEventHanldingTest), + CL(Issue9898) }; unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]); @@ -1454,3 +1455,36 @@ std::string RegisterAndUnregisterWhileEventHanldingTest::subtitle() const { return "Tap the square multiple times - should not crash!"; } + +Issue9898::Issue9898() +{ + auto origin = Director::getInstance()->getVisibleOrigin(); + auto size = Director::getInstance()->getVisibleSize(); + + auto nodeA = Node::create(); + addChild(nodeA); + + _listener = cocos2d::EventListenerCustom::create("Issue9898", [&](cocos2d::EventCustom *event){ + _eventDispatcher->removeEventListener(_listener); + _eventDispatcher->dispatchCustomEvent("Issue9898"); + }); + _eventDispatcher->addEventListenerWithSceneGraphPriority(_listener, nodeA); + + auto menuItem = MenuItemFont::create("Dispatch Custom Event", [&](Ref *sender) { + _eventDispatcher->dispatchCustomEvent("Issue9898"); + }); + menuItem->setPosition(origin.x + size.width/2, origin.y + size.height/2); + auto menu = Menu::create(menuItem, nullptr); + menu->setPosition(Vec2::ZERO); + addChild(menu); +} + +std::string Issue9898::title() const +{ + return ""; +} + +std::string Issue9898::subtitle() const +{ + return "Should not crash if dispatch event after remove\n event listener in callback"; +} diff --git a/tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h b/tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h index 8118f2619e..a6bc7e0a0a 100644 --- a/tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h +++ b/tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h @@ -227,4 +227,17 @@ public: virtual std::string subtitle() const override; }; +class Issue9898 : public EventDispatcherTestDemo +{ +public: + CREATE_FUNC(Issue9898); + Issue9898(); + + virtual std::string title() const override; + virtual std::string subtitle() const override; + +private: + EventListenerCustom* _listener; +}; + #endif /* defined(__samples__NewEventDispatcherTest__) */