Broke out Hooke.run and Hooke.run_lines into HookeRunner.
authorW. Trevor King <wking@drexel.edu>
Sun, 16 May 2010 13:53:53 +0000 (09:53 -0400)
committerW. Trevor King <wking@drexel.edu>
Sun, 16 May 2010 13:53:53 +0000 (09:53 -0400)
This allows the main process access to the command process' possibly
altered Hooke instance.  For example:
  >>> h = Hooke()
  >>> r = HookeRunner()
  >>> h = r.run_lines(h, ['load_playlist test/data/test'])
  >>> h = r.run_lines(h, ['curve_info --all=True'])
With the old implementation, second run_lines() call would fail
because the playlist was only loaded in the first command process'
Hooke instance, not the Hooke instance that the main (UI) process
held.

hooke/engine.py
hooke/hooke.py
test/load_playlist.py

index de1ae70a8aedeea2027a358a272003217eea366c..a973730f65a4af3c422bff3951dc96605f58c250 100644 (file)
@@ -40,6 +40,7 @@ class CommandEngine (object):
         while True:
             msg = ui_to_command_queue.get()
             if isinstance(msg, CloseEngine):
+                command_to_ui_queue.put(hooke)
                 break
             assert isinstance(msg, CommandMessage), type(msg)
             msg.command.run(hooke, ui_to_command_queue, command_to_ui_queue,
index 72fab311d59bd49f50c0ae682e7a4eaf29189e1d..e8a00506602665605fb43193ff2bb4ad3150b805 100644 (file)
@@ -73,44 +73,51 @@ class Hooke (object):
     def close(self):
         self.config.write() # Does not preserve original comments
 
-    def run(self):
+class HookeRunner (object):
+    def run(self, hooke):
         """Run Hooke's main execution loop.
 
         Spawns a :class:`hooke.engine.CommandEngine` subprocess and
         then runs the UI, rejoining the `CommandEngine` process after
         the UI exits.
         """
-        ui_to_command,command_to_ui,command = self._setup_run()
+        ui_to_command,command_to_ui,command = self._setup_run(hooke)
         try:
-            self.ui.run(self.commands, ui_to_command, command_to_ui)
+            self.ui.run(hooke.commands, ui_to_command, command_to_ui)
         finally:
-            self._cleanup_command(ui_to_command, command_to_ui, command)
+            hooke = self._cleanup_run(ui_to_command, command_to_ui, command)
+        return hooke
 
-    def run_lines(self, lines):
+    def run_lines(self, hooke, lines):
         """Run the pre-set commands `lines` with the "command line" UI.
 
         Allows for non-interactive sessions that are otherwise
         equivalent to :meth:'.run'.
         """
-        cmdline = ui.load_ui(self.config, 'command line')
-        ui_to_command,command_to_ui,command = self._setup_run()
+        cmdline = ui.load_ui(hooke.config, 'command line')
+        ui_to_command,command_to_ui,command = self._setup_run(hooke)
         try:
             cmdline.run_lines(
-                self.commands, ui_to_command, command_to_ui, lines)
+                hooke.commands, ui_to_command, command_to_ui, lines)
         finally:
-            self._cleanup_command(ui_to_command, command_to_ui, command)
+            hooke = self._cleanup_run(ui_to_command, command_to_ui, command)
+        return hooke
 
-    def _setup_run(self):
+    def _setup_run(self, hooke):
         ui_to_command = multiprocessing.Queue()
         command_to_ui = multiprocessing.Queue()
+        manager = multiprocessing.Manager()        
         command = multiprocessing.Process(name='command engine',
-            target=self.command.run, args=(self, ui_to_command, command_to_ui))
+            target=hooke.command.run, args=(hooke, ui_to_command, command_to_ui))
         command.start()
         return (ui_to_command, command_to_ui, command)
 
     def _cleanup_run(self, ui_to_command, command_to_ui, command):
         ui_to_command.put(ui.CloseEngine())
+        hooke = command_to_ui.get()
+        assert isinstance(hooke, Hooke)
         command.join()
+        return hooke
 
 
 def main():
@@ -129,20 +136,24 @@ def main():
         print >> sys.stderr, p.help()
         sys.exit(1)
 
-    app = Hooke(debug=__debug__)
+    hooke = Hooke(debug=__debug__)
+    runner = HookeRunner()
 
     if options.script != None:
         f = open(os.path.expanduser(options.script), 'r')
         options.commands.extend(f.readlines())
         f.close
     if len(options.commands) > 0:
-        app.run_lines(options.commands)
+        try:
+            hooke = runner.run_lines(hooke, options.commands)
+        finally:
+            hooke.close()
         sys.exit(0)
 
     try:
-        app.run()
+        hooke = runner.run(hooke)
     finally:
-        app.close()
+        hooke.close()
 
 if __name__ == '__main__':
     main()
index 46af92eb0f1d85be966df01e9fd0667171a701eb..18d829510752a78792da5ab0267742ba7180f6ad 100644 (file)
 # <http://www.gnu.org/licenses/>.
 
 """
->>> from hooke.hooke import Hooke
+>>> from hooke.hooke import Hooke, HookeRunner
 >>> h = Hooke()
->>> h.run_lines(['load_playlist test/data/test']) # doctest: +ELLIPSIS
+>>> r = HookeRunner()
+>>> h = r.run_lines(h, ['load_playlist test/data/test']) # doctest: +ELLIPSIS
 <FilePlaylist test.hkp>
 Success
 <BLANKLINE>