Mercurial > rinkhals
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 |
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()) |