diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index f40cdc3600..8639e57c7b 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -489,9 +489,11 @@ optional TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool, void TOOL_MANAGER::dispatchInternal( const TOOL_EVENT& aEvent ) { // iterate over all registered tools - for( TOOL_ID toolId : m_activeTools ) + for( auto it = m_activeTools.begin(); it != m_activeTools.end(); /* iteration is done inside */) { - TOOL_STATE* st = m_toolIdIndex[toolId]; + auto curIt = it; + TOOL_STATE* st = m_toolIdIndex[*it]; + ++it; // it might be overwritten, if the tool is removed the m_activeTools deque // the tool state handler is waiting for events (i.e. called Wait() method) if( st->pendingWait ) @@ -507,7 +509,10 @@ void TOOL_MANAGER::dispatchInternal( const TOOL_EVENT& aEvent ) st->waitEvents.clear(); if( st->cofunc && !st->cofunc->Resume() ) - finishTool( st ); // The couroutine has finished + { + if( finishTool( st, false ) ) // The couroutine has finished + it = m_activeTools.erase( curIt ); + } // If the tool did not request to propagate // the event to other tools, we should stop it now @@ -635,8 +640,10 @@ void TOOL_MANAGER::dispatchContextMenu( const TOOL_EVENT& aEvent ) } -void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) +bool TOOL_MANAGER::finishTool( TOOL_STATE* aState, bool aDeactivate ) { + bool shouldDeactivate = false; + // Reset VIEW_CONTROLS only if the most recent tool is finished if( m_activeTools.empty() || m_activeTools.front() == aState->theTool->GetId() ) m_viewControls->Reset(); @@ -648,10 +655,17 @@ void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) aState->theTool->GetId() ); if( tool != m_activeTools.end() ) - m_activeTools.erase( tool ); + { + shouldDeactivate = true; + + if( aDeactivate ) + m_activeTools.erase( tool ); + } } aState->theTool->SetTransitions(); + + return shouldDeactivate; } diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 4703f635ce..7c9f2ae4fd 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -390,8 +390,11 @@ private: * Deactivates a tool and does the necessary clean up. * * @param aState is the state variable of the tool to be stopped. + * @param aDeactivate decides if the tool should be removed from the active tools set. + * @return True if the tool should be deactivated (note it does not necessarily mean it has + * been deactivated, aDeactivate parameter decides). */ - void finishTool( TOOL_STATE* aState ); + bool finishTool( TOOL_STATE* aState, bool aDeactivate = true ); /** * Function isRegistered()