1 # Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
3 # This file is part of Hooke.
5 # Hooke is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Lesser General Public License as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
10 # Hooke is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
13 # Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with Hooke. If not, see
17 # <http://www.gnu.org/licenses/>.
19 """The ``command_stack`` module provides tools for managing and
20 executing stacks of :class:`~hooke.engine.CommandMessage`\s.
24 class CommandStack (list):
25 """Store a stack of commands.
29 >>> from .engine import CommandMessage
31 Define two dummy commands for testing.
33 >>> class CommandA (object):
36 >>> class CommandB (CommandA):
40 Show off `CommandStack`\s functionality.
42 >>> c = CommandStack([CommandMessage(ca, {'param':'A'})])
43 >>> c.append(CommandMessage(cb, {'param':'B'}))
44 >>> c.append(CommandMessage(ca, {'param':'C'}))
45 >>> c.append(CommandMessage(cb, {'param':'D'}))
47 Implement a dummy :meth:`_execute` for testing. This would
48 usually call :meth:`hooke.command.Command.run` with appropriate
51 >>> def execute(command_message):
52 ... cm = command_message
53 ... print 'EXECUTE', cm.command.name, cm.arguments
54 >>> c._execute = execute
56 >>> c.execute() # doctest: +ELLIPSIS
57 EXECUTE CommandA {'param': 'A'}
58 EXECUTE CommandB {'param': 'B'}
59 EXECUTE CommandA {'param': 'C'}
60 EXECUTE CommandB {'param': 'D'}
62 :meth:`filter` allows you to select which commands get executed.
63 If, for example, you are applying a set of commands to the current
64 :class:`~hooke.curve.Curve`, you may only want to execute
65 instances of :class:`~hooke.plugin.curve.CurveCommand`. Here we
66 only execute instances of `CommandB`.
68 >>> def filter(command_message):
69 ... return isinstance(command_message.command, CommandB)
72 Apply the stack to the current curve
73 >>> c.execute() # doctest: +ELLIPSIS
74 EXECUTE CommandB {'param': 'B'}
75 EXECUTE CommandB {'param': 'D'}
77 def execute(self, *args, **kwargs):
78 """Execute a stack of commands.
84 for command_message in self:
85 if self.filter(command_message) == True:
86 self._execute(command_message, *args, **kwargs)
88 def filter(self, command_message):
89 """Any commands in the stack that are not subclasses of
90 :class:`~hooke.plugin.curve.CurveCommand` are ignored.
94 def _execute(self, command_message):
95 raise NotImplementedError()