diff --git a/lib/dialogwizard/wizard.py b/lib/dialogwizard/wizard.py index a22ffa83..f6f4c00b 100755 --- a/lib/dialogwizard/wizard.py +++ b/lib/dialogwizard/wizard.py @@ -43,6 +43,18 @@ class Scenario: raise TypeError("Can only bind steps") self.steps = ('NEST', step, self.steps) + def case(self, switch, cases, fallback = None): #revoir le fallback + u"""Calls a function (passing to it the environment), and will + call the corresponding scenario in the second arg.""" + if not callable(switch): + raise TypeError("switch must be callable") + if not isinstance(cases, dict): + raise TypeError("cases must be a dict") + for case in cases.values(): + if not isinstance(case, Scenario): + raise TypeError("cases must all be Scenarios") + self.steps = ('CASE', (switch, cases, fallback), self.steps) + def branch(self, cond, plan_A, plan_B): u"""Makes a test (will call it passing the environnement), and depending on the result, will process one of the two scenarios""" @@ -50,7 +62,8 @@ class Scenario: raise TypeError("cond must be callable") if not isinstance(plan_A, Scenario) or not isinstance(plan_B, Scenario): raise TypeError("Can only branch on scenarios") - self.steps = ('BRANCH', (cond, plan_A, plan_B) , self.steps) +# self.steps = ('BRANCH', (cond, plan_A, plan_B) , self.steps) + self.case(cond, { True: plan_A, False: plan_B }) def quote(self, scenario): u"""Runs a scenario as a single scenario step""" @@ -87,21 +100,32 @@ class Running: def step(self): if self.steps: - # Case of a Branching - if self.steps[0] == 'BRANCH' : - # As it is (should be) an epsilon-test we won't - # backtrack it. - cond, plan_A, plan_B = self.steps[1] + # Case of a Case, as a list of possible choices depending on + # the result of a function call, if it is not handled, then + # it does nothing. + if self.steps[0] == 'CASE' : + switch, cases, fallback = self.steps[1] self.steps = self.steps[2] - if cond(self.env): - plan_steps = plan_A.steps - else: - plan_steps = plan_B.steps - # Let's not forget we need to reverse the steps lists. + plan_steps = cases.get(switch(self.env), fallback).steps while plan_steps: self.steps = plan_steps[0], plan_steps[1], self.steps plan_steps = plan_steps[2] + ## # Case of a Branching + ## if self.steps[0] == 'BRANCH' : + ## # As it is (should be) an epsilon-test we won't + ## # backtrack it. + ## cond, plan_A, plan_B = self.steps[1] + ## self.steps = self.steps[2] + ## if cond(self.env): + ## plan_steps = plan_A.steps + ## else: + ## plan_steps = plan_B.steps + ## # Let's not forget we need to reverse the steps lists. + ## while plan_steps: + ## self.steps = plan_steps[0], plan_steps[1], self.steps + ## plan_steps = plan_steps[2] + # Case of nesting elif self.steps[0] == 'NEST': try: