mirror of https://github.com/axmolengine/axmol.git
Merge pull request #14184 from xiaofeng11/v3_xf
Fix EventListenerCustom registered by UILabel never has been released bug
This commit is contained in:
commit
f4a2a53f6d
|
@ -204,6 +204,7 @@ EventDispatcher::EventDispatcher()
|
|||
, _nodePriorityIndex(0)
|
||||
{
|
||||
_toAddedListeners.reserve(50);
|
||||
_toRemovedListeners.reserve(50);
|
||||
|
||||
// fixed #4129: Mark the following listener IDs for internal use.
|
||||
// Therefore, internal listeners would not be cleaned when removeAllEventListeners is invoked.
|
||||
|
@ -619,9 +620,13 @@ void EventDispatcher::removeEventListener(EventListener* listener)
|
|||
|
||||
if (_inDispatch == 0)
|
||||
{
|
||||
listeners->erase(iter);
|
||||
iter = listeners->erase(iter);
|
||||
CC_SAFE_RELEASE(l);
|
||||
}
|
||||
else
|
||||
{
|
||||
_toRemovedListeners.push_back(l);
|
||||
}
|
||||
|
||||
isFound = true;
|
||||
break;
|
||||
|
@ -1152,6 +1157,10 @@ void EventDispatcher::updateListeners(Event* event)
|
|||
if (!l->isRegistered())
|
||||
{
|
||||
iter = sceneGraphPriorityListeners->erase(iter);
|
||||
// if item in toRemove list, remove it from the list
|
||||
auto matchIter = std::find(_toRemovedListeners.begin(), _toRemovedListeners.end(), l);
|
||||
if (matchIter != _toRemovedListeners.end())
|
||||
_toRemovedListeners.erase(matchIter);
|
||||
l->release();
|
||||
}
|
||||
else
|
||||
|
@ -1169,6 +1178,10 @@ void EventDispatcher::updateListeners(Event* event)
|
|||
if (!l->isRegistered())
|
||||
{
|
||||
iter = fixedPriorityListeners->erase(iter);
|
||||
// if item in toRemove list, remove it from the list
|
||||
auto matchIter = std::find(_toRemovedListeners.begin(), _toRemovedListeners.end(), l);
|
||||
if (matchIter != _toRemovedListeners.end())
|
||||
_toRemovedListeners.erase(matchIter);
|
||||
l->release();
|
||||
}
|
||||
else
|
||||
|
@ -1223,6 +1236,11 @@ void EventDispatcher::updateListeners(Event* event)
|
|||
}
|
||||
_toAddedListeners.clear();
|
||||
}
|
||||
|
||||
if (!_toRemovedListeners.empty())
|
||||
{
|
||||
cleanToRemovedListeners();
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::updateDirtyFlagForSceneGraph()
|
||||
|
@ -1525,4 +1543,61 @@ void EventDispatcher::setDirty(const EventListener::ListenerID& listenerID, Dirt
|
|||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::cleanToRemovedListeners()
|
||||
{
|
||||
for (auto& l : _toRemovedListeners)
|
||||
{
|
||||
auto listenersIter = _listenerMap.find(l->getListenerID());
|
||||
if (listenersIter == _listenerMap.end())
|
||||
{
|
||||
CC_SAFE_RELEASE(l);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool find = false;
|
||||
auto listeners = listenersIter->second;
|
||||
auto fixedPriorityListeners = listeners->getFixedPriorityListeners();
|
||||
auto sceneGraphPriorityListeners = listeners->getSceneGraphPriorityListeners();
|
||||
|
||||
if (sceneGraphPriorityListeners)
|
||||
{
|
||||
auto machedIter = std::find(sceneGraphPriorityListeners->begin(), sceneGraphPriorityListeners->end(), l);
|
||||
if (machedIter != sceneGraphPriorityListeners->end())
|
||||
{
|
||||
find = true;
|
||||
CC_SAFE_RELEASE(l);
|
||||
sceneGraphPriorityListeners->erase(machedIter);
|
||||
}
|
||||
}
|
||||
|
||||
if (fixedPriorityListeners)
|
||||
{
|
||||
auto machedIter = std::find(fixedPriorityListeners->begin(), fixedPriorityListeners->end(), l);
|
||||
if (machedIter != fixedPriorityListeners->end())
|
||||
{
|
||||
find = true;
|
||||
CC_SAFE_RELEASE(l);
|
||||
fixedPriorityListeners->erase(machedIter);
|
||||
}
|
||||
}
|
||||
|
||||
if (find)
|
||||
{
|
||||
if (sceneGraphPriorityListeners && sceneGraphPriorityListeners->empty())
|
||||
{
|
||||
listeners->clearSceneGraphListeners();
|
||||
}
|
||||
|
||||
if (fixedPriorityListeners && fixedPriorityListeners->empty())
|
||||
{
|
||||
listeners->clearFixedListeners();
|
||||
}
|
||||
}
|
||||
else
|
||||
CC_SAFE_RELEASE(l);
|
||||
}
|
||||
|
||||
_toRemovedListeners.clear();
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -300,7 +300,10 @@ protected:
|
|||
|
||||
/** Walks though scene graph to get the draw order for each node, it's called before sorting event listener with scene graph priority */
|
||||
void visitTarget(Node* node, bool isRootNode);
|
||||
|
||||
|
||||
/** Remove all listeners in _toRemoveListeners list and cleanup */
|
||||
void cleanToRemovedListeners();
|
||||
|
||||
/** Listeners map */
|
||||
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listenerMap;
|
||||
|
||||
|
@ -318,7 +321,10 @@ protected:
|
|||
|
||||
/** The listeners to be added after dispatching event */
|
||||
std::vector<EventListener*> _toAddedListeners;
|
||||
|
||||
|
||||
/** The listeners to be removed after dispatching event */
|
||||
std::vector<EventListener*> _toRemovedListeners;
|
||||
|
||||
/** The nodes were associated with scene graph based priority listeners */
|
||||
std::set<Node*> _dirtyNodes;
|
||||
|
||||
|
|
Loading…
Reference in New Issue