In EventDispatcher::updateListeners(), unregistered event listeners are being removed from the _listenerMap without the appropriate dirty flags being set. This can cause a crash when event listeners are removed, but the affected priority list not subsequently sorted.
The fix is to add two calls to setDirty(). This problem is observed in version 3.8.1.
Current code:
if (sceneGraphPriorityListeners)
{
for (auto iter = sceneGraphPriorityListeners->begin(); iter != sceneGraphPriorityListeners->end();)
{
auto l = *iter;
if (!l->isRegistered())
{
iter = sceneGraphPriorityListeners->erase(iter);
l->release();
}
else
{
++iter;
}
}
}
if (fixedPriorityListeners)
{
for (auto iter = fixedPriorityListeners->begin(); iter != fixedPriorityListeners->end();)
{
auto l = *iter;
if (!l->isRegistered())
{
iter = fixedPriorityListeners->erase(iter);
l->release();
}
else
{
++iter;
}
}
}
Fixed code:
if (sceneGraphPriorityListeners)
{
for (auto iter = sceneGraphPriorityListeners->begin(); iter != sceneGraphPriorityListeners->end();)
{
auto l = *iter;
if (!l->isRegistered())
{
iter = sceneGraphPriorityListeners->erase(iter);
l->release();
setDirty(listenerID, DirtyFlag::SCENE_GRAPH_PRIORITY);
}
else
{
++iter;
}
}
}
if (fixedPriorityListeners)
{
for (auto iter = fixedPriorityListeners->begin(); iter != fixedPriorityListeners->end();)
{
auto l = *iter;
if (!l->isRegistered())
{
iter = fixedPriorityListeners->erase(iter);
l->release();
setDirty(listenerID, DirtyFlag::FIXED_PRIORITY);
}
else
{
++iter;
}
}
}