Browse Source

Refactor request_handler.py to use GeneratorStackEntry objects instead of tuples

jonathanvdc 8 years ago
parent
commit
ab2249128f
1 changed files with 44 additions and 31 deletions
  1. 44 31
      kernel/modelverse_kernel/request_handler.py

+ 44 - 31
kernel/modelverse_kernel/request_handler.py

@@ -4,12 +4,42 @@ class KnownRequestHandled(Exception):
     """An exception that signifies that a known request was handled."""
     pass
 
+class GeneratorStackEntry(object):
+    """An entry in the generator stack of a request handles."""
+    def __init__(self, generator):
+        self.generator = generator
+        self.pending_requests = None
+        self.finished_requests = True
+        self.replies = []
+        self.has_reply = False
+
+    def append_reply(self, new_reply):
+        """Appends a reply to the this entry's list of pending replies."""
+        self.replies.append(new_reply)
+        self.has_reply = True
+
+    def extend_replies(self, new_replies):
+        """Appends a list of replies to this entry's list of pending replies."""
+        if new_replies is not None:
+            self.replies.extend(new_replies)
+            self.has_reply = True
+
+    def step(self):
+        """Performs a single step: accumulated replies are fed to the generator,
+           which then produces requests."""
+        # Send the replies to the generator, and ask for new requests.
+        self.pending_requests = self.generator.send(self.replies if self.has_reply else None)
+
+        # Reset some data structures.
+        self.finished_requests = False
+        self.replies = []
+        self.has_reply = False
+
 class RequestHandler(object):
     """A type of object that intercepts logic-related Modelverse requests, and
        forwards Modelverse state requests."""
     def __init__(self):
-        # generator_stack is a stack of (generator, pending requests, request replies, has-reply)
-        # tuples.
+        # generator_stack is a stack of GeneratorStackEntry values.
         self.generator_stack = []
         # exception_handlers is a stack of
         # (generator_stack index, [(exception type, handler function)])
@@ -80,17 +110,15 @@ class RequestHandler(object):
 
     def set_finished_requests_flag(self):
         """Sets the finished_requests flag in the top-of-stack tuple."""
-        current_generator, requests, _, replies, has_reply = self.generator_stack[-1]
-        self.generator_stack[-1] = (current_generator, requests, True, replies, has_reply)
+        self.generator_stack[-1].finished_requests = True
 
     def has_pending_requests(self):
         """Tests if the top-of-stack generator has pending requests."""
-        _, _, finished_requests, _, _ = self.generator_stack[-1]
-        return not finished_requests
+        return not self.generator_stack[-1].finished_requests
 
     def push_generator(self, gen):
         """Pushes a new generator onto the stack."""
-        self.generator_stack.append((gen, None, True, [], False))
+        self.generator_stack.append(GeneratorStackEntry(gen))
         # print('Pushed generator %s. Generator count: %d' % (gen, len(self.generator_stack)))
 
     def pop_generator(self):
@@ -113,30 +141,16 @@ class RequestHandler(object):
 
     def append_reply(self, new_reply):
         """Appends a reply to the top-of-stack generator's list of pending replies."""
-        current_generator, requests, requests_done, replies, has_reply = self.generator_stack[-1]
-        replies.append(new_reply)
-        has_reply = True
-        self.generator_stack[-1] = (current_generator, requests, requests_done, replies, has_reply)
+        self.generator_stack[-1].append_reply(new_reply)
 
     def extend_replies(self, new_replies):
         """Appends a list of replies to the top-of-stack generator's list of pending replies."""
-        current_generator, requests, requests_done, replies, has_reply = self.generator_stack[-1]
-        if new_replies is not None:
-            replies.extend(new_replies)
-            has_reply = True
-            self.generator_stack[-1] = (
-                current_generator, requests, requests_done, replies, has_reply)
+        self.generator_stack[-1].extend_replies(new_replies)
 
     def step(self):
         """Performs a single step: accumulated replies are fed to the generator,
            which then produces requests."""
-        current_generator, _, _, replies, has_reply = self.generator_stack[-1]
-
-        # Send the replies to the generator, and ask for new requests.
-        requests = current_generator.send(replies if has_reply else None)
-
-        # Update the entry on the stack.
-        self.generator_stack[-1] = (current_generator, requests, False, [], False)
+        self.generator_stack[-1].step()
 
     def handle_exception(self, exception):
         """Handles the given exception. A Boolean is returned that tells if
@@ -158,12 +172,11 @@ class RequestHandler(object):
                 # a single 'TAIL_CALL_ARGS' request. The next iteration will replace
                 # the dummy frame by an actual frame.
                 del self.generator_stack[stack_index:]
-                self.generator_stack.append(
-                    (None,
-                     [('TAIL_CALL_ARGS', [applicable_handler, (exception,)])],
-                     False,
-                     [],
-                     False))
+                stack_entry = GeneratorStackEntry(None)
+                stack_entry.pending_requests = [
+                    ('TAIL_CALL_ARGS', [applicable_handler, (exception,)])]
+                stack_entry.finished_requests = False
+                self.generator_stack.append(stack_entry)
                 return True
 
         # We couldn't find an applicable exception handler, even after exhausting the
@@ -179,7 +192,7 @@ class RequestHandler(object):
 
            A list of requests and a Boolean are returned. The latter is True
            if there are no more requests to process, and false otherwise."""
-        _, requests, _, _, _ = self.generator_stack[-1]
+        requests = self.generator_stack[-1].pending_requests
         if requests is None or len(requests) == 0:
             # Couldn't find a request for the state to handle.
             self.set_finished_requests_flag()