annotate gamelib/serializer.py @ 415:8f012ef1f64f

Start of ability to serialize game state.
author Simon Cross <hodgestar@gmail.com>
date Sat, 21 Nov 2009 12:55:08 +0000
parents
children cf4b020e6385
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
415
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
1 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
2 Interface for converting objects to and from simple structures: lists, dicts,
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
3 strings, integers and combinations there of. Used for sending objects over
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
4 the communications API.
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
5 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
6
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
7 REGISTERED_CLASSES = {}
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
8
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
9 def simplify(item):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
10 """Convert an item to a simple data structure."""
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
11 if issubclass(type(item), Simplifiable):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
12 return item.simplify()
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
13 elif type(item) is list:
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
14 return { 'list': [simplify(x) for x in item] }
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
15 elif type(item) is tuple:
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
16 return { 'tuple': tuple([simplify(x) for x in item]) }
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
17 elif item is None:
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
18 return { 'none': '' }
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
19 else:
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
20 return { 'raw': item }
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
21
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
22 def unsimplify(value):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
23 """Reverse the simplify process."""
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
24 if value.has_key('class'):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
25 cls = REGISTERED_CLASSES[value['class']]
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
26 return cls.unsimplify(value)
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
27 elif value.has_key('list'):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
28 return [unsimplify(x) for x in value['list']]
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
29 elif value.has_key('tuple'):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
30 return tuple([unsimplify(x) for x in value['tuple']])
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
31 elif value.has_key('none'):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
32 return None
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
33 elif value.has_key('raw'):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
34 return value['raw']
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
35 else:
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
36 raise SimplifyError("Unknown tar type key.")
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
37
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
38 class SimplifyError(Exception):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
39 pass
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
40
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
41 class SimplifiableMetaclass(type):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
42 def __init__(cls, name, bases, dct):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
43 super(SimplifiableMetaclass, cls).__init__(name, bases, dct)
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
44 REGISTERED_CLASSES[cls.__name__] = cls
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
45
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
46 class Simplifiable(object):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
47 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
48 Object which can be simplified() and unsimplified() (i.e.
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
49 converted to a data type which, for example, Python's XMLRPC
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
50 or json module is capable of handling). Each subclass
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
51 must provide SIMPLIFY (a list of strings giving the names
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
52 of attributes which should be stored) unless a parent class
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
53 provides the right thing.
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
54 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
55 __metaclass__ = SimplifiableMetaclass
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
56
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
57 # List of attributes which need to be stored and restored
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
58 SIMPLIFY = []
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
59
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
60 def make(cls):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
61 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
62 Create an object of this class without any attributes set.
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
63 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
64 return cls.__new__(cls)
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
65 make = classmethod(make)
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
66
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
67 def unsimplify(cls, value):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
68 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
69 Create an object of this class (or a sub-class) from its
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
70 simplification.
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
71 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
72 actual_cls = REGISTERED_CLASSES[value['class']]
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
73 attrs = value['attributes']
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
74
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
75 if not issubclass(actual_cls, cls):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
76 raise SimplifyError("Real class not a subclass of this class")
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
77
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
78 if not len(attrs) == len(actual_cls.SIMPLIFY):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
79 raise SimplifyError("Wrong number of attributes for this class")
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
80
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
81 obj = actual_cls.make()
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
82 for attr, value in zip(actual_cls.SIMPLIFY, attrs):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
83 setattr(obj, attr, unsimplify(value))
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
84
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
85 return obj
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
86 unsimplify = classmethod(unsimplify)
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
87
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
88 def simplify(self):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
89 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
90 Create a simplified version (tar) of the object.
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
91 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
92 value = {}
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
93 value['class'] = self.__class__.__name__
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
94
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
95 attrs = []
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
96 for attr in self.SIMPLIFY:
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
97 o = getattr(self, attr)
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
98 attrs.append(simplify(o))
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
99
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
100 value['attributes'] = attrs
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
101 return value
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
102
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
103 def copy(self):
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
104 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
105 Return a copy of the object.
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
106 """
8f012ef1f64f Start of ability to serialize game state.
Simon Cross <hodgestar@gmail.com>
parents:
diff changeset
107 return self.__class__.unsimplify(self.simplify())