diff options
Diffstat (limited to 'tutorius/core.py')
-rw-r--r-- | tutorius/core.py | 64 |
1 files changed, 30 insertions, 34 deletions
diff --git a/tutorius/core.py b/tutorius/core.py index 8ab0b51..f51c5fb 100644 --- a/tutorius/core.py +++ b/tutorius/core.py @@ -25,6 +25,7 @@ import logging import os from sugar.tutorius.TProbe import ProbeManager +from sugar.tutorius.dbustools import save_args from sugar.tutorius import addon logger = logging.getLogger("tutorius") @@ -92,17 +93,6 @@ class Tutorial (object): self.state_machine.set_state(name) - # Currently unused -- equivalent function is in each state - def _eventfilter_state_done(self, eventfilter): - """ - Callback handler for eventfilter to notify - when we must go to the next state. - """ - #XXX Tests should be run here normally - - #Swith to the next state pointed by the eventfilter - self.set_state(eventfilter.get_next_state()) - def _prepare_activity(self): """ Prepare the activity for the tutorial by loading the saved state and @@ -116,7 +106,8 @@ class Tutorial (object): self.activity_init_state_filename readfile = addon.create("ReadFile", filename=filename) if readfile: - self._probeMgr.install(self._activity_id, readfile) + self._probeMgr.install(readfile) + self._probeMgr.uninstall(readfile) class State(object): """ @@ -146,7 +137,9 @@ class State(object): # Unused for now #self.tests = [] - self._event_filters = event_filter_list or [] + self._transitions= dict(event_filter_list or []) + + self._installedEvents = set() self.tutorial = tutorial @@ -170,8 +163,8 @@ class State(object): Install the state itself, by first registering the event filters and then triggering the actions. """ - for eventfilter in self._event_filters: - self.tutorial.probeManager.subscribe(eventfilter, self._event_filter_state_done_cb ) + for (event, next_state) in self._transitions.items(): + self._installedEvents.add(self.tutorial.probeManager.subscribe(event, save_args(self._event_filter_state_done_cb, next_state ))) for action in self._actions: self.tutorial.probeManager.install(action) @@ -183,24 +176,25 @@ class State(object): removing dialogs that were displayed, removing highlights, etc... """ # Remove the handlers for the all of the state's event filters - for event_filter in self._event_filters: - self.tutorial.probeManager.unsubscribe(event_filter, self._event_filter_state_done_cb ) + while len(self._installedEvents) > 0: + self.tutorial.probeManager.unsubscribe(self._installedEvents.pop()) # Undo all the actions related to this state for action in self._actions: self.tutorial.probeManager.uninstall(action) - def _event_filter_state_done_cb(self, event_filter): + def _event_filter_state_done_cb(self, next_state, event): """ Callback for event filters. This function needs to inform the tutorial that the state is over and tell it what is the next state. - @param event_filter The event filter that was called + @param next_state The next state for the transition + @param event The event that occured """ # Run the tests here, if need be # Warn the higher level that we wish to change state - self.tutorial.set_state(event_filter.get_next_state()) + self.tutorial.set_state(next_state) # Model manipulation # These functions are used to simplify the creation of states @@ -230,19 +224,21 @@ class State(object): Removes all the action associated with this state. A cleared state will not do anything when entered or exited. """ + #FIXME What if the action is currently installed? self._actions = [] - def add_event_filter(self, event_filter): + def add_event_filter(self, event, next_state): """ Adds an event filter that will cause a transition from this state. The same event filter may not be added twice. - @param event_filter The new event filter that will trigger a transition + @param event The event that will trigger a transition + @param next_state The state to which the transition will lead @return True if added, False otherwise """ - if event_filter not in self._event_filters: - self._event_filters.append(event_filter) + if event not in self._transitions.keys(): + self._transitions[event]=next_state return True return False @@ -250,7 +246,7 @@ class State(object): """ @return The list of event filters associated with this state. """ - return self._event_filters + return self._transitions.items() def clear_event_filters(self): """ @@ -258,7 +254,7 @@ class State(object): was just cleared will become a sink and will be the end of the tutorial. """ - self._event_filters = [] + self._transitions = {} class FiniteStateMachine(State): """ @@ -471,9 +467,9 @@ class FiniteStateMachine(State): #TODO : Move this code inside the State itself - we're breaking # encap :P - for event_filter in st._event_filters: - if event_filter.get_next_state() == state_name: - st._event_filters.remove(event_filter) + for event, state in st._transitions: + if state == state_name: + del st._transitions[event] # Remove the state from the dictionary del self._states[state_name] @@ -491,8 +487,8 @@ class FiniteStateMachine(State): next_states = set() - for event_filter in state._event_filters: - next_states.add(event_filter.get_next_state()) + for event, state in state._transitions: + next_states.add(state) return tuple(next_states) @@ -514,9 +510,9 @@ class FiniteStateMachine(State): states = [] # Walk through the list of states for st in self._states.itervalues(): - for event_filter in st._event_filters: - if event_filter.get_next_state() == state_name: - states.append(event_filter.get_next_state()) + for event, state in st._transitions: + if state == state_name: + states.append(state) continue return tuple(states) |