# Copyright (C) 2009, Tutorius.org # Greatly influenced by sugar/activity/namingalert.py # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA from sugar.tutorius.core import * from sugar.tutorius.actions import * from sugar.tutorius.filters import * from copy import deepcopy class LinearCreator(object): """ This class is used to create a FSM from a linear sequence of orders. The orders themselves are meant to be either an action or a transition. """ def __init__(self): self.fsm = FiniteStateMachine("Sample Tutorial") self.current_actions = [] self.nb_state = 0 self.state_name = "INIT" def set_name(self, name): """ Sets the name of the generated FSM. """ self.fsm.name = name def action(self, action): """ Adds an action to execute in the current state. """ self.current_actions.append(action) def event(self, event_filter): """ Adds a transition to another state. When executing this, all the actions previously called will be bundled in a single state, with the exit condition of this state being the transition just added. Whatever the name of the next state you inserted in the event, it will be replaced to point to the next event in the line. """ if len(self.current_actions) != 0: # Set the next state name - there is no way the caller should have # to deal with that. next_state_name = "State %d" % (self.nb_state+1) event_filter.set_next_state(next_state_name) state = State(self.state_name, action_list=self.current_actions, event_filter_list=[event_filter]) self.state_name = next_state_name self.nb_state += 1 self.fsm.add_state(state) # Clear the actions from the list self.current_actions = [] def generate_fsm(self): """ Returns a finite state machine corresponding to the sequence of calls that were made from this point on. """ # Copy the whole FSM that was generated yet new_fsm = deepcopy(self.fsm) # Generate the final state state = None if len(self.current_actions) != 0: state = State("State" + str(self.nb_state), action_list=self.current_actions) # Don't increment the nb_state here - we would break the linearity # because we might generate more stuff with this creator later. # Since we rely on linearity for continuity when generating the # next state's name on an event filter, we cannot increment here. else: state = State("State" + str(self.nb_state)) # Insert the state in the copy of the FSM new_fsm.add_state(state) return new_fsm