|
|
(13 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
− | == Currently ==
| + | <big>'''Note:''' We are migrating this content to the slicer.org domain - <font color="orange">The newer page is [https://www.slicer.org/wiki/Slicer3:EventBroker here]</font></big> |
− | The basic idea of the EventBroker is that currently we have a lot of this kind of code in GUIs:
| |
− | | |
− | node->AddObserver(vtkCommand::ModifiedEvent, callbackCommand)
| |
− | | |
− | == Problems ==
| |
− | | |
− | The problems with this:
| |
− | | |
− | * node 'owns' the observer, but the callbackCommand is opaque so it doesn't know anything about what will happen when the event is invoked
| |
− | | |
− | * the GUI needs to explicitly remove the observer before it is destroyed
| |
− | | |
− | * node is not introspectable; you cannot get a list of observers on the node
| |
− | | |
− | * there's no easy way to know what side effects will happen for any Set call (either a priori or experimentally).
| |
− | | |
− | * there's no way to collapse events or disable them
| |
− | | |
− | == Goals for Solution ==
| |
− | | |
− | So the EventBroker would be a singleton, perhaps owned by the MRML Scene that would look something like:
| |
− | | |
− | broker->AddObservation(node, vtkCommand::ModifiedEvent, this, callbackCommand);
| |
− | | |
− | The broker would do the following: | |
− | | |
− | * add DeleteEvent observers to both node and this so it can remove the observer automatically if either side is destroyed
| |
− | | |
− | * keep an introspectable list of all observers it knows about
| |
− | | |
− | * have an option to keep a log of all event invocations for debugging and performance analysis
| |
− | | |
− | * have an option to turn off all event invocations
| |
− | | |
− | * have an option to queue all event invocations and invoke them later
| |
− | | |
− | * have methods to collapse redundant events in the queue
| |
− | | |
− | * perhaps have method to pass event invocations from a processing thread to the main GUI thread?
| |
− | | |
− | * the callbackCommand could be avoided if the vtkObject had a virtual method like this:
| |
− | | |
− | virtual void HandleEvent( vtkObject *caller, unsigned long event, void *clientData, void *callData );
| |
− | | |
− | * vtkEventBroker can have a class static GetInstance() method returning pointer to the global broker (like the way vtkSlicerApplication is done).
| |
− | | |
− | Additional possible extensions:
| |
− | | |
− | * rather than maintaining a distinct queue, the broker could queue events into the GUI event queue
| |
− | | |
− | * the event queue could be protected by a mutex lock so that multiple threads can access the MRML scene in parallel but only the GUI thread talks to the display
| |
− | | |
− | * add a timer to log the amount of time taken to process each event
| |
− | | |
− | ==References==
| |
− | | |
− | * [http://java.sun.com/products/jms/javadoc-102a/index.html Java Message Service (JMS) API]
| |
− | * [http://en.wikipedia.org/wiki/Observer_pattern Wikipedia definition of Observer Pattern]
| |
− | * [http://xlobject.sourceforge.net/ A C++ implementation]
| |
− | * [http://sigslot.sourceforge.net/ Another C++ implementation]
| |
− | * [http://doc.trolltech.com/4.3/signalsandslots.html The Qt implementation]
| |
− | | |
− | ==Dependency Graphs==
| |
− | | |
− | EventBroker code should have the option to put out log files that are compatible with [http://www.graphviz.org graphviz] .dot file format. This can be rendered with a variety of programs, or even pasted directly in the wiki: | |
− | | |
− | <graphviz border='frame' format='svg'> | |
− | digraph G {
| |
− | vtkImageViewer -> vtkImageEllipsoidSource[ label = ModifiedEvent ]
| |
− | ;}
| |
− | </graphviz> | |