From 7289ba2cc332269b38cbd6e0f599c1c0f15b3dfd Mon Sep 17 00:00:00 2001 From: Nimetu Date: Tue, 3 Nov 2015 01:06:12 +0200 Subject: [PATCH] Fixed: Crash in CWidgetManager::sendClockTickEvent when element removed from _ClockMsgTargets (issue #250) --- code/nel/include/nel/gui/widget_manager.h | 2 +- code/nel/src/gui/widget_manager.cpp | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 6d2336047..c30bdd663 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -569,7 +569,7 @@ namespace NLGUI std::vector< CInterfaceGroup* > _GroupsUnderPointer; // view that should be notified from clock msg - std::vector _ClockMsgTargets; + std::list _ClockMsgTargets; NLMISC::CRGBA _GlobalColor; NLMISC::CRGBA _GlobalColorForContent; diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index b9efd50d5..d57658571 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2866,17 +2866,19 @@ namespace NLGUI void CWidgetManager::unregisterClockMsgTarget(CCtrlBase *vb) { if (!vb) return; - std::vector::iterator it = std::find(_ClockMsgTargets.begin(), _ClockMsgTargets.end(), vb); + std::list::iterator it = std::find(_ClockMsgTargets.begin(), _ClockMsgTargets.end(), vb); if (it != _ClockMsgTargets.end()) { - _ClockMsgTargets.erase(it); + // instead of deleting, just mark as deleted incase we are inside iterating loop, + // it will be removed in sendClockTickEvent + (*it) = NULL; } } // *************************************************************************** bool CWidgetManager::isClockMsgTarget(CCtrlBase *vb) const { - std::vector::const_iterator it = std::find(_ClockMsgTargets.begin(), _ClockMsgTargets.end(), vb); + std::list::const_iterator it = std::find(_ClockMsgTargets.begin(), _ClockMsgTargets.end(), vb); return it != _ClockMsgTargets.end(); } @@ -2895,10 +2897,16 @@ namespace NLGUI } // and send clock tick msg to ctrl that are registered - std::vector clockMsgTarget = _ClockMsgTargets; - for(std::vector::iterator it = clockMsgTarget.begin(); it != clockMsgTarget.end(); ++it) + for(std::list::iterator it = _ClockMsgTargets.begin(); it != _ClockMsgTargets.end();) { - (*it)->handleEvent(clockTick); + CCtrlBase* ctrl = *it; + if (ctrl) + { + ctrl->handleEvent(clockTick); + ++it; + } + else + it = _ClockMsgTargets.erase(it); } }