Fixed: Crash in CWidgetManager::sendClockTickEvent when element removed from _ClockMsgTargets (issue #250)

This commit is contained in:
Nimetu 2015-11-03 01:06:12 +02:00
parent 2d170378ab
commit 97754b7af1
2 changed files with 15 additions and 7 deletions

View file

@ -569,7 +569,7 @@ namespace NLGUI
std::vector< CInterfaceGroup* > _GroupsUnderPointer; std::vector< CInterfaceGroup* > _GroupsUnderPointer;
// view that should be notified from clock msg // view that should be notified from clock msg
std::vector<CCtrlBase*> _ClockMsgTargets; std::list<CCtrlBase*> _ClockMsgTargets;
NLMISC::CRGBA _GlobalColor; NLMISC::CRGBA _GlobalColor;
NLMISC::CRGBA _GlobalColorForContent; NLMISC::CRGBA _GlobalColorForContent;

View file

@ -2866,17 +2866,19 @@ namespace NLGUI
void CWidgetManager::unregisterClockMsgTarget(CCtrlBase *vb) void CWidgetManager::unregisterClockMsgTarget(CCtrlBase *vb)
{ {
if (!vb) return; if (!vb) return;
std::vector<CCtrlBase*>::iterator it = std::find(_ClockMsgTargets.begin(), _ClockMsgTargets.end(), vb); std::list<CCtrlBase*>::iterator it = std::find(_ClockMsgTargets.begin(), _ClockMsgTargets.end(), vb);
if (it != _ClockMsgTargets.end()) 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 bool CWidgetManager::isClockMsgTarget(CCtrlBase *vb) const
{ {
std::vector<CCtrlBase*>::const_iterator it = std::find(_ClockMsgTargets.begin(), _ClockMsgTargets.end(), vb); std::list<CCtrlBase*>::const_iterator it = std::find(_ClockMsgTargets.begin(), _ClockMsgTargets.end(), vb);
return it != _ClockMsgTargets.end(); return it != _ClockMsgTargets.end();
} }
@ -2895,10 +2897,16 @@ namespace NLGUI
} }
// and send clock tick msg to ctrl that are registered // and send clock tick msg to ctrl that are registered
std::vector<CCtrlBase*> clockMsgTarget = _ClockMsgTargets; for(std::list<CCtrlBase*>::iterator it = _ClockMsgTargets.begin(); it != _ClockMsgTargets.end();)
for(std::vector<CCtrlBase*>::iterator it = clockMsgTarget.begin(); it != clockMsgTarget.end(); ++it)
{ {
(*it)->handleEvent(clockTick); CCtrlBase* ctrl = *it;
if (ctrl)
{
ctrl->handleEvent(clockTick);
++it;
}
else
it = _ClockMsgTargets.erase(it);
} }
} }