# HG changeset patch # User Simon Cross # Date 1258828476 0 # Node ID cf4b020e63853e4f3e195c7374805234e1613540 # Parent 16437cf4a2b8dc012e601132eb25f70728816575 Start of serializer for buildings and support for reference cycles. diff -r 16437cf4a2b8 -r cf4b020e6385 gamelib/animal.py --- a/gamelib/animal.py Sat Nov 21 18:15:01 2009 +0000 +++ b/gamelib/animal.py Sat Nov 21 18:34:36 2009 +0000 @@ -54,9 +54,9 @@ return cls((0, 0)) make = classmethod(make) - def unsimplify(cls, value): + def unsimplify(cls, *args, **kwargs): """Override default Simplifiable unsimplification.""" - obj = super(Animal, cls).unsimplify(value) + obj = super(Animal, cls).unsimplify(*args, **kwargs) obj.redraw() return obj unsimplify = classmethod(unsimplify) diff -r 16437cf4a2b8 -r cf4b020e6385 gamelib/buildings.py --- a/gamelib/buildings.py Sat Nov 21 18:15:01 2009 +0000 +++ b/gamelib/buildings.py Sat Nov 21 18:34:36 2009 +0000 @@ -13,9 +13,15 @@ import warnings warnings.filterwarnings("ignore", "os.popen3 is deprecated.") -class Place(object): +class Place(serializer.Simplifiable): """Space within a building that can be occupied.""" + SIMPLIFY = [ + 'occupant', + 'building', + 'offset', + ] + def __init__(self, building, offset): self.occupant = None self.building = building @@ -40,11 +46,16 @@ return (bpos[0] + self.offset[0], bpos[1] + self.offset[1], self.offset[2]) -class Floor(object): +class Floor(serializer.Simplifiable): """A set of places within a building. Places on a floor are organised into rows and columns. """ + SIMPLIFY = [ + 'title', + 'places', + ] + def __init__(self, title, places): self.title = title # str self.places = places # list of lists of places @@ -81,7 +92,7 @@ '_repair_price', '_sun_on', '_broken', - '_predators', + '_floors', ] def __init__(self, pos): diff -r 16437cf4a2b8 -r cf4b020e6385 gamelib/serializer.py --- a/gamelib/serializer.py Sat Nov 21 18:15:01 2009 +0000 +++ b/gamelib/serializer.py Sat Nov 21 18:34:36 2009 +0000 @@ -6,34 +6,77 @@ REGISTERED_CLASSES = {} -def simplify(item): +def simplify(item, refs=None): """Convert an item to a simple data structure.""" + if refs is None: + refs = set() + + refid = id(item) + + if refid in refs: + return { 'byref': refid } + if issubclass(type(item), Simplifiable): - return item.simplify() + refs.add(refid) + value = item.simplify(refs) + value['refid'] = refid elif type(item) is list: - return { 'list': [simplify(x) for x in item] } + refs.add(refid) + value = { 'list': [simplify(x, refs) for x in item] } + value['refid'] = refid + elif type(item) is set: + refs.add(refid) + value = { 'set': [simplify(x, refs) for x in item] } + value['refid'] = refid elif type(item) is tuple: - return { 'tuple': tuple([simplify(x) for x in item]) } + refs.add(refid) + value = { 'tuple': tuple([simplify(x, refs) for x in item]) } + value['refid'] = refid elif item is None: - return { 'none': '' } + value = { 'none': '' } else: - return { 'raw': item } + value = { 'raw': item } + + return value -def unsimplify(value): +def unsimplify(value, refs=None): """Reverse the simplify process.""" + if refs is None: + refs = {} + + if 'refid' in value: + refid = value['refid'] + if value.has_key('class'): cls = REGISTERED_CLASSES[value['class']] - return cls.unsimplify(value) + item = cls.unsimplify(value, refs) elif value.has_key('list'): - return [unsimplify(x) for x in value['list']] + item = [] + refs[refid] = item + item.extend(unsimplify(x, refs) for x in value['list']) + elif value.has_key('set'): + item = set() + refs[refid] = item + item.update(unsimplify(x, refs) for x in value['set']) elif value.has_key('tuple'): - return tuple([unsimplify(x) for x in value['tuple']]) + item = tuple([unsimplify(x, refs) for x in value['tuple']]) elif value.has_key('none'): - return None + item = None elif value.has_key('raw'): - return value['raw'] + item = value['raw'] + elif value.has_key('byref'): + refid = value['byref'] + if refid in refs: + item = refs[refid] + else: + raise SimplifyError("Unknown refid %r in byref." % (refid,)) else: - raise SimplifyError("Unknown tar type key.") + raise SimplifyError("Unknown unsimplify type key.") + + if 'refid' in value: + refs[value['refid']] = item + + return item class SimplifyError(Exception): pass @@ -64,7 +107,7 @@ return cls.__new__(cls) make = classmethod(make) - def unsimplify(cls, value): + def unsimplify(cls, value, refs=None): """ Create an object of this class (or a sub-class) from its simplification. @@ -79,13 +122,15 @@ raise SimplifyError("Wrong number of attributes for this class") obj = actual_cls.make() + refs[value['refid']] = obj + for attr, value in zip(actual_cls.SIMPLIFY, attrs): - setattr(obj, attr, unsimplify(value)) + setattr(obj, attr, unsimplify(value, refs)) return obj unsimplify = classmethod(unsimplify) - def simplify(self): + def simplify(self, refs=None): """ Create a simplified version (tar) of the object. """ @@ -95,7 +140,7 @@ attrs = [] for attr in self.SIMPLIFY: o = getattr(self, attr) - attrs.append(simplify(o)) + attrs.append(simplify(o, refs)) value['attributes'] = attrs return value