Transition from v0.1 XML playlists to v0.2 YAML playlists.
[hooke.git] / hooke / command_stack.py
index 17a633ba954343996c6ef97be56ea3da6a12ac64..234b3f3d85dfbd0ed7f42584c1d04f51517cf6be 100644 (file)
@@ -40,7 +40,7 @@ class CommandStack (list):
 
     Implement a dummy :meth:`execute_command` for testing.
     
-    >>> def execute_cmd(hooke, command_message):
+    >>> def execute_cmd(hooke, command_message, stack=None):
     ...     cm = command_message
     ...     print 'EXECUTE', cm.command, cm.arguments
     >>> c.execute_command = execute_cmd
@@ -80,12 +80,38 @@ class CommandStack (list):
      '<CommandMessage CommandB {param: D}>',
      '<CommandMessage CommandC {param: E}>']
 
+    The data-type is also pickleable, to ensure we can move it between
+    processes with :class:`multiprocessing.Queue`\s and easily save it
+    to disk.
+
+    >>> import pickle
+    >>> s = pickle.dumps(c)
+    >>> z = pickle.loads(s)
+    >>> print [repr(cm) for cm in c]  # doctest: +NORMALIZE_WHITESPACE
+    ['<CommandMessage CommandA {param: A}>',
+     '<CommandMessage CommandB {param: B}>',
+     '<CommandMessage CommandA {param: C}>',
+     '<CommandMessage CommandB {param: D}>',
+     '<CommandMessage CommandC {param: E}>']
+
     There is also a convenience function for clearing the stack.
 
     >>> c.clear()
     >>> print [repr(cm) for cm in c]
     []
     """
+    def __getstate__(self):
+        state = [{'command':cm.command, 'arguments':cm.arguments}
+                for cm in self]
+        return state
+
+    def __setstate__(self, state):
+        self.clear()
+        for cm_state in state:
+            self.append(CommandMessage(
+                    command=cm_state['command'],
+                    arguments=cm_state['arguments']))
+
     def execute(self, hooke, stack=False):
         """Execute a stack of commands.
 
@@ -123,8 +149,23 @@ class FileCommandStack (CommandStack):
 
     def __init__(self, *args, **kwargs):
         super(FileCommandStack, self).__init__(*args, **kwargs)
-        self.name = None
+        self.name = self.path = None
+
+    def __getstate__(self):
+        command_stack = super(FileCommandStack, self).__getstate__()
+        state = {
+            'command stack': command_stack,
+            'path': self.path,
+            'name': self.name,
+            }
+        return state
+
+    def __setstate__(self, state):
+        super(FileCommandStack, self).__setstate__(
+            state.get('command stack', []))
+        self.name = state.get('name', None)
         self.path = None
+        self.set_path(state.get('path', None))
 
     def set_path(self, path):
         """Set the path (and possibly the name) of the command  stack.