Difference between revisions of "Slicer3:EventBroker"
From NAMIC Wiki
Line 18: | Line 18: | ||
* there's no way to collapse events or disable them | * there's no way to collapse events or disable them | ||
− | == | + | == EventBroker Solution == |
− | + | The EventBroker is a singleton, available as: | |
− | broker | + | 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 |
− | + | Future options include: | |
* add a timer to log the amount of time taken to process each event | * add a timer to log the amount of time taken to process each event |
Revision as of 20:24, 4 April 2008
Home < Slicer3:EventBrokerContents
Currently
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
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
Future options include:
- add a timer to log the amount of time taken to process each event
References
- Java Message Service (JMS) API
- Wikipedia definition of Observer Pattern
- A C++ implementation
- Another C++ implementation
- The Qt implementation
Dependency Graphs
EventBroker code should have the option to put out log files that are compatible with 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?