From 9936040ffc0fdf65d29757efc56135d172741eb6 Mon Sep 17 00:00:00 2001 From: mike Date: Sat, 28 Feb 2009 05:50:30 +0000 Subject: TutoriusV1 : Modifying the State and FSM classes to fit with the Event Filters (ongoing) --- diff --git a/src/sugar/tutorius/core.py b/src/sugar/tutorius/core.py index 45eee3a..9d0cba2 100644 --- a/src/sugar/tutorius/core.py +++ b/src/sugar/tutorius/core.py @@ -122,72 +122,155 @@ class Tutorial (object): class State: """This is a step in a tutorial. The state represents a collection of - actions to undertake when entering the state, and a description of an - event filter with associated actions to go to the next state.""" + actions to undertake when entering the state, and a series of event filters + with associated actions that point to a possible next state.""" - def __init__(self): + def __init__(self, action_list=[], event_filter_list=[]): """Initializes the content of the state, as in loading the actions - that are required and building the correct tests.""" - self.actions = [] - self.tests = [] + that are required and building the correct tests. + + @param action_list The list of actions to execute when entering this + state + @param event_filter_list A list of tuples of the form + (event_filter, next_state_name), that explains the outgoing links for + this state""" + self._actions = action_list + + # Unused for now + #self.tests = [] + + self._event_filters = event_filter_list def setup(self): """Install the state itself. This is the best time to pop-up a dialog that has to remain for the duration of the state.""" - for act in self.actions: + for action in self._actions: act.do() - def teardown(self): """Undo every action that was installed for this state. This means removing dialogs that were displayed, removing highlights, etc...""" - for act in self.actions: + for act in self._actions: act.undo() - - def verify(self): - """Run the internal tests to see if one of them passes. If it does, - then do the associated processing to go in the next state.""" - for test in self.tests: - if test.verify() == True: - actions = test.get_actions() - for act in actions: - act.do() - # Now that we execute the actions related to a test, we might - # want to undo them right after --- should we use a callback or - # a timer? + # Unused for now +## def verify(self): +## """Run the internal tests to see if one of them passes. If it does, +## then do the associated processing to go in the next state.""" +## for test in self.tests: +## if test.verify() == True: +## actions = test.get_actions() +## for act in actions: +## act.do() +## # Now that we execute the actions related to a test, we might +## # want to undo them right after --- should we use a callback or +## # a timer? class FiniteStateMachine(State): """This is a collection of states, with a start state and an end callback. It is used to simplify the development of the various tutorials by encapsulating a collection of states that represent a given learning process.""" - def __init__(self, start_state, setup_actions): + + def __init__(self, state_dict={}, start_state_name="INIT", setup_actions=[]): """The constructor for a FSM. Pass in the start state and the setup actions that need to be taken when the FSM itself start (which may be - different from what is done in the first state of the machine).""" + different from what is done in the first state of the machine). + + @param state_dict A dictionary containing the state names as keys and + the state themselves as entries. + @param start_state_name The name of the starting state, if different + from "INIT" + @param setup_actions The actions to undertake when initializing the FSM + """ State.__init__(self) - self.start_state = start_state + # Dictionnary of states contained in the FSM + self._states = state_dict + + # Remember the initial state - we might want to reset + # or rewind the FSM at a later moment + self.start_state = state_dict[start_state] + + # Register the actions for the FSM - They will be processed at the + # FSM level, meaning that when the FSM will start, it will first + # execute those actions. When the FSM closes, it will tear down the + # inner actions of the state, then close its own actions self.actions = setup_actions self.current_state = self.start_state + + # Flag to mention that the FSM was initialized + self._fsm_setup_done = False + # Flag that must be raised when the FSM is to be teared down + self._fsm_teardown_done = False + # Flag used to declare that the FSM has reached an end state + self._fsm_has_finished = False + def setup(self): """ - Set up the FSM + Set up the FSM the first time, then setup the inner state """ - for act in self.actions: - act.do() + # If we never initialized the FSM itself, then we need to run all the + # actions associated with the FSM. + if self._fsm_setup_done == False: + # Flag the FSM level setup as done + self._fsm_setup_done = True + # Execute all the FSM level actions + for act in self.actions: + act.do() + + # Then, we need to run the setup of the current state + self.current_state.setup() + + def set_state(self, new_state_name): + """ + This functions changes the current state of the finite state machine. + + @param new_state The identifier of the state we need to go to + """ + # Pass in the name to the internal state - it might be a FSM and + # this name will apply to it + self.current_state.set_state(new_state_name) + + # Make sure the given state is owned by the FSM + if not self._states.haskey(new_state_name): + # If we did not recognize the name, then we do not possess any + # state by that name - we must ignore this state change request as + # it will be done elsewhere in the hierarchy (or it's just bogus). + return + + new_state = self._states[new_state_name] + + # Undo the actions of the old state + self.current_state.teardown() + + # Insert the new state + self.current_state = new_state + + # Call the initial actions in the new state + self.current_state.setup() + def teardown(self): """ Revert any changes done by setup() """ - for act in self.actions: - act.undo() - - def verify(self): - "Verify if the current state passes it's tests""" - return self.current_state.verify() + # Teardown the current state + self.current_state.teardown() + + # If we just finished the whole FSM, we need to also call the teardown + # on the FSM level actions + if self._fsm_has_finished == True: + # Flag the FSM teardown as not needed anymore + self._fsm_teardown_done = False + # Undo all the FSM level actions here + for act in self.actions: + act.undo() + + #Unused for now +## def verify(self): +## """Verify if the current state passes its tests""" +## return self.current_state.verify() -- cgit v0.9.1