#include <VisFramework/VisFrameworkBase/interface/VisQueueProcessor.h>
Public Types | |
typedef IgDispatcher < VisEventMessage & > | VisEventDispatcher |
Public Member Functions | |
VisEventDispatcher | eventDispatcher (void) |
virtual void | process (void) |
Process visualisation commands for a new event. | |
virtual void | scheduleAbort (void) |
Queue a command to terminate the event processing. | |
virtual void | scheduleNextEvent (void) |
Queue a command to advance to the next event. | |
VisQueueProcessor (IgState *state) | |
Construct the visualisation event processing handler. | |
~VisQueueProcessor (void) | |
Destroy the object and detach from the state. | |
Private Member Functions | |
void | doAbort (void) |
Actual execution of scheduleAbort() in the event thread. | |
void | doNextEvent (void) |
Actual execution of scheduleNextEvent() in the event thread. | |
IG_DECLARE_STATE_ELEMENT (VisQueueProcessor) | |
Private Attributes | |
VisEventDispatcher * | m_dispatcher |
bool | m_done |
IgState * | m_state |
VisQueueProcessor is instantied by the VisAnalyser module to block the framework thread and event loop until GUI has no more interest in the event. The queue processor pulls actions off VisQueue and executes them.
There are two reasons for the existence of this class. The first is that framework blindly runs through the input collection as quickly it can, so we simply have to stop it while we have an interest in the event. Typically our interest ends when the user selects "next event" from the menu (or some other similar action).
The second reason for this class is that access to event must happen inside a framework module's process() method, so all twig operations must be executed in such a context. The action to be executed is packaged up as a SEAL Callback object, and executed when an event is available.
Normally event-related twigs simply inherit from VisQueuedTwig: it hides the details for most common visualisation needs.
Definition at line 49 of file VisQueueProcessor.h.
Definition at line 53 of file VisQueueProcessor.h.
VisQueueProcessor::VisQueueProcessor | ( | IgState * | state | ) |
Construct the visualisation event processing handler.
Definition at line 26 of file VisQueueProcessor.cc.
References ASSERT, LFfwvis, LOG, m_state, IgState::put(), and GsfMatrixTools::trace().
00027 : m_state (state), 00028 m_done (false), 00029 m_dispatcher (new VisEventDispatcher ()) 00030 { 00031 LOG (0, trace, LFfwvis, "VisQueueProcessor::VisQueueProcessor\n"); 00032 ASSERT (m_state); m_state->put (s_key, this); 00033 }
VisQueueProcessor::~VisQueueProcessor | ( | void | ) |
Destroy the object and detach from the state.
Definition at line 36 of file VisQueueProcessor.cc.
References ASSERT, IgState::detach(), and m_state.
Actual execution of scheduleAbort() in the event thread.
Definition at line 161 of file VisQueueProcessor.cc.
Referenced by scheduleAbort().
Actual execution of scheduleNextEvent() in the event thread.
Simply causes upDate() to break out of the loop and to return.
Definition at line 169 of file VisQueueProcessor.cc.
References IgDispatcher< Message >::broadcast(), event(), eventDispatcher(), LFfwvis, LOG, m_done, and GsfMatrixTools::trace().
Referenced by scheduleNextEvent().
00170 { 00171 LOG (0, trace, LFfwvis, "VisQueueProcessor::doNextEvent()\n"); 00172 00173 VisEventMessage event; 00174 00175 eventDispatcher ().broadcast (event); 00176 m_done = true; 00177 00178 LOG (0, trace, LFfwvis, "VisQueueProcessor::doNextEvent() done\n"); 00179 }
VisQueueProcessor::VisEventDispatcher VisQueueProcessor::eventDispatcher | ( | void | ) |
Definition at line 40 of file VisQueueProcessor.cc.
References m_dispatcher.
Referenced by doNextEvent().
00041 { 00042 return *m_dispatcher; 00043 }
VisQueueProcessor::IG_DECLARE_STATE_ELEMENT | ( | VisQueueProcessor | ) | [private] |
Process visualisation commands for a new event.
This method is invoked in the event processing (consumer) thread by the COBRA dispatcher once all LazyObserver objects have been notified about the new event. We block the thread, waiting for commands queued into VisQueue. Each command so scheduled is popped off the queue and executed.
This method enables all event access must to place in the COBRA event processing thread as required by COBRA; other threads such as the Qt GUI loop must not access the event. Any access to the event or reconstruction objects from the GUI must be wrapped as a command callback and queued for execution through VisQueue, which available in the same IgState as this object. When a COBRA event becomes available, this method dequeues the callback actions in the order they were scheduled and invokes them.
Invoke scheduleNextEvent() to let the event processing continue to the next event, or to the end of the run if this is the last event. scheduleAbort() can be used similarly to exit from the event processing thread. Both result in a command being inserted in the VisQueue that, when executed, causes the desired action. (If other commands are queued after scheduleNextEvent(), they will be executed once a new event arrives.)
Since this object blocks the event consumer thread, there cannot be any other G3EventProxy Observer objects. LazyObserver objects have their baseUpDate()
methods invoked before this class is notified. Thus other objects can monitor the event by becoming a LazyObserver and scheduling commands to execute in their baseUpDate()
method (or simply performing the desired action in that method). All event-related data proxies and GUI displays should be built using that mechanism.
The commands must not access objects outside the event processing thread without synchronisation. For example, access to Qt and OpenInventor must be surrounded by calls to QApplication::lock() and QApplication::unlock().
An instance of this object comes to existence only once the event consumer thread starts execution -- and is specific to the consumer thread. Normally clients should use VisQueue which is created early in the initialisation of COBRA visualisation and isn't specific to any thread.
Definition at line 91 of file VisQueueProcessor.cc.
References cmsRelvalreport::action, ASSERT, DBSPlugin::get(), lat::Signal::handleFatal(), LFfwvis, LOG, m_done, m_state, TSqueue< X >::pop(), and GsfMatrixTools::trace().
Referenced by VisSimProcessor::update().
00092 { 00093 LOG (0, trace, LFfwvis, "VisQueueProcessor::process()\n"); 00094 00095 // Force our signal handler until we can get decent tracebacks 00096 // from COBRA in case of error. This kills the Objy handlers so 00097 // it isn't a nice approach... 00098 lat::Signal::handleFatal("iguana"); 00099 00100 // FIXME: Move out -- another lazy observer that observes event? 00101 qApp->lock (); 00102 QApplication::restoreOverrideCursor (); 00103 qApp->unlock (false); 00104 00105 // Pull items off the queue and execute them until we are told to 00106 // stop. Abort throws an exception so we don't need to care. 00107 VisQueue *q = VisQueue::get (m_state); 00108 ASSERT (q); 00109 00110 for (m_done = false; ! m_done; ) 00111 { 00112 lat::Callback action (q->pop ()); 00113 LOG (0, trace, LFfwvis, "VisQueueProcessor: got action\n"); 00114 action (); 00115 } 00116 00117 LOG (0, trace, LFfwvis, "VisQueueProcessor: loop done\n"); 00118 00119 // FIXME: Move out -- another observer that observes end-of-event? 00120 // FIXME: Block GUI. FIXME: Needs unsetting for end-of-run. 00121 qApp->lock (); 00122 QApplication::setOverrideCursor (Qt::waitCursor); 00123 qApp->unlock (false); 00124 00125 LOG (0, trace, LFfwvis, "VisQueueProcessor::process() done\n"); 00126 }
Queue a command to terminate the event processing.
Once commands already in the queue have been executed, the event processing is terminated and the COBRA application will exit. This method can be called in any thread.
Definition at line 134 of file VisQueueProcessor.cc.
References ASSERT, lat::CreateCallback(), doAbort(), DBSPlugin::get(), and m_state.
00135 { 00136 ASSERT (VisQueue::get (m_state)); 00137 VisQueue::get (m_state) 00138 ->push (lat::CreateCallback (this, &VisQueueProcessor::doAbort)); 00139 }
Queue a command to advance to the next event.
Once commands already in the queue have been executed, the upDate() method will return to the COBRA event processor for more events (or exit if all events have been processed). This method can be called in any thread.
Definition at line 147 of file VisQueueProcessor.cc.
References ASSERT, lat::CreateCallback(), doNextEvent(), DBSPlugin::get(), LFfwvis, LOG, m_state, and GsfMatrixTools::trace().
00148 { 00149 LOG (0, trace, LFfwvis, "VisQueueProcessor::scheduleNextEvent()\n"); 00150 00151 ASSERT (VisQueue::get (m_state)); 00152 VisQueue::get (m_state) 00153 ->push (lat::CreateCallback (this, &VisQueueProcessor::doNextEvent)); 00154 00155 LOG (0, trace, LFfwvis, "VisQueueProcessor::scheduleNextEvent() done\n"); 00156 }
bool VisQueueProcessor::m_done [private] |
IgState* VisQueueProcessor::m_state [private] |
Definition at line 73 of file VisQueueProcessor.h.
Referenced by process(), scheduleAbort(), scheduleNextEvent(), VisQueueProcessor(), and ~VisQueueProcessor().