If: Conditional actions.
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 21 Apr 2010 05:21:09 +0000 (22:21 -0700)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 21 Apr 2010 05:21:09 +0000 (22:21 -0700)
bulletml/parser.py
examples/normal/twofire-if.xml [new file with mode: 0644]

index 653b90f..2075ac9 100644 (file)
@@ -377,6 +377,58 @@ class Repeat(object):
     def __repr__(self):
         return "%s(%r, %r)" % (type(self).__name__, self.times, self.action)
 
+class If(object):
+    """Conditional actions."""
+
+    def __init__(self, cond, then, else_=None):
+        self.cond = cond
+        self.then = then
+        self.else_ = else_
+
+    def __getstate__(self):
+        if self.else_:
+            return [('cond', self.cond.expr),
+                    ('then', self.then),
+                    ('else', self.else_)]
+        else:
+            return [('cond', self.cond.expr), ('then', self.then)]
+
+    def __setstate__(self, state):
+        state = dict(state)
+        state["else_"] = state.pop("else", None)
+        state["cond"] = INumberDef(state["cond"])
+        self.__init__(**state)
+
+    @classmethod
+    def FromXML(cls, doc, element):
+        """Construct using an ElementTree-style element."""
+        else_ = None
+        for subelem in element.getchildren():
+            tag = realtag(subelem)
+            if tag == "cond":
+                cond = INumberDef(subelem.text)
+            elif tag == "then":
+                then = ActionDef.FromXML(doc, subelem)
+            elif tag == "else":
+                else_ = ActionDef.FromXML(doc, subelem)
+        try:
+            return cls(cond, then, else_)
+        except UnboundLocalError as exc:
+            raise ParseError(str(exc))
+
+    def __call__(self, owner, action, params, rank, created):
+        if self.cond(params, rank):
+            branch = self.then
+        else:
+            branch = self.else_
+
+        if branch:
+            actions, params = branch(params, rank)
+            child = action.__class__(owner, action, actions, params, rank)
+            owner.replace(action, child)
+            child.step(owner, created)
+            return True
+        
 class Accel(object):
     """Accelerate over some time."""
 
@@ -976,3 +1028,4 @@ ActionDef.CONSTRUCTORS = dict(
     untag=Untag,
     action=ActionDef,
     actionRef=ActionRef)
+ActionDef.CONSTRUCTORS["if"] = If
diff --git a/examples/normal/twofire-if.xml b/examples/normal/twofire-if.xml
new file mode 100644 (file)
index 0000000..ddc1b8f
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" ?>\r
+<!DOCTYPE bulletml SYSTEM "http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/bulletml.dtd">\r
+\r
+<bulletml xmlns="http://www.asahi-net.or.jp/~cs8k-cyu/bulletml"\r
+         xmlns:py="http://code.google.com/p/python-bulletml/">\r
+\r
+  <action label="top">\r
+    <actionRef label="threefire">\r
+      <param>10 + 20 * $rank * $rand</param>\r
+    </actionRef>\r
+  </action>\r
+\r
+  <action label="threefire">\r
+    <fire>\r
+      <bulletRef label="dropper">\r
+       <param>$1</param>\r
+       <param>0</param>\r
+      </bulletRef>\r
+      <direction>0</direction>\r
+    </fire>\r
+    <py:if>\r
+      <py:cond>$rand > 0.5</py:cond>\r
+      <py:then>\r
+       <fire>\r
+         <bulletRef label="dropper">\r
+           <param>$1</param>\r
+           <param>-90</param>\r
+         </bulletRef>\r
+         <direction type="sequence">-90</direction>\r
+       </fire>\r
+      </py:then>\r
+      <py:else>\r
+       <fire>\r
+         <bulletRef label="dropper">\r
+           <param>$1</param>\r
+           <param>90</param>\r
+         </bulletRef>\r
+         <direction type="sequence">90</direction>\r
+       </fire>\r
+      </py:else>\r
+    </py:if>\r
+  </action>\r
+\r
+  <bullet label="dropper">\r
+    <speed>1</speed>\r
+    <action>\r
+      <wait>3</wait>\r
+      <changeSpeed>\r
+       <term>1</term>\r
+       <speed>0</speed>\r
+      </changeSpeed>\r
+      <changeDirection>\r
+       <term>1</term>\r
+       <direction type="relative">-$2</direction>\r
+      </changeDirection>\r
+      <wait>1</wait>\r
+      <repeat>\r
+       <times>$1</times>\r
+       <action>\r
+         <fire>\r
+           <bullet>\r
+             <direction type="relative">0</direction>\r
+             <speed type="absolute">1</speed>\r
+           </bullet>\r
+         </fire>\r
+         <wait>4</wait>\r
+       </action>\r
+      </repeat>\r
+      <changeSpeed>\r
+       <term>1</term>\r
+       <speed>1</speed>\r
+      </changeSpeed>\r
+    </action>\r
+  </bullet>\r
+</bulletml>\r