Added event queue to handle events at the end of the event processing cycle.

This commit is contained in:
Maciej Suminski 2014-07-09 16:25:50 +02:00
parent 81ad03cf91
commit b1837615aa
6 changed files with 88 additions and 54 deletions

View File

@ -89,24 +89,14 @@ int ACTION_MANAGER::MakeActionId( const std::string& aActionName )
} }
bool ACTION_MANAGER::RunAction( const std::string& aActionName ) const TOOL_ACTION* ACTION_MANAGER::FindAction( const std::string& aActionName ) const
{ {
std::map<std::string, TOOL_ACTION*>::const_iterator it = m_actionNameIndex.find( aActionName ); std::map<std::string, TOOL_ACTION*>::const_iterator it = m_actionNameIndex.find( aActionName );
if( it == m_actionNameIndex.end() ) if( it != m_actionNameIndex.end() )
return false; // no action with given name found return it->second;
RunAction( it->second ); return NULL;
return true;
}
void ACTION_MANAGER::RunAction( const TOOL_ACTION* aAction ) const
{
TOOL_EVENT event = aAction->MakeEvent();
m_toolMgr->ProcessEvent( event );
} }
@ -153,6 +143,8 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
if( tool ) if( tool )
{ {
// Choose the action that goes to the tool with highest priority
// (i.e. is on the top of active tools stack)
priority = m_toolMgr->GetPriority( tool->GetId() ); priority = m_toolMgr->GetPriority( tool->GetId() );
if( priority >= 0 && priority > highestPriority ) if( priority >= 0 && priority > highestPriority )
@ -163,13 +155,16 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
} }
} }
if( !global && !context ) // currently there is no valid action to run
return false;
if( context ) if( context )
RunAction( context ); {
else if( global ) m_toolMgr->RunAction( *context, true );
RunAction( global );
return true; return true;
}
else if( global )
{
m_toolMgr->RunAction( *global, true );
return true;
}
return false;
} }

View File

@ -290,15 +290,40 @@ void TOOL_MANAGER::UnregisterAction( TOOL_ACTION* aAction )
} }
bool TOOL_MANAGER::RunAction( const std::string& aActionName ) bool TOOL_MANAGER::RunAction( const std::string& aActionName, bool aNow )
{ {
return m_actionMgr->RunAction( aActionName ); TOOL_ACTION* action = m_actionMgr->FindAction( aActionName );
if( action )
{
if( aNow )
{
TOOL_EVENT event = action->MakeEvent();
ProcessEvent( event );
}
else
{
PostEvent( action->MakeEvent() );
}
return true;
}
return false;
} }
void TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction ) void TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction, bool aNow )
{ {
m_actionMgr->RunAction( &aAction ); if( aNow )
{
TOOL_EVENT event = aAction.MakeEvent();
ProcessEvent( event );
}
else
{
PostEvent( aAction.MakeEvent() );
}
} }
@ -424,6 +449,8 @@ optional<TOOL_EVENT> TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool,
{ {
TOOL_STATE* st = m_toolState[aTool]; TOOL_STATE* st = m_toolState[aTool];
assert( !st->pendingWait ); // everything collapses on two Yield() in a row
// indicate to the manager that we are going to sleep and we shall be // indicate to the manager that we are going to sleep and we shall be
// woken up when an event matching aConditions arrive // woken up when an event matching aConditions arrive
st->pendingWait = true; st->pendingWait = true;
@ -477,7 +504,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
{ {
if( tr.first.Matches( aEvent ) ) if( tr.first.Matches( aEvent ) )
{ {
// no tool context allocated yet? Create one. // if there is already a context, then store it
if( st->cofunc ) if( st->cofunc )
st->Push(); st->Push();
@ -590,6 +617,14 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
dispatchActivation( aEvent ); dispatchActivation( aEvent );
dispatchContextMenu( aEvent ); dispatchContextMenu( aEvent );
// Dispatch queue
while( !m_eventQueue.empty() )
{
TOOL_EVENT event = m_eventQueue.front();
m_eventQueue.pop_front();
ProcessEvent( event );
}
if( m_view->IsDirty() ) if( m_view->IsDirty() )
{ {
PCB_EDIT_FRAME* f = static_cast<PCB_EDIT_FRAME*>( GetEditFrame() ); PCB_EDIT_FRAME* f = static_cast<PCB_EDIT_FRAME*>( GetEditFrame() );

View File

@ -75,20 +75,12 @@ public:
static int MakeActionId( const std::string& aActionName ); static int MakeActionId( const std::string& aActionName );
/** /**
* Function RunAction() * Function FindAction()
* Runs an action with a given name (if there is one available). * Finds an action with a given name (if there is one available).
* @param aActionName is the name of action to be run. * @param aActionName is the searched action.
* @return True if there was an action associated with the name, false otherwise. * @return Pointer to a TOOL_ACTION object or NULL if there is no such action.
*/ */
bool RunAction( const std::string& aActionName ) const; TOOL_ACTION* FindAction( const std::string& aActionName ) const;
/**
* Function RunAction()
* Prepares an appropriate event and sends it to the destination specified in a TOOL_ACTION
* object.
* @param aAction is the action to be run.
*/
void RunAction( const TOOL_ACTION* aAction ) const;
/** /**
* Function RunHotKey() * Function RunHotKey()

View File

@ -106,17 +106,21 @@ public:
* Runs the specified action. The common format for action names is "application.ToolName.Action". * Runs the specified action. The common format for action names is "application.ToolName.Action".
* *
* @param aActionName is the name of action to be invoked. * @param aActionName is the name of action to be invoked.
* @return True if the action finished successfully, false otherwise. * @param aNow decides if the action has to be run immediately or after the current coroutine
* is preemptied.
* @return False if the action was not found.
*/ */
bool RunAction( const std::string& aActionName ); bool RunAction( const std::string& aActionName, bool aNow = false );
/** /**
* Function RunAction() * Function RunAction()
* Runs the specified action. * Runs the specified action.
* *
* @param aAction is the action to be invoked. * @param aAction is the action to be invoked.
* @param aNow decides if the action has to be run immediately or after the current coroutine
* is preemptied.
*/ */
void RunAction( const TOOL_ACTION& aAction ); void RunAction( const TOOL_ACTION& aAction, bool aNow = false );
/** /**
* Function FindTool() * Function FindTool()
@ -158,11 +162,20 @@ public:
void ResetTools( TOOL_BASE::RESET_REASON aReason ); void ResetTools( TOOL_BASE::RESET_REASON aReason );
/** /**
* Takes an event from the TOOL_DISPATCHER and propagates it to * Propagates an event to tools that requested events of matching type(s).
* tools that requested events of matching type(s) * @param aEvent is the event to be processed.
*/ */
bool ProcessEvent( TOOL_EVENT& aEvent ); bool ProcessEvent( TOOL_EVENT& aEvent );
/**
* Puts an event to the event queue to be processed at the end of event processing cycle.
* @param aEvent is the event to be put into the queue.
*/
inline void PostEvent( const TOOL_EVENT& aEvent )
{
m_eventQueue.push_back( aEvent );
}
/** /**
* Sets the work environment (model, view, view controls and the parent window). * Sets the work environment (model, view, view controls and the parent window).
* These are made available to the tool. Called by the parent frame (PCB_EDIT_FRAME) * These are made available to the tool. Called by the parent frame (PCB_EDIT_FRAME)
@ -177,17 +190,17 @@ public:
return m_view; return m_view;
} }
KIGFX::VIEW_CONTROLS* GetViewControls() const inline KIGFX::VIEW_CONTROLS* GetViewControls() const
{ {
return m_viewControls; return m_viewControls;
} }
EDA_ITEM* GetModel() const inline EDA_ITEM* GetModel() const
{ {
return m_model; return m_model;
} }
wxWindow* GetEditFrame() const inline wxWindow* GetEditFrame() const
{ {
return m_editFrame; return m_editFrame;
} }
@ -197,7 +210,7 @@ public:
* (was invoked the most recently). * (was invoked the most recently).
* @return Id of the currently used tool. * @return Id of the currently used tool.
*/ */
int GetCurrentToolId() const inline int GetCurrentToolId() const
{ {
return m_activeTools.front(); return m_activeTools.front();
} }
@ -207,7 +220,7 @@ public:
* (was invoked the most recently). * (was invoked the most recently).
* @return Pointer to the currently used tool. * @return Pointer to the currently used tool.
*/ */
TOOL_BASE* GetCurrentTool() const inline TOOL_BASE* GetCurrentTool() const
{ {
return FindTool( GetCurrentToolId() ); return FindTool( GetCurrentToolId() );
} }
@ -405,6 +418,9 @@ private:
KIGFX::VIEW_CONTROLS* m_viewControls; KIGFX::VIEW_CONTROLS* m_viewControls;
wxWindow* m_editFrame; wxWindow* m_editFrame;
/// Queue that stores events to be processed at the end of the event processing cycle.
std::list<TOOL_EVENT> m_eventQueue;
/// Flag saying if the currently processed event should be passed to other tools. /// Flag saying if the currently processed event should be passed to other tools.
bool m_passEvent; bool m_passEvent;
}; };

View File

@ -404,11 +404,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
bds.SetCustomViaDrill( m_router->Settings().GetViaDrill() ); bds.SetCustomViaDrill( m_router->Settings().GetViaDrill() );
bds.UseCustomTrackViaSize( true ); bds.UseCustomTrackViaSize( true );
// TODO Should be done another way, but RunAction() won't work here. As the ROUTER_TOOL m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged );
// did not call Wait(), it does not wait for events and therefore the sent event
// won't arrive here
TOOL_EVENT event = COMMON_ACTIONS::trackViaSizeChanged.MakeEvent();
handleCommonEvents( event );
} }
else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) ) else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) )

View File

@ -559,7 +559,7 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection )
bool EDIT_TOOL::makeSelection( const SELECTION& aSelection ) bool EDIT_TOOL::makeSelection( const SELECTION& aSelection )
{ {
if( aSelection.Empty() ) // Try to find an item that could be modified if( aSelection.Empty() ) // Try to find an item that could be modified
m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle, true );
return !aSelection.Empty(); return !aSelection.Empty();
} }