From: W. Trevor King Date: Thu, 12 Aug 2010 15:02:06 +0000 (-0400) Subject: Added CurveEngine.run_command and reorganized CommandStack._execute X-Git-Url: http://git.tremily.us/?p=hooke.git;a=commitdiff_plain;h=608c372b4c9beb3f8c0cfc5a2889012827592d12 Added CurveEngine.run_command and reorganized CommandStack._execute --- diff --git a/hooke/command_stack.py b/hooke/command_stack.py index fc8dc75..3888a45 100644 --- a/hooke/command_stack.py +++ b/hooke/command_stack.py @@ -44,11 +44,9 @@ class CommandStack (list): >>> c.append(CommandMessage(ca, {'param':'C'})) >>> c.append(CommandMessage(cb, {'param':'D'})) - Implement a dummy :meth:`_execute` for testing. This would - usually call :meth:`hooke.command.Command.run` with appropriate - arguments. + Implement a dummy :meth:`_execute` for testing. - >>> def execute(command_message): + >>> def execute(hooke, command_message): ... cm = command_message ... print 'EXECUTE', cm.command.name, cm.arguments >>> c._execute = execute @@ -74,7 +72,7 @@ class CommandStack (list): EXECUTE CommandB {'param': 'B'} EXECUTE CommandB {'param': 'D'} """ - def execute(self, *args, **kwargs): + def execute(self, hooke): """Execute a stack of commands. See Also @@ -83,7 +81,7 @@ class CommandStack (list): """ for command_message in self: if self.filter(command_message) == True: - self._execute(command_message, *args, **kwargs) + self._execute(hooke, command_message) def filter(self, command_message): """Any commands in the stack that are not subclasses of @@ -91,5 +89,5 @@ class CommandStack (list): """ return True - def _execute(self, command_message): - raise NotImplementedError() + def _execute(self, hooke, command_message): + hooke.run_command(command_message.command, command_message.arguments) diff --git a/hooke/curve.py b/hooke/curve.py index 552eda6..34fb34e 100644 --- a/hooke/curve.py +++ b/hooke/curve.py @@ -170,6 +170,11 @@ class Curve (object): self.info = info self.name = os.path.basename(path) self.command_stack = CommandStack() + self._hooke = None # Hooke instance for Curve.load() + + def set_hooke(self, hooke=None): + if hooke != None: + self._hooke = hooke def identify(self, drivers): """Identify the appropriate :class:`hooke.driver.Driver` for @@ -188,18 +193,21 @@ class Curve (object): return raise NotRecognized(self) - def load(self, *args, **kwargs): + def load(self, hooke=None): """Use the driver to read the curve into memory. Also runs any commands in :attr:`command_stack`. All arguments are passed through to :meth:`hooke.command_stack.CommandStack.execute`. """ + self.set_hooke(hooke) data,info = self.driver.read(self.path, self.info) self.data = data for key,value in info.items(): self.info[key] = value - self.command_stack.execute(*args, **kwargs) + if self.hooke != None: + # TODO: set 'curve' argument explicitly for CurveCommands + self.command_stack.execute(self.hooke) def unload(self): """Release memory intensive :attr:`.data`. diff --git a/hooke/engine.py b/hooke/engine.py index 90c652e..b438129 100644 --- a/hooke/engine.py +++ b/hooke/engine.py @@ -22,6 +22,8 @@ import logging +from .command import NullQueue + class QueueMessage (object): def __str__(self): @@ -73,3 +75,15 @@ class CommandEngine (object): log.debug('engine running %s' % msg.command.name) msg.command.run(hooke, ui_to_command_queue, command_to_ui_queue, **msg.arguments) + + def run_command(self, hooke, command, arguments): + """Internal command execution. + + This allows commands to execute sub commands and enables + :class:`~hooke.command_stack.CommandStack` execution. + + Note that these commands *do not* have access to the usual UI + communication queues, so make sure they will not need user + interaction. + """ + command.run(hooke, NullQueue(), NullQueue(), arguments) diff --git a/hooke/hooke.py b/hooke/hooke.py index 54f0f0f..a8079a9 100644 --- a/hooke/hooke.py +++ b/hooke/hooke.py @@ -90,7 +90,7 @@ class Hooke (object): self.load_plugins() self.load_drivers() self.load_ui() - self.command = engine.CommandEngine() + self.engine = engine.CommandEngine() self.playlists = playlist.NoteIndexList() def load_log(self): @@ -118,6 +118,16 @@ class Hooke (object): def close(self): self.config.write() # Does not preserve original comments + def run_command(self, command, arguments): + """Run `command` with `arguments` using + :meth:`~hooke.engine.CommandEngine.run_command`. + + Allows for running commands without spawning another process + as in :class:`HookeRunner`. + """ + self.engine.run_command(self, command, arguments) + + class HookeRunner (object): def run(self, hooke): """Run Hooke's main execution loop. @@ -153,7 +163,7 @@ class HookeRunner (object): command_to_ui = multiprocessing.Queue() manager = multiprocessing.Manager() command = multiprocessing.Process(name='command engine', - target=hooke.command.run, args=(hooke, ui_to_command, command_to_ui)) + target=hooke.engine.run, args=(hooke, ui_to_command, command_to_ui)) command.start() return (ui_to_command, command_to_ui, command) diff --git a/hooke/playlist.py b/hooke/playlist.py index 906cb06..d3ca4c6 100644 --- a/hooke/playlist.py +++ b/hooke/playlist.py @@ -118,8 +118,6 @@ class Playlist (NoteIndexList): self.drivers = drivers self._loaded = [] # List of loaded curves, see :meth:`._setup_item`. self._max_loaded = 100 # curves to hold in memory simultaneously. - self._curve_load_args = () - self._curve_load_kwargs = {} def append_curve_by_path(self, path, info=None, identify=True): path = os.path.normpath(path) @@ -129,10 +127,6 @@ class Playlist (NoteIndexList): self.append(c) return c - def set_curve_load_args(self, *args, **kwargs): - self._curve_load_args = args - self._curve_load_kwargs = kwargs - def _setup_item(self, curve): if curve != None and curve not in self._loaded: if curve not in self: @@ -140,7 +134,7 @@ class Playlist (NoteIndexList): if curve.driver == None: c.identify(self.drivers) if curve.data == None: - curve.load(*self._curve_load_args, **self._curve_load_kwargs) + curve.load() self._loaded.append(curve) if len(self._loaded) > self._max_loaded: oldest = self._loaded.pop(0)