The command_stack module provides tools for managing and executing stacks of CommandMessages.
Store a stack of commands.
Examples
>>> c = CommandStack([CommandMessage('CommandA', {'param':'A'})])
>>> c.append(CommandMessage('CommandB', {'param':'B'}))
>>> c.append(CommandMessage('CommandA', {'param':'C'}))
>>> c.append(CommandMessage('CommandB', {'param':'D'}))
Implement a dummy execute_command() for testing.
>>> def execute_cmd(hooke, command_message, stack=None):
... cm = command_message
... print 'EXECUTE', cm.command, cm.arguments
>>> c.execute_command = execute_cmd
>>> c.execute(hooke=None)
EXECUTE CommandA {'param': 'A'}
EXECUTE CommandB {'param': 'B'}
EXECUTE CommandA {'param': 'C'}
EXECUTE CommandB {'param': 'D'}
filter() allows you to select which commands get executed. If, for example, you are applying a set of commands to the current Curve, you may only want to execute instances of CurveCommand. Here we only execute commands named CommandB.
>>> def filter(hooke, command_message):
... return command_message.command == 'CommandB'
Apply the stack to the current curve.
>>> c.execute(hooke=None, filter=filter)
EXECUTE CommandB {'param': 'B'}
EXECUTE CommandB {'param': 'D'}
Execute a new command and add it to the stack.
>>> cm = CommandMessage('CommandC', {'param':'E'})
>>> c.execute_command(hooke=None, command_message=cm)
EXECUTE CommandC {'param': 'E'}
>>> c.append(cm)
>>> print [repr(cm) for cm in c]
['<CommandMessage CommandA {param: A}>',
'<CommandMessage CommandB {param: B}>',
'<CommandMessage CommandA {param: C}>',
'<CommandMessage CommandB {param: D}>',
'<CommandMessage CommandC {param: E}>']
The data-type is also pickleable, which ensures we can move it between processes with multiprocessing.Queues and easily save it to disk. We must remove the unpickleable dummy executor before testing though.
>>> c.execute_command
<function execute_cmd at 0x...>
>>> del(c.__dict__['execute_command'])
>>> c.execute_command
<bound method CommandStack.execute_command of ...>
Lets also attach a child command message to demonstrate recursive serialization (we can’t append c itself because of Python issue 1062277).
>>> import copy
>>> c.append(CommandMessage('CommandD', {'param': copy.deepcopy(c)}))
Run the pickle (and YAML) tests.
>>> import pickle
>>> s = pickle.dumps(c)
>>> z = pickle.loads(s)
>>> print '\n'.join([repr(cm) for cm in c]
... )
<CommandMessage CommandA {param: A}>
<CommandMessage CommandB {param: B}>
<CommandMessage CommandA {param: C}>
<CommandMessage CommandB {param: D}>
<CommandMessage CommandC {param: E}>
<CommandMessage CommandD {param:
[<CommandMessage CommandA {param: A}>,
<CommandMessage CommandB {param: B}>,
<CommandMessage CommandA {param: C}>,
<CommandMessage CommandB {param: D}>,
<CommandMessage CommandC {param: E}>]}>
>>> import yaml
>>> print yaml.dump(c)
!!python/object/new:hooke.command_stack.CommandStack
listitems:
- !!python/object:hooke.engine.CommandMessage
arguments: {param: A}
command: CommandA
explicit_user_call: true
- !!python/object:hooke.engine.CommandMessage
arguments: {param: B}
command: CommandB
explicit_user_call: true
- !!python/object:hooke.engine.CommandMessage
arguments: {param: C}
command: CommandA
explicit_user_call: true
- !!python/object:hooke.engine.CommandMessage
arguments: {param: D}
command: CommandB
explicit_user_call: true
- !!python/object:hooke.engine.CommandMessage
arguments: {param: E}
command: CommandC
explicit_user_call: true
- !!python/object:hooke.engine.CommandMessage
arguments:
param: !!python/object/new:hooke.command_stack.CommandStack
listitems:
- !!python/object:hooke.engine.CommandMessage
arguments: {param: A}
command: CommandA
explicit_user_call: true
- !!python/object:hooke.engine.CommandMessage
arguments: {param: B}
command: CommandB
explicit_user_call: true
- !!python/object:hooke.engine.CommandMessage
arguments: {param: C}
command: CommandA
explicit_user_call: true
- !!python/object:hooke.engine.CommandMessage
arguments: {param: D}
command: CommandB
explicit_user_call: true
- !!python/object:hooke.engine.CommandMessage
arguments: {param: E}
command: CommandC
explicit_user_call: true
command: CommandD
explicit_user_call: true
<BLANKLINE>
There is also a convenience function for clearing the stack.
>>> c.clear()
>>> print [repr(cm) for cm in c]
[]
YAMLize a curve argument.
>>> from .curve import Curve
>>> c.append(CommandMessage('curve info', {'curve': Curve(path=None)}))
>>> print yaml.dump(c)
!!python/object/new:hooke.command_stack.CommandStack
listitems:
- !!python/object:hooke.engine.CommandMessage
arguments:
curve: !!python/object:hooke.curve.Curve {}
command: curve info
explicit_user_call: true
<BLANKLINE>
Methods
append | |
clear | |
count | |
execute | |
execute_command | |
extend | |
filter | |
index | |
insert | |
pop | |
remove | |
reverse | |
sort |
Execute a stack of commands.
See also
Return True to execute command_message, False otherwise.
The default implementation always returns True.
A file-backed CommandStack.
Methods
append | |
clear | |
count | |
execute | |
execute_command | |
extend | |
filter | |
flatten | |
from_string | |
index | |
insert | |
load | |
pop | |
remove | |
reverse | |
save | |
set_path | |
sort |
Create a string representation of the command stack.
A playlist is a YAML document with the following syntax:
- arguments: {param: A}
command: CommandA
- arguments: {param: B, ...}
command: CommandB
...
Examples
>>> c = FileCommandStack([CommandMessage('CommandA', {'param':'A'})])
>>> c.append(CommandMessage('CommandB', {'param':'B'}))
>>> c.append(CommandMessage('CommandA', {'param':'C'}))
>>> c.append(CommandMessage('CommandB', {'param':'D'}))
>>> print c.flatten()
- arguments: {param: A}
command: CommandA
- arguments: {param: B}
command: CommandB
- arguments: {param: C}
command: CommandA
- arguments: {param: D}
command: CommandB
<BLANKLINE>
Load a playlist from a string.
Warning
This is not safe with untrusted input.
Examples
>>> string = '''- arguments: {param: A}
... command: CommandA
... - arguments: {param: B}
... command: CommandB
... - arguments: {param: C}
... command: CommandA
... - arguments: {param: D}
... command: CommandB
... '''
>>> c = FileCommandStack()
>>> c.from_string(string)
>>> print [repr(cm) for cm in c]
['<CommandMessage CommandA {param: A}>',
'<CommandMessage CommandB {param: B}>',
'<CommandMessage CommandA {param: C}>',
'<CommandMessage CommandB {param: D}>']
Load a command stack from path.
Saves the command stack to path.
Set the path (and possibly the name) of the command stack.
Examples
>>> c = FileCommandStack([CommandMessage('CommandA', {'param':'A'})])
name is set only if it starts out equal to None. >>> c.name == None True >>> c.set_path(os.path.join(‘path’, ‘to’, ‘my’, ‘command’, ‘stack’)) >>> c.path ‘path/to/my/command/stack’ >>> c.name ‘stack’ >>> c.set_path(os.path.join(‘another’, ‘path’)) >>> c.path ‘another/path’ >>> c.name ‘stack’