--- /dev/null
+""" A navigable graph of actors. """
+
+
+class ActorNavigator:
+ """ A navigable graph of actors. """
+
+ def __init__(self):
+ self._actors = {}
+ self._graph = {}
+ self._current_id = None
+
+ @property
+ def current(self):
+ return self._actors.get(self._current_id)
+
+ def connect_pair(self, a1, a2, edge):
+ self._actors[id(a1)] = a1
+ self._actors[id(a2)] = a2
+ if self._current_id is None:
+ self._current_id = id(a1)
+ a1edges = self._graph.setdefault(id(a1), {})
+ a1edges[edge] = id(a2)
+
+ def connect(self, actors, edges, reverse=None, wrap=True):
+ if not edges or not actors:
+ return
+ first, previous, current = None, None, None
+ for actor in actors:
+ previous, current = current, actor
+ if previous is None:
+ first = current
+ continue
+ for edge in edges:
+ self.connect_pair(previous, current, edge)
+ if wrap and first is not current:
+ for edge in edges:
+ self.connect_pair(current, first, edge)
+ if reverse is not None:
+ self.connect(list(reversed(actors)), reverse)
+
+ def follow(self, edge):
+ future = self._graph.get(self._current_id, {}).get(edge)
+ if future:
+ old, self._current_id = self._current_id, future
+ return self._actors[old], self._actors[future]
+ return None, None