From 06f166f613efb7611b6d06c94925f982724d072c Mon Sep 17 00:00:00 2001 From: psi Date: Sat, 2 Nov 2013 16:03:54 +0900 Subject: [PATCH 1/4] why not search _toAddedListeners?? --- cocos/2d/CCEventDispatcher.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index 14be190f68..1159bba86e 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -212,9 +212,16 @@ void EventDispatcher::removeEventListener(EventListener* listener) break; } - if (isFound) - { + if (isFound) { CC_SAFE_RELEASE(listener); + } else { + for(auto iter=_toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter) { + if ((*iter)->listener == listener) + { + _toAddedListeners.erase(iter); + break; + } + } } } From 7dc6513687c4f6992087060f7ca532a0bd4f5be6 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 21:47:00 +0800 Subject: [PATCH 2/4] Adding more tests for EventDispatcherTest. --- .../NewEventDispatcherTest.cpp | 87 ++++++++++++++++++- .../NewEventDispatcherTest.h | 9 ++ 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index bbc041c70b..5f06e0c9ed 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -19,7 +19,8 @@ std::function createFunctions[] = CL(CustomEventTest), CL(LabelKeyboardEventTest), CL(SpriteAccelerationEventTest), - CL(RemoveAndRetainNodeTest) + CL(RemoveAndRetainNodeTest), + CL(RemoveListenerAfterAddingTest) }; unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]); @@ -665,4 +666,86 @@ std::string RemoveAndRetainNodeTest::title() std::string RemoveAndRetainNodeTest::subtitle() { return "Sprite should be removed after 5s, add to scene again after 5s"; -} \ No newline at end of file +} + +//RemoveListenerAfterAddingTest +void RemoveListenerAfterAddingTest::onEnter() +{ + EventDispatcherTestDemo::onEnter(); + + auto item1 = MenuItemFont::create("Click Me 1", [this](Object* sender){ + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = [](Touch* touch, Event* event) -> bool{ + CCASSERT(false, "Should not come here!"); + return true; + }; + + _eventDispatcher->addEventListenerWithFixedPriority(listener, -1); + _eventDispatcher->removeEventListener(listener); + }); + + item1->setPosition(VisibleRect::center() + Point(0, 80)); + + auto addNextButton = [this](){ + auto next = MenuItemFont::create("Please Click Me To Reset!"); + next->setPosition(VisibleRect::center() + Point(0, -40)); + + auto menu = Menu::create(next, nullptr); + menu->setPosition(VisibleRect::leftBottom()); + menu->setAnchorPoint(Point::ZERO); + this->addChild(menu); + }; + + auto item2 = MenuItemFont::create("Click Me 2", [=](Object* sender){ + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = [](Touch* touch, Event* event) -> bool{ + CCASSERT(false, "Should not come here!"); + return true; + }; + + _eventDispatcher->addEventListenerWithFixedPriority(listener, -1); + _eventDispatcher->removeEventListeners(EventListener::Type::TOUCH_ONE_BY_ONE); + + addNextButton(); + }); + + item2->setPosition(VisibleRect::center() + Point(0, 40)); + + auto item3 = MenuItemFont::create("Click Me 3", [=](Object* sender){ + auto listener = EventListenerTouchOneByOne::create(); + listener->onTouchBegan = [](Touch* touch, Event* event) -> bool{ + CCASSERT(false, "Should not come here!"); + return true; + }; + + _eventDispatcher->addEventListenerWithFixedPriority(listener, -1); + _eventDispatcher->removeAllEventListeners(); + + addNextButton(); + }); + + item3->setPosition(VisibleRect::center()); + + auto menu = Menu::create(item1, item2, item3, nullptr); + menu->setPosition(VisibleRect::leftBottom()); + menu->setAnchorPoint(Point::ZERO); + + addChild(menu); +} + +void RemoveListenerAfterAddingTest::onExit() +{ + EventDispatcherTestDemo::onExit(); +} + +std::string RemoveListenerAfterAddingTest::title() +{ + return "RemoveListenerAfterAddingTest"; +} + +std::string RemoveListenerAfterAddingTest::subtitle() +{ + return "Should not crash!"; +} + + diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h index 080e623008..529813e7b8 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h @@ -96,4 +96,13 @@ private: bool _spriteSaved; }; +class RemoveListenerAfterAddingTest : public EventDispatcherTestDemo +{ +public: + virtual void onEnter() override; + virtual void onExit() override; + virtual std::string title() override; + virtual std::string subtitle() override; +}; + #endif /* defined(__samples__NewEventDispatcherTest__) */ From 8f213420ebee44f6a871d70c042da3af7068f293 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 22:05:04 +0800 Subject: [PATCH 3/4] closed #3106: Update NewEventDispatcherTest.cpp. --- .../Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index 5f06e0c9ed..1828dbb03d 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -687,7 +687,9 @@ void RemoveListenerAfterAddingTest::onEnter() item1->setPosition(VisibleRect::center() + Point(0, 80)); auto addNextButton = [this](){ - auto next = MenuItemFont::create("Please Click Me To Reset!"); + auto next = MenuItemFont::create("Please Click Me To Reset!", [this](Object* sender){ + this->restartCallback(nullptr); + }); next->setPosition(VisibleRect::center() + Point(0, -40)); auto menu = Menu::create(next, nullptr); From fd21e3ea38682352cb274bff902b9128b2c948ad Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 2 Nov 2013 22:08:08 +0800 Subject: [PATCH 4/4] closed #3106: fixed: EventListeners can't be removed sometimes. --- cocos/2d/CCEventDispatcher.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/cocos/2d/CCEventDispatcher.cpp b/cocos/2d/CCEventDispatcher.cpp index e4be089f7d..0b9f4d042d 100644 --- a/cocos/2d/CCEventDispatcher.cpp +++ b/cocos/2d/CCEventDispatcher.cpp @@ -442,11 +442,15 @@ void EventDispatcher::removeEventListener(EventListener* listener) break; } - if (isFound) { + if (isFound) + { CC_SAFE_RELEASE(listener); - } else { - for(auto iter=_toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter) { - if ((*iter)->listener == listener) + } + else + { + for(auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end(); ++iter) + { + if (*iter == listener) { _toAddedListeners.erase(iter); break; @@ -1048,6 +1052,18 @@ void EventDispatcher::removeEventListenersForListenerID(EventListener::ListenerI _priorityDirtyFlagMap.erase(listenerID); } } + + for(auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end();) + { + if ((*iter)->getListenerID() == listenerID) + { + iter = _toAddedListeners.erase(iter); + } + else + { + ++iter; + } + } } void EventDispatcher::removeEventListeners(EventListener::Type listenerType)