Commit fe1b1850b40327aa879cd5d4e8dde78a07a2a952

Authored by Olli-Pekka Kahilakoski
Committed by GitHub
1 parent 8e5c5977
Exists in master

ADD: Callbacks to NeuronavigationAPI, allowing controlling InVesalius (#441)

Showing 1 changed file with 26 additions and 5 deletions   Show diff stats
invesalius/net/neuronavigation_api.py
@@ -28,20 +28,26 @@ class NeuronavigationApi(metaclass=Singleton): @@ -28,20 +28,26 @@ class NeuronavigationApi(metaclass=Singleton):
28 An API used internally in InVesalius to communicate with the 28 An API used internally in InVesalius to communicate with the
29 outside world. 29 outside world.
30 30
31 - When something noteworthy happens when running InVesalius, e.g.,  
32 - the coil is moved during neuronavigation, an object created from  
33 - this class can be used to update that information. 31 + When an event of one of several types happens while running InVesalius, e.g.,
  32 + the coil is moved during neuronavigation, this class is used to update the
  33 + information conveyed by the event.
34 34
35 When created for the first time, takes a connection object obtained 35 When created for the first time, takes a connection object obtained
36 from outside InVesalius (see the main entrypoint in app.py). 36 from outside InVesalius (see the main entrypoint in app.py).
37 37
38 - If connection object is not given or it is None, skip doing the updates. 38 + The owner of the connection object can update the state of InVesalius by implementing
  39 + functions to set callbacks, used then to communicate the new state to InVesalius (see,
  40 + e.g., set_callback__set_markers below).
  41 +
  42 + If connection object is not given or it is None, do not do the updates.
39 """ 43 """
40 N_VERTICES_IN_POLYGON = 3 44 N_VERTICES_IN_POLYGON = 3
41 45
42 def __init__(self, connection=None): 46 def __init__(self, connection=None):
43 if connection is not None: 47 if connection is not None:
44 - assert self._hasmethod(connection, 'update_coil_pose') 48 + self.assert_valid(connection)
  49 +
  50 + self.__set_callbacks(connection)
45 self.__bind_events() 51 self.__bind_events()
46 52
47 self.connection = connection 53 self.connection = connection
@@ -49,9 +55,16 @@ class NeuronavigationApi(metaclass=Singleton): @@ -49,9 +55,16 @@ class NeuronavigationApi(metaclass=Singleton):
49 def _hasmethod(self, obj, name): 55 def _hasmethod(self, obj, name):
50 return hasattr(obj, name) and callable(getattr(obj, name)) 56 return hasattr(obj, name) and callable(getattr(obj, name))
51 57
  58 + def assert_valid(self, connection):
  59 + assert self._hasmethod(connection, 'update_coil_pose')
  60 + assert self._hasmethod(connection, 'update_focus')
  61 + assert self._hasmethod(connection, 'set_callback__set_markers')
  62 +
52 def __bind_events(self): 63 def __bind_events(self):
53 Publisher.subscribe(self.update_focus, 'Set cross focal point') 64 Publisher.subscribe(self.update_focus, 'Set cross focal point')
54 65
  66 + # Functions for InVesalius to send updates.
  67 +
55 # TODO: Not the cleanest API; for an example of a better API, see update_coil_pose 68 # TODO: Not the cleanest API; for an example of a better API, see update_coil_pose
56 # below, for which position and orientation are sent separately. Changing this 69 # below, for which position and orientation are sent separately. Changing this
57 # would require changing 'Set cross focal point' publishers and subscribers 70 # would require changing 'Set cross focal point' publishers and subscribers
@@ -96,3 +109,11 @@ class NeuronavigationApi(metaclass=Singleton): @@ -96,3 +109,11 @@ class NeuronavigationApi(metaclass=Singleton):
96 points=points, 109 points=points,
97 polygons=polygons, 110 polygons=polygons,
98 ) 111 )
  112 +
  113 + # Functions for InVesalius to receive updates via callbacks.
  114 +
  115 + def __set_callbacks(self, connection):
  116 + connection.set_callback__set_markers(self.set_markers)
  117 +
  118 + def set_markers(self, markers):
  119 + Publisher.sendMessage('Set markers', markers=markers)