From e753939f30c6c07a68363c7819acf8c0e57a6951 Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Thu, 18 Mar 2010 22:45:31 -0700 Subject: [PATCH] Order state elements to generate more readable YAML. --- bulletml/parser.py | 172 +++++++++++++++++++++++++-------------------- 1 file changed, 97 insertions(+), 75 deletions(-) diff --git a/bulletml/parser.py b/bulletml/parser.py index 10b789a..51e15ad 100644 --- a/bulletml/parser.py +++ b/bulletml/parser.py @@ -45,7 +45,7 @@ class ParamList(object): self.params = list(params) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" return cls([NumberDef(subelem.text) for subelem in element if realtag(subelem) == "param"]) @@ -68,13 +68,14 @@ class Direction(object): self.value = value def __getstate__(self): - return dict(type=self.type, value=self.value.expr) + return [('type', self.type), ('value', self.value.expr)] def __setstate__(self, state): + state = dict(state) self.__init__(state["type"], NumberDef(state["value"])) @classmethod - def FromElement(cls, doc, element, default="absolute"): + def FromXML(cls, doc, element, default="absolute"): """Construct using an ElementTree-style element.""" return cls(element.get("type", default), NumberDef(element.text)) @@ -93,21 +94,22 @@ class ChangeDirection(object): self.direction = direction def __getstate__(self): - return dict(frames=self.term.expr, - type=self.direction.type, - value=self.direction.value.expr) + return [('frames', self.term.expr), + ('type', self.direction.type), + ('value', self.direction.value.expr)] def __setstate__(self, state): + state = dict(state) self.__init__(INumberDef(state["frames"]), Direction(state["type"], NumberDef(state["value"]))) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" for subelem in element.getchildren(): tag = realtag(subelem) if tag == "direction": - direction = Direction.FromElement(doc, subelem) + direction = Direction.FromXML(doc, subelem) elif tag == "term": term = INumberDef(subelem.text) try: @@ -134,13 +136,14 @@ class Speed(object): self.value = value def __getstate__(self): - return dict(type=self.type, value=self.value.expr) + return [('type', self.type), ('value', self.value.expr)] def __setstate__(self, state): + state = dict(state) self.__init__(state["type"], NumberDef(state["value"])) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" return cls(element.get("type", "absolute"), NumberDef(element.text)) @@ -158,21 +161,22 @@ class ChangeSpeed(object): self.speed = speed def __getstate__(self): - return dict(frames=self.term.expr, - type=self.speed.type, - value=self.speed.value.expr) + return [('frames', self.term.expr), + ('type', self.speed.type), + ('value', self.speed.value.expr)] def __setstate__(self, state): + state = dict(state) self.__init__(INumberDef(state["frames"]), Speed(state["type"], NumberDef(state["value"]))) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" for subelem in element.getchildren(): tag = realtag(subelem) if tag == "speed": - speed = Speed.FromElement(doc, subelem) + speed = Speed.FromXML(doc, subelem) elif tag == "term": term = INumberDef(subelem.text) try: @@ -200,7 +204,7 @@ class Wait(object): self.__init__(INumberDef(state["frames"])) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" return cls(INumberDef(element.text)) @@ -223,7 +227,7 @@ class Tag(object): self.__init__(state["tag"]) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" return cls(element.text) @@ -240,7 +244,7 @@ class Untag(object): self.__init__(state["tag"]) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" return cls(element.text) @@ -251,7 +255,7 @@ class Vanish(object): pass @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" return cls() @@ -266,22 +270,23 @@ class Repeat(object): self.action = action def __getstate__(self): - return dict(times=self.times.expr, action=self.action) + return [('times', self.times.expr), ('action', self.action)] def __setstate__(self, state): + state = dict(state) self.__init__(INumberDef(state["times"]), state["action"]) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" for subelem in element.getchildren(): tag = realtag(subelem) if tag == "times": times = INumberDef(subelem.text) elif tag == "action": - action = ActionDef.FromElement(doc, subelem) + action = ActionDef.FromXML(doc, subelem) elif tag == "actionRef": - action = ActionRef.FromElement(doc, subelem) + action = ActionRef.FromXML(doc, subelem) try: return cls(times, action) except UnboundLocalError as exc: @@ -305,19 +310,20 @@ class Accel(object): self.vertical = vertical def __getstate__(self): - state = dict(frames=self.term.expr) + state = [('frames', self.term.expr)] if self.horizontal: - state["horizontal"] = self.horizontal + state.append(('horizontal', self.horizontal)) if self.vertical: - state["vertical"] = self.vertical + state.append(('vertical', self.vertical)) return state def __setstate__(self, state): + state = dict(state) self.__init__(INumberDef(state["frames"]), state.get("horizontal"), state.get("vertical")) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" horizontal = None vertical = None @@ -327,9 +333,9 @@ class Accel(object): if tag == "term": term = INumberDef(subelem.text) elif tag == "horizontal": - horizontal = Speed.FromElement(doc, subelem) + horizontal = Speed.FromXML(doc, subelem) elif tag == "vertical": - vertical = Speed.FromElement(doc, subelem) + vertical = Speed.FromXML(doc, subelem) try: return cls(term, horizontal, vertical) @@ -358,20 +364,21 @@ class BulletDef(object): self.actions = list(actions) def __getstate__(self): - state = dict() + state = [] if self.direction: - state["direction"] = self.direction + state.append(("direction", self.direction)) if self.speed: - state["speed"] = self.speed + state.append(("speed", self.speed)) if self.actions: - state["actions"] = self.actions + state.append(("actions", self.actions)) return state def __setstate__(self, state): + state = dict(state) self.__init__(**state) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" actions = [] speed = None @@ -379,13 +386,13 @@ class BulletDef(object): for subelem in element.getchildren(): tag = realtag(subelem) if tag == "direction": - direction = Direction.FromElement(doc, subelem) + direction = Direction.FromXML(doc, subelem) elif tag == "speed": - speed = Speed.FromElement(doc, subelem) + speed = Speed.FromXML(doc, subelem) elif tag == "action": - actions.append(ActionDef.FromElement(doc, subelem)) + actions.append(ActionDef.FromXML(doc, subelem)) elif tag == "actionRef": - actions.append(ActionRef.FromElement(doc, subelem)) + actions.append(ActionRef.FromXML(doc, subelem)) dfn = cls(actions, direction, speed) doc.bullets[element.get("label")] = dfn return dfn @@ -409,20 +416,23 @@ class BulletRef(object): self.params = ParamList() if params is None else params def __getstate__(self): - state = dict(bullet=self.bullet) + state = [] if self.params.params: - state["params"] = [param.expr for param in self.params.params] + params = [param.expr for param in self.params.params] + state.append(("params", params)) + state.append(('bullet', self.bullet)) return state def __setstate__(self, state): + state = dict(state) bullet = state["bullet"] params = [NumberDef(param) for param in state.get("params", [])] self.__init__(bullet, ParamList(params)) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" - bullet = cls(element.get("label"), ParamList.FromElement(doc, element)) + bullet = cls(element.get("label"), ParamList.FromXML(doc, element)) doc._bullet_refs.append(bullet) return bullet @@ -438,7 +448,7 @@ class ActionDef(object): To support parsing new actions, add tags to ActionDef.CONSTRUCTORS. It maps tag names to classes with a - FromElement classmethod, which take the BulletML instance and + FromXML classmethod, which take the BulletML instance and ElementTree element as arguments. """ @@ -452,10 +462,11 @@ class ActionDef(object): return dict(actions=self.actions) def __setstate__(self, state): + state = dict(state) self.__init__(state["actions"]) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" actions = [] for subelem in element.getchildren(): @@ -465,7 +476,7 @@ class ActionDef(object): except KeyError: continue else: - actions.append(ctr.FromElement(doc, subelem)) + actions.append(ctr.FromXML(doc, subelem)) dfn = cls(actions) doc.actions[element.get("label")] = dfn return dfn @@ -484,20 +495,23 @@ class ActionRef(object): self.params = params or ParamList() def __getstate__(self): - state = dict(action=self.action) + state = [] if self.params.params: - state["params"] = [param.expr for param in self.params.params] + params = [param.expr for param in self.params.params] + state.append(("params", params)) + state.append(('action', self.action)) return state def __setstate__(self, state): + state = dict(state) action = state["action"] params = [NumberDef(param) for param in state.get("params", [])] self.__init__(action, ParamList(params)) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" - action = cls(element.get("label"), ParamList.FromElement(doc, element)) + action = cls(element.get("label"), ParamList.FromXML(doc, element)) doc._action_refs.append(action) return action @@ -521,18 +535,19 @@ class Offset(object): self.y = y def __getstate__(self): - state = dict(type=self.type) + state = [('type', self.type)] if self.x: - state["x"] = self.x.expr + state.append(('x', self.x.expr)) if self.y: - state["y"] = self.y.expr + state.append(('y', self.y.expr)) return state def __setstate__(self, state): + state = dict(state) self.__init__(state["type"], state.get("x"), state.get("y")) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" type = element.get("type", "relative") x = None @@ -559,28 +574,31 @@ class FireDef(object): self.offset = offset def __getstate__(self): + state = [] + if self.direction: + state.append(("direction", self.direction)) + if self.speed: + state.append(("speed", self.speed)) + if self.offset: + state.append(("offset", self.offset)) try: params = self.bullet.params except AttributeError: state = dict(bullet=self.bullet) else: if params.params: - state = dict(bullet=self.bullet) + state.append(('bullet', self.bullet)) else: - state = dict(bullet=self.bullet.bullet) - if self.direction: - state["direction"] = self.direction - if self.speed: - state["speed"] = self.speed - if self.offset: - state["offset"] = self.offset + # Strip out empty BulletRefs. + state.append(('bullet', self.bullet.bullet)) return state def __setstate__(self, state): + state = dict(state) self.__init__(**state) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" direction = None speed = None @@ -589,15 +607,15 @@ class FireDef(object): for subelem in element.getchildren(): tag = realtag(subelem) if tag == "direction": - direction = Direction.FromElement(doc, subelem, "aim") + direction = Direction.FromXML(doc, subelem, "aim") elif tag == "speed": - speed = Speed.FromElement(doc, subelem) + speed = Speed.FromXML(doc, subelem) elif tag == "bullet": - bullet = BulletDef.FromElement(doc, subelem) + bullet = BulletDef.FromXML(doc, subelem) elif tag == "bulletRef": - bullet = BulletRef.FromElement(doc, subelem) + bullet = BulletRef.FromXML(doc, subelem) elif tag == "offset": - offset = Offset.FromElement(doc, subelem) + offset = Offset.FromXML(doc, subelem) try: fire = cls(bullet, direction, speed, offset) except UnboundLocalError as exc: @@ -626,20 +644,23 @@ class FireRef(object): self.params = params or ParamList() def __getstate__(self): - state = dict(fire=self.fire) + state = [] if self.params.params: - state["params"] = [param.expr for param in self.params.params] + params = [param.expr for param in self.params.params] + state.append(("params", params)) + state.append(('fire', self.fire)) return state def __setstate__(self, state): + state = dict(state) fire = state["fire"] params = [NumberDef(param) for param in state.get("params", [])] self.__init__(fire, ParamList(params)) @classmethod - def FromElement(cls, doc, element): + def FromXML(cls, doc, element): """Construct using an ElementTree-style element.""" - fired = cls(element.get("label"), ParamList.FromElement(doc, element)) + fired = cls(element.get("label"), ParamList.FromXML(doc, element)) doc._fire_refs.append(fired) return fired @@ -657,7 +678,7 @@ class BulletML(object): firings, as well as a base game type. You can add tags to the BulletML.CONSTRUCTORS dictionary to extend - its parsing. It maps tag names to classes with a FromElement + its parsing. It maps tag names to classes with a FromXML classmethod, which take the BulletML instance and ElementTree element as arguments. @@ -676,9 +697,10 @@ class BulletML(object): self.fires = {} if fires is None else fires def __getstate__(self): - return dict(type=self.type, actions=self.actions) + return [('type', self.type), ('actions', self.actions)] def __setstate__(self, state): + state = dict(state) self.__init__(state["type"], actions=state.get("actions")) @classmethod @@ -699,7 +721,7 @@ class BulletML(object): for element in root.getchildren(): tag = realtag(element) if tag in self.CONSTRUCTORS: - self.CONSTRUCTORS[tag].FromElement(self, element) + self.CONSTRUCTORS[tag].FromXML(self, element) try: for ref in self._bullet_refs: @@ -749,7 +771,7 @@ class BulletML(object): source.seek(0) if start == "<": return cls.FromXML(source) - elif start == "!": + elif start == "!" or start == "#": return cls.FromYAML(source) else: raise ParseError("unknown initial character %r" % start) -- 2.20.1