Difference between revisions of "Slicer3:EventBroker"

From Slicer Wiki
Jump to: navigation, search
m (1 revision)
(Replacing page with '<big>'''Note:''' We are migrating this content to the slicer.org domain - <font color="orange">The newer page is [http://www.slicer.org/slicerWiki/index.php/Slicer3:EventBroker...')
Line 1: Line 1:
== Currently ==
+
<big>'''Note:''' We are migrating this content to the slicer.org domain - <font color="orange">The newer page is [http://www.slicer.org/slicerWiki/index.php/Slicer3:EventBroker  here]</font></big>a
The basic idea of the EventBroker is to avoid the following kind of code that shows up in GUIs and other classes that depend on events generated by other classes:
 
 
 
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 (all data and methods are private)
 
 
 
* 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
 
 
 
== EventBroker Solution ==
 
 
 
The EventBroker is a singleton, available as:
 
 
 
vtkEventBroker *broker = vtkEventBroker::GetInstance();
 
 
 
with the broker, you can make a call like the following:
 
 
 
broker->AddObservation(node, vtkCommand::ModifiedEvent, this, callbackCommand);
 
 
 
where ''node'' is the subject of the observation.
 
 
 
The broker does the following:
 
 
 
* adds DeleteEvent observers to both ''node'' and ''this'' so it can remove the observation automatically when either side is destroyed
 
 
 
* keeps an introspectable list of all observers it knows about
 
 
 
* has an option to keep a log of all event invocations for debugging and performance analysis
 
 
 
* has an option to turn off all event invocations
 
 
 
* has an ''asynchronous'' option to queue all event invocations and invoke them later (off by default)
 
 
 
* has option to collapse redundant events in the queue
 
 
 
The broker is also available for use from tcl. For convenience in slicer there's a global variable for the broker so you can use a code snippet like:
 
 
 
$::slicer3::Broker AddObservation $node ModifiedEvent {puts "the node was modified"}
 
 
 
Another nice feature is that you can use a numerical value for the event argument, which works around the limitation in VTK's native wrapping of event types.  So, if you look in the header for a widget or object and know the custom event number, you can use it as an argument:
 
 
 
$::slicer3::Broker AddObservation $node 1 {puts "got an AnyEvent notification from the node"}
 
 
 
Future options include:
 
 
 
* add a timer to log the amount of time taken to process each event
 
 
 
* specify that some observations must be handled synchronously (e.g. for progress events that shouldn't be collapsed)
 
 
 
See the file [http://www.na-mic.org/Slicer/Documentation/Slicer3/html/classvtkEventBroker.html Libs/MRML/vtkEventBroker.h] for more information on logging options and introspection features.
 
 
 
==References==
 
 
 
The following reference provided insight on requirements and design precedents.
 
 
 
* [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:
 
 
 
=== Simple Dependency ===
 
<graphviz border='frame' format='svg'>
 
digraph G {
 
vtkImageViewer -> vtkImageEllipsoidSource[ label = ModifiedEvent ]
 
;}
 
</graphviz>
 
 
 
=== Subset of Slicer Dependencies ===
 
<graphviz border='frame' format='svg'>
 
strict digraph G {
 
vtkMRMLModelDisplayNode -> vtkMRMLModelDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLScalarVolumeDisplayNode -> vtkMRMLScalarVolumeDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLLabelMapVolumeDisplayNode -> vtkMRMLLabelMapVolumeDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLDiffusionWeightedVolumeDisplayNode -> vtkMRMLDiffusionWeightedVolumeDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLDiffusionTensorVolumeDisplayNode -> vtkMRMLDiffusionTensorVolumeDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLFiberBundleLineDisplayNode -> vtkMRMLFiberBundleLineDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLFiberBundleTubeDisplayNode -> vtkMRMLFiberBundleTubeDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLFiberBundleGlyphDisplayNode -> vtkMRMLFiberBundleGlyphDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLCameraNode -> vtkOpenGLCamera [ label = "ModifiedEvent" ]
 
; vtkMRMLUnstructuredGridDisplayNode -> vtkMRMLUnstructuredGridDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLCameraNode -> vtkOpenGLCamera [ label = "ModifiedEvent" ]
 
; vtkMRMLModelDisplayNode -> vtkMRMLModelDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLCameraNode -> vtkOpenGLCamera [ label = "ModifiedEvent" ]
 
; vtkMRMLModelNode -> vtkPolyData [ label = "ModifiedEvent" ]
 
; vtkMRMLModelNode -> vtkPolyData [ label = "ModifiedEvent" ]
 
; vtkMRMLModelDisplayNode -> vtkMRMLModelDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLModelDisplayNode -> vtkImageData [ label = "ModifiedEvent" ]
 
; vtkMRMLModelNode -> vtkPolyData [ label = "ModifiedEvent" ]
 
; vtkMRMLModelDisplayNode -> vtkMRMLModelDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLModelDisplayNode -> vtkImageData [ label = "ModifiedEvent" ]
 
; vtkMRMLModelNode -> vtkPolyData [ label = "ModifiedEvent" ]
 
; vtkMRMLModelDisplayNode -> vtkMRMLModelDisplayNode [ label = "ModifiedEvent" ]
 
; vtkMRMLModelDisplayNode -> vtkImageData [ label = "ModifiedEvent" ]
 
;}
 
</graphviz>
 
 
 
== Issues ==
 
 
 
* how to work with the vtkObserverManager?
 

Revision as of 19:23, 19 May 2008

Home < Slicer3:EventBroker

Note: We are migrating this content to the slicer.org domain - The newer page is herea