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();) 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__) */