Utility for navigating actors.
authorSimon Cross <hodgestar@gmail.com>
Sun, 28 Feb 2016 21:37:32 +0000 (23:37 +0200)
committerSimon Cross <hodgestar@gmail.com>
Sun, 28 Feb 2016 21:37:32 +0000 (23:37 +0200)
koperkapel/actors/navigator.py [new file with mode: 0644]

diff --git a/koperkapel/actors/navigator.py b/koperkapel/actors/navigator.py
new file mode 100644 (file)
index 0000000..40835cb
--- /dev/null
@@ -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