Merge pull request #9963 from Dhilan007/v3-issue9898-fix

Fixed crash if dispatch event after remove event listener in callback
This commit is contained in:
minggo 2015-01-14 10:59:42 +08:00
commit d320941ca1
3 changed files with 52 additions and 6 deletions

View File

@ -1024,7 +1024,10 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event)
void EventDispatcher::updateListeners(Event* event) void EventDispatcher::updateListeners(Event* event)
{ {
CCASSERT(_inDispatch > 0, "If program goes here, there should be event in dispatch."); 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 onUpdateListeners = [this](const EventListener::ListenerID& listenerID)
{ {
auto listenersIter = _listenerMap.find(listenerID); auto listenersIter = _listenerMap.find(listenerID);
@ -1081,7 +1084,6 @@ void EventDispatcher::updateListeners(Event* event)
} }
}; };
if (event->getType() == Event::Type::TOUCH) if (event->getType() == Event::Type::TOUCH)
{ {
onUpdateListeners(EventListenerTouchOneByOne::LISTENER_ID); onUpdateListeners(EventListenerTouchOneByOne::LISTENER_ID);
@ -1092,9 +1094,6 @@ void EventDispatcher::updateListeners(Event* event)
onUpdateListeners(__getListenerID(event)); onUpdateListeners(__getListenerID(event));
} }
if (_inDispatch > 1)
return;
CCASSERT(_inDispatch == 1, "_inDispatch should be 1 here."); CCASSERT(_inDispatch == 1, "_inDispatch should be 1 here.");
for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();) for (auto iter = _listenerMap.begin(); iter != _listenerMap.end();)

View File

@ -28,7 +28,8 @@ std::function<Layer*()> createFunctions[] =
CL(Issue4129), CL(Issue4129),
CL(Issue4160), CL(Issue4160),
CL(DanglingNodePointersTest), CL(DanglingNodePointersTest),
CL(RegisterAndUnregisterWhileEventHanldingTest) CL(RegisterAndUnregisterWhileEventHanldingTest),
CL(Issue9898)
}; };
unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]); 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!"; 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";
}

View File

@ -227,4 +227,17 @@ public:
virtual std::string subtitle() const override; 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__) */ #endif /* defined(__samples__NewEventDispatcherTest__) */