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 );
if( it == m_actionNameIndex.end() )
return false; // no action with given name found
if( it != m_actionNameIndex.end() )
return it->second;
RunAction( it->second );
return true;
}
void ACTION_MANAGER::RunAction( const TOOL_ACTION* aAction ) const
{
TOOL_EVENT event = aAction->MakeEvent();
m_toolMgr->ProcessEvent( event );
return NULL;
}
@ -153,6 +143,8 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
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() );
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 )
RunAction( context );
{
m_toolMgr->RunAction( *context, true );
return true;
}
else if( global )
RunAction( global );
{
m_toolMgr->RunAction( *global, true );
return 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];
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
// woken up when an event matching aConditions arrive
st->pendingWait = true;
@ -477,7 +504,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& 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 )
st->Push();
@ -590,6 +617,14 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
dispatchActivation( 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() )
{
PCB_EDIT_FRAME* f = static_cast<PCB_EDIT_FRAME*>( GetEditFrame() );

View File

@ -75,20 +75,12 @@ public:
static int MakeActionId( const std::string& aActionName );
/**
* Function RunAction()
* Runs an action with a given name (if there is one available).
* @param aActionName is the name of action to be run.
* @return True if there was an action associated with the name, false otherwise.
* Function FindAction()
* Finds an action with a given name (if there is one available).
* @param aActionName is the searched action.
* @return Pointer to a TOOL_ACTION object or NULL if there is no such action.
*/
bool RunAction( 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;
TOOL_ACTION* FindAction( const std::string& aActionName ) const;
/**
* Function RunHotKey()

View File

@ -106,17 +106,21 @@ public:
* Runs the specified action. The common format for action names is "application.ToolName.Action".
*
* @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()
* Runs the specified action.
*
* @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()
@ -158,11 +162,20 @@ public:
void ResetTools( TOOL_BASE::RESET_REASON aReason );
/**
* Takes an event from the TOOL_DISPATCHER and propagates it to
* tools that requested events of matching type(s)
* Propagates an event to tools that requested events of matching type(s).
* @param aEvent is the event to be processed.
*/
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).
* These are made available to the tool. Called by the parent frame (PCB_EDIT_FRAME)
@ -177,17 +190,17 @@ public:
return m_view;
}
KIGFX::VIEW_CONTROLS* GetViewControls() const
inline KIGFX::VIEW_CONTROLS* GetViewControls() const
{
return m_viewControls;
}
EDA_ITEM* GetModel() const
inline EDA_ITEM* GetModel() const
{
return m_model;
}
wxWindow* GetEditFrame() const
inline wxWindow* GetEditFrame() const
{
return m_editFrame;
}
@ -197,7 +210,7 @@ public:
* (was invoked the most recently).
* @return Id of the currently used tool.
*/
int GetCurrentToolId() const
inline int GetCurrentToolId() const
{
return m_activeTools.front();
}
@ -207,7 +220,7 @@ public:
* (was invoked the most recently).
* @return Pointer to the currently used tool.
*/
TOOL_BASE* GetCurrentTool() const
inline TOOL_BASE* GetCurrentTool() const
{
return FindTool( GetCurrentToolId() );
}
@ -405,6 +418,9 @@ private:
KIGFX::VIEW_CONTROLS* m_viewControls;
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.
bool m_passEvent;
};

View File

@ -404,11 +404,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
bds.SetCustomViaDrill( m_router->Settings().GetViaDrill() );
bds.UseCustomTrackViaSize( true );
// TODO Should be done another way, but RunAction() won't work here. As the ROUTER_TOOL
// 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 );
m_toolMgr->RunAction( 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 )
{
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();
}