From 8d0a38ef88ea5d422ba5a30bdbf6edfef484e425 Mon Sep 17 00:00:00 2001 From: Simon Cross Date: Sun, 28 Feb 2016 23:37:32 +0200 Subject: [PATCH] Utility for navigating actors. --- koperkapel/actors/navigator.py | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 koperkapel/actors/navigator.py diff --git a/koperkapel/actors/navigator.py b/koperkapel/actors/navigator.py new file mode 100644 index 0000000..40835cb --- /dev/null +++ b/koperkapel/actors/navigator.py @@ -0,0 +1,46 @@ +""" 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 -- 2.34.1