mirror of https://github.com/axmolengine/axmol.git
Merge pull request #6162 from dumganhar/pull/6160
Fixed a potential crash in EventDispatcher, based on PR #6160
This commit is contained in:
commit
c2b8557efb
|
@ -340,6 +340,27 @@ void EventDispatcher::removeEventListenersForTarget(Node* target, bool recursive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bug fix: ensure there are no references to the node in the list of listeners to be added.
|
||||||
|
// If we find any listeners associated with the destroyed node in this list then remove them.
|
||||||
|
// This is to catch the scenario where the node gets destroyed before it's listener
|
||||||
|
// is added into the event dispatcher fully. This could happen if a node registers a listener
|
||||||
|
// and gets destroyed while we are dispatching an event (touch etc.)
|
||||||
|
for (auto iter = _toAddedListeners.begin(); iter != _toAddedListeners.end(); )
|
||||||
|
{
|
||||||
|
EventListener * listener = *iter;
|
||||||
|
|
||||||
|
if (listener->getSceneGraphPriority() == target)
|
||||||
|
{
|
||||||
|
listener->setRegistered(false);
|
||||||
|
listener->release();
|
||||||
|
iter = _toAddedListeners.erase(iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (recursive)
|
if (recursive)
|
||||||
{
|
{
|
||||||
const auto& children = target->getChildren();
|
const auto& children = target->getChildren();
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "NewEventDispatcherTest.h"
|
#include "NewEventDispatcherTest.h"
|
||||||
#include "testResource.h"
|
#include "testResource.h"
|
||||||
|
#include "CCAutoreleasePool.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -27,7 +28,8 @@ std::function<Layer*()> createFunctions[] =
|
||||||
CL(PauseResumeTargetTest),
|
CL(PauseResumeTargetTest),
|
||||||
CL(Issue4129),
|
CL(Issue4129),
|
||||||
CL(Issue4160),
|
CL(Issue4160),
|
||||||
CL(DanglingNodePointersTest)
|
CL(DanglingNodePointersTest),
|
||||||
|
CL(RegisterAndUnregisterWhileEventHanldingTest)
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]);
|
unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]);
|
||||||
|
@ -1413,3 +1415,44 @@ std::string DanglingNodePointersTest::subtitle() const
|
||||||
"CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS == 1\n&& COCOS2D_DEBUG > 0";
|
"CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS == 1\n&& COCOS2D_DEBUG > 0";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RegisterAndUnregisterWhileEventHanldingTest::RegisterAndUnregisterWhileEventHanldingTest()
|
||||||
|
{
|
||||||
|
Point origin = Director::getInstance()->getVisibleOrigin();
|
||||||
|
Size size = Director::getInstance()->getVisibleSize();
|
||||||
|
|
||||||
|
auto callback1 = [=](DanglingNodePointersTestSprite * sprite)
|
||||||
|
{
|
||||||
|
auto callback2 = [](DanglingNodePointersTestSprite * sprite)
|
||||||
|
{
|
||||||
|
CCASSERT(false, "This should never get called!");
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
AutoreleasePool pool;
|
||||||
|
|
||||||
|
auto sprite2 = DanglingNodePointersTestSprite::create(callback2);
|
||||||
|
sprite2->setTexture("Images/CyanSquare.png");
|
||||||
|
sprite2->setPosition(origin+Point(size.width/2, size.height/2));
|
||||||
|
|
||||||
|
addChild(sprite2, 0);
|
||||||
|
removeChild(sprite2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto sprite1 = DanglingNodePointersTestSprite::create(callback1);
|
||||||
|
sprite1->setTexture("Images/CyanSquare.png");
|
||||||
|
sprite1->setPosition(origin+Point(size.width/2, size.height/2));
|
||||||
|
addChild(sprite1, -10);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RegisterAndUnregisterWhileEventHanldingTest::title() const
|
||||||
|
{
|
||||||
|
return "RegisterAndUnregisterWhileEventHanldingTest";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RegisterAndUnregisterWhileEventHanldingTest::subtitle() const
|
||||||
|
{
|
||||||
|
return "Tap the square multiple times - should not crash!";
|
||||||
|
}
|
||||||
|
|
|
@ -217,4 +217,14 @@ public:
|
||||||
virtual std::string subtitle() const override;
|
virtual std::string subtitle() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RegisterAndUnregisterWhileEventHanldingTest : public EventDispatcherTestDemo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CREATE_FUNC(RegisterAndUnregisterWhileEventHanldingTest);
|
||||||
|
RegisterAndUnregisterWhileEventHanldingTest();
|
||||||
|
|
||||||
|
virtual std::string title() const override;
|
||||||
|
virtual std::string subtitle() const override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* defined(__samples__NewEventDispatcherTest__) */
|
#endif /* defined(__samples__NewEventDispatcherTest__) */
|
||||||
|
|
Loading…
Reference in New Issue