from xml.etree.ElementTree import ElementTree
+# Python 3 moved this for no really good reason.
+try:
+ from sys import intern
+except ImportError:
+ pass
+
try:
from io import StringIO
except ImportError:
from bulletml.expr import NumberDef, INumberDef
-__all_ = ["ParseError", "BulletML"]
+__all__ = ["ParseError", "BulletML"]
class ParseError(Error):
"""Raised when an error occurs parsing the XML structure."""
def __init__(self, type, value):
if type not in self.VALID_TYPES:
raise ValueError("invalid type %r" % type)
- self.type = type
+ self.type = intern(type)
self.value = value
def __getstate__(self):
def __init__(self, type, value):
if type not in self.VALID_TYPES:
raise ValueError("invalid type %r" % type)
- self.type = type
+ self.type = intern(type)
self.value = value
def __getstate__(self):
direction = None
speed = None
- def __init__(self, actions=[], direction=None, speed=None):
+ def __init__(self, actions=(), direction=None, speed=None, tags=()):
self.direction = direction
self.speed = speed
self.actions = list(actions)
+ self.tags = set(tags)
def __getstate__(self):
state = []
state.append(("speed", self.speed))
if self.actions:
state.append(("actions", self.actions))
+ if self.tags:
+ state.append(("tags", list(self.tags)))
return state
def __setstate__(self, state):
actions = []
speed = None
direction = None
+ tags = set()
for subelem in element.getchildren():
tag = realtag(subelem)
if tag == "direction":
actions.append(ActionDef.FromXML(doc, subelem))
elif tag == "actionRef":
actions.append(ActionRef.FromXML(doc, subelem))
- dfn = cls(actions, direction, speed)
+ elif tag == "tag":
+ tags.add(subelem.text)
+ dfn = cls(actions, direction, speed, tags)
doc._bullets[element.get("label")] = dfn
return dfn
return (
self.direction and self.direction(params, rank),
self.speed and self.speed(params, rank),
+ self.tags,
actions)
def __repr__(self):
def __init__(self, type, x, y):
if type not in self.VALID_TYPES:
raise ValueError("invalid type %r" % type)
- self.type = type
+ self.type = intern(type)
self.x = x
self.y = y
class FireDef(object):
"""Fire definition (creates a bullet)."""
- def __init__(self, bullet, direction=None, speed=None, offset=None):
+ def __init__(
+ self, bullet, direction=None, speed=None, offset=None, tags=()):
self.bullet = bullet
self.direction = direction
self.speed = speed
self.offset = offset
+ self.tags = set(tags)
def __getstate__(self):
state = []
state.append(("speed", self.speed))
if self.offset:
state.append(("offset", self.offset))
+ if self.tags:
+ state.append(("tags", list(self.tags)))
try:
params = self.bullet.params
except AttributeError:
direction = None
speed = None
offset = None
+ tags = set()
for subelem in element.getchildren():
tag = realtag(subelem)
bullet = BulletRef.FromXML(doc, subelem)
elif tag == "offset":
offset = Offset.FromXML(doc, subelem)
+ elif tag == "tag":
+ tags.add(subelem.text)
try:
- fire = cls(bullet, direction, speed, offset)
+ fire = cls(bullet, direction, speed, offset, tags)
except UnboundLocalError as exc:
raise ParseError(str(exc))
else:
return fire
def __call__(self, params, rank):
- direction, speed, actions = self.bullet(params, rank)
+ direction, speed, tags, actions = self.bullet(params, rank)
if self.direction:
direction = self.direction(params, rank)
if self.speed:
speed = self.speed(params, rank)
- return direction, speed, actions, self.offset
+ tags = tags.union(self.tags)
+ return direction, speed, self.offset, tags, actions
def __repr__(self):
return "%s(direction=%r, speed=%r, bullet=%r)" % (
)
def __init__(self, type="none", actions=None):
- self.type = type
+ self.type = intern(type)
self.actions = [] if actions is None else actions
def __getstate__(self):
tree = ElementTree()
root = tree.parse(source)
- self = cls(type=root.get("type", "none"))
+ doc = cls(type=root.get("type", "none"))
- self._bullets = {}
- self._actions = {}
- self._fires = {}
- self._bullet_refs = []
- self._action_refs = []
- self._fire_refs = []
+ doc._bullets = {}
+ doc._actions = {}
+ doc._fires = {}
+ doc._bullet_refs = []
+ doc._action_refs = []
+ doc._fire_refs = []
for element in root.getchildren():
tag = realtag(element)
- if tag in self.CONSTRUCTORS:
- self.CONSTRUCTORS[tag].FromXML(self, element)
+ if tag in doc.CONSTRUCTORS:
+ doc.CONSTRUCTORS[tag].FromXML(doc, element)
try:
- for ref in self._bullet_refs:
- ref.bullet = self._bullets[ref.bullet]
- for ref in self._fire_refs:
- ref.fire = self._fires[ref.fire]
- for ref in self._action_refs:
- ref.action = self._actions[ref.action]
+ for ref in doc._bullet_refs:
+ ref.bullet = doc._bullets[ref.bullet]
+ for ref in doc._fire_refs:
+ ref.fire = doc._fires[ref.fire]
+ for ref in doc._action_refs:
+ ref.action = doc._actions[ref.action]
except KeyError as exc:
raise ParseError("unknown reference %s" % exc)
- self.actions = [act for name, act in self._actions.items()
+ doc.actions = [act for name, act in doc._actions.items()
if name and name.startswith("top")]
- del(self._bullet_refs)
- del(self._action_refs)
- del(self._fire_refs)
- del(self._bullets)
- del(self._actions)
- del(self._fires)
+ del(doc._bullet_refs)
+ del(doc._action_refs)
+ del(doc._fire_refs)
+ del(doc._bullets)
+ del(doc._actions)
+ del(doc._fires)
- return self
+ return doc
@classmethod
def FromYAML(cls, source):
else:
try:
return yaml.load(source)
- except Exception, exc:
+ except Exception as exc:
raise ParseError(str(exc))
@classmethod
raise ParseError("unknown initial character %r" % start)
def __repr__(self):
- return "%s(type=%r, bullets=%r, actions=%r, fires=%r)" % (
- type(self).__name__, self.type, self.bullets, self.actions,
- self.fires)
+ return "%s(type=%r, actions=%r)" % (
+ type(self).__name__, self.type, self.actions)
ActionDef.CONSTRUCTORS = dict(
repeat=Repeat,