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)
|
, _nodePriorityIndex(0)
|
||||||
{
|
{
|
||||||
_toAddedListeners.reserve(50);
|
_toAddedListeners.reserve(50);
|
||||||
|
_toRemovedListeners.reserve(50);
|
||||||
|
|
||||||
// fixed #4129: Mark the following listener IDs for internal use.
|
// fixed #4129: Mark the following listener IDs for internal use.
|
||||||
// Therefore, internal listeners would not be cleaned when removeAllEventListeners is invoked.
|
// Therefore, internal listeners would not be cleaned when removeAllEventListeners is invoked.
|
||||||
|
@ -619,9 +620,13 @@ void EventDispatcher::removeEventListener(EventListener* listener)
|
||||||
|
|
||||||
if (_inDispatch == 0)
|
if (_inDispatch == 0)
|
||||||
{
|
{
|
||||||
listeners->erase(iter);
|
iter = listeners->erase(iter);
|
||||||
CC_SAFE_RELEASE(l);
|
CC_SAFE_RELEASE(l);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_toRemovedListeners.push_back(l);
|
||||||
|
}
|
||||||
|
|
||||||
isFound = true;
|
isFound = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1152,6 +1157,10 @@ void EventDispatcher::updateListeners(Event* event)
|
||||||
if (!l->isRegistered())
|
if (!l->isRegistered())
|
||||||
{
|
{
|
||||||
iter = sceneGraphPriorityListeners->erase(iter);
|
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();
|
l->release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1169,6 +1178,10 @@ void EventDispatcher::updateListeners(Event* event)
|
||||||
if (!l->isRegistered())
|
if (!l->isRegistered())
|
||||||
{
|
{
|
||||||
iter = fixedPriorityListeners->erase(iter);
|
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();
|
l->release();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1223,6 +1236,11 @@ void EventDispatcher::updateListeners(Event* event)
|
||||||
}
|
}
|
||||||
_toAddedListeners.clear();
|
_toAddedListeners.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_toRemovedListeners.empty())
|
||||||
|
{
|
||||||
|
cleanToRemovedListeners();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventDispatcher::updateDirtyFlagForSceneGraph()
|
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
|
NS_CC_END
|
||||||
|
|
|
@ -301,6 +301,9 @@ protected:
|
||||||
/** Walks though scene graph to get the draw order for each node, it's called before sorting event listener with scene graph priority */
|
/** 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);
|
void visitTarget(Node* node, bool isRootNode);
|
||||||
|
|
||||||
|
/** Remove all listeners in _toRemoveListeners list and cleanup */
|
||||||
|
void cleanToRemovedListeners();
|
||||||
|
|
||||||
/** Listeners map */
|
/** Listeners map */
|
||||||
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listenerMap;
|
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listenerMap;
|
||||||
|
|
||||||
|
@ -319,6 +322,9 @@ protected:
|
||||||
/** The listeners to be added after dispatching event */
|
/** The listeners to be added after dispatching event */
|
||||||
std::vector<EventListener*> _toAddedListeners;
|
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 */
|
/** The nodes were associated with scene graph based priority listeners */
|
||||||
std::set<Node*> _dirtyNodes;
|
std::set<Node*> _dirtyNodes;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue