From ebb94ef8194ec1e9d22b979e2f5a64a2b182102f Mon Sep 17 00:00:00 2001 From: mike Date: Wed, 25 Nov 2009 18:49:32 +0000 Subject: LP 448319 : Cleaning up code a bit to make the FSM structure more obvious, Adding bubblemessage with image from Dave --- (limited to 'tutorius') diff --git a/tutorius/engine.py b/tutorius/engine.py index be0b935..34616f6 100644 --- a/tutorius/engine.py +++ b/tutorius/engine.py @@ -37,7 +37,6 @@ RUNNER_STATE_SETUP_EVENTS = 2 RUNNER_STATE_AWAITING_NOTIFICATIONS = 3 RUNNER_STATE_UNINSTALLING_ACTIONS = 4 RUNNER_STATE_UNSUBSCRIBING_EVENTS = 5 -RUNNER_STATE_STOPPED = 6 LOGGER = logging.getLogger("sugar.tutorius.engine") @@ -82,7 +81,9 @@ class TutorialRunner(object): #Temp FIX until event, actions have an activity id def setCurrentActivity(self): self._pM.currentActivity = self._activity_id - + + ########################################################################### + # Incoming messages def start(self): self.setCurrentActivity() #Temp Hack until activity in events/actions self.enterState(self._tutorial.INIT) @@ -94,10 +95,78 @@ class TutorialRunner(object): else: self._execute_stop() + def action_installed(self, action_name, action, address): + LOGGER.debug("TutorialRunner :: Action %s received address %s"%(action_name, address)) + self._installed_actions[action_name] = address + # Verify if we just completed the installation of the actions for this state + self._verify_action_install_state() + + def install_error(self, action_name, action, exception): + # TODO : Fix this as it doesn't warn the user about the problem or anything + LOGGER.debug("TutorialRunner :: Action could not be installed %s, exception was : %s"%(str(action), str(exception))) + self._installation_errors[action_name] = exception + self._verify_action_install_state() + + def event_subscribed(self, event_name, event_address): + LOGGER.debug("TutorialRunner :: Event %s was subscribed to, located at address %s"%(event_name, event_address)) + self._subscribed_events[event_name] = event_address + + # Verify if we just completed the subscription of all the events for this state + self._verify_event_install_state() + + def subscribe_error(self, event_name, exception): + # TODO : Do correct error handling here + LOGGER.debug("TutorialRunner :: Could not subscribe to event %s, got exception : %s"%(event_name, str(exception))) + self._subscription_errors[event_name] = exception + + # Verify if we just completed the subscription of all the events for this state + self._verify_event_install_state() + + def all_actions_installed(self): + self._runner_state = RUNNER_STATE_SETUP_EVENTS + # Process the messages that might have been stored + self._process_pending_messages() + + # If we processed a message that changed the runner state, we need to stop + # processing + if self._runner_state != RUNNER_STATE_SETUP_EVENTS: + return + + # Start subscribing to events + transitions = self._tutorial.get_transition_dict(self._state) + + # If there are no transitions, raise the All Events Subscribed message + if len(transitions) == 0: + self.all_events_subscribed() + return + + # Send all the event registration + for (event_name, (event, next_state)) in transitions.items(): + self._pM.subscribe(event_name, event, + save_args(self._handleEvent, next_state), + save_args(self.event_subscribed, event_name), + save_args(self.subscribe_error, event_name)) + + def all_events_subscribed(self): + self._runner_state = RUNNER_STATE_AWAITING_NOTIFICATIONS + self._process_pending_messages() + + def _uninstall_actions(self): + self._runner_state = RUNNER_STATE_UNINSTALLING_ACTIONS + self._remove_installed_actions() + self._execute_stop() + + def _unsubscribe_events(self): + self._runner_state = RUNNER_STATE_UNSUBSCRIBING_EVENTS + self._remove_subscribed_events() + self._uninstall_actions() + + ########################################################################### + # Helper functions def _execute_stop(self): self.setCurrentActivity() #Temp Hack until activity in events/actions self._state = None - self._runner_state = RUNNER_STATE_STOPPED + self._runner_state = RUNNER_STATE_IDLE def _handleEvent(self, next_state, event): # Look if we are actually receiving notifications @@ -136,19 +205,7 @@ class TutorialRunner(object): self._subscribed_events.clear() self._subscription_errors.clear() - def __action_installed(self, action_name, action, address): - LOGGER.debug("TutorialRunner :: Action %s received address %s"%(action_name, address)) - self._installed_actions[action_name] = address - # Verify if we just completed the installation of the actions for this state - self.__verify_action_install_state() - - def __install_error(self, action_name, action, exception): - # TODO : Fix this as it doesn't warn the user about the problem or anything - LOGGER.debug("TutorialRunner :: Action could not be installed %s, exception was : %s"%(str(action), str(exception))) - self._installation_errors[action_name] = exception - self.__verify_action_install_state() - - def __verify_action_install_state(self): + def _verify_action_install_state(self): # Do the check to see if we have finished installing all the actions by either having # received a address for it or an error message install_complete = True @@ -162,24 +219,9 @@ class TutorialRunner(object): if install_complete: LOGGER.debug("TutorialRunner :: All actions installed!") # Raise the All Actions Installed event for the TutorialRunner state - self.__all_actions_installed() + self.all_actions_installed() - def __event_subscribed(self, event_name, event_address): - LOGGER.debug("TutorialRunner :: Event %s was subscribed to, located at address %s"%(event_name, event_address)) - self._subscribed_events[event_name] = event_address - - # Verify if we just completed the subscription of all the events for this state - self.__verify_event_install_state() - - def __subscribe_error(self, event_name, exception): - # TODO : Do correct error handling here - LOGGER.debug("TutorialRunner :: Could not subscribe to event %s, got exception : %s"%(event_name, str(exception))) - self._subscription_errors[event_name] = exception - - # Verify if we just completed the subscription of all the events for this state - self.__verify_event_install_state() - - def __verify_event_install_state(self): + def _verify_event_install_state(self): transitions = self._tutorial.get_transition_dict(self._state) # Check to see if we completed all the event subscriptions @@ -192,48 +234,9 @@ class TutorialRunner(object): if subscribe_complete: LOGGER.debug("TutorialRunner : Subscribed to all events!") - self.__all_events_subscribed() - - def __all_actions_installed(self): - self._runner_state = RUNNER_STATE_SETUP_EVENTS - # Process the messages that might have been stored - self.__process_pending_messages() + self.all_events_subscribed() - # If we processed a message that changed the runner state, we need to stop - # processing - if self._runner_state != RUNNER_STATE_SETUP_EVENTS: - return - - # Start subscribing to events - transitions = self._tutorial.get_transition_dict(self._state) - - # If there are no transitions, raise the All Events Subscribed message - if len(transitions) == 0: - self.__all_events_subscribed() - return - - # Send all the event registration - for (event_name, (event, next_state)) in transitions.items(): - self._pM.subscribe(event_name, event, - save_args(self._handleEvent, next_state), - save_args(self.__event_subscribed, event_name), - save_args(self.__subscribe_error, event_name)) - - def __all_events_subscribed(self): - self._runner_state = RUNNER_STATE_AWAITING_NOTIFICATIONS - self.__process_pending_messages() - - def __uninstall_actions(self): - self._runner_state = RUNNER_STATE_UNINSTALLING_ACTIONS - self._remove_installed_actions() - self._execute_stop() - - def __unsubscribe_events(self): - self._runner_state = RUNNER_STATE_UNSUBSCRIBING_EVENTS - self._remove_subscribed_events() - self.__uninstall_actions() - - def __process_pending_messages(self): + def _process_pending_messages(self): while len(self._message_queue) != 0: (priority, message) = heappop(self._message_queue) @@ -245,9 +248,9 @@ class TutorialRunner(object): # Start removing the installed addons if self._runner_state == RUNNER_STATE_AWAITING_NOTIFICATIONS: # Start uninstalling the events - self.__unsubscribe_events() + self._unsubscribe_events() if self._runner_state == RUNNER_STATE_SETUP_EVENTS: - self.__uninstall_actions() + self._uninstall_actions() elif priority == EVENT_NOTIFICATION_MSG_PRIORITY: LOGGER.debug("TutorialRunner :: Handling stored event notification for next_state %s"%message[0]) self._handle_event(*message) @@ -259,22 +262,22 @@ class TutorialRunner(object): self._actions = self._tutorial.get_action_dict(self._state) if len(self._actions) == 0: - self.__all_actions_installed() + self.all_actions_installed() return for (action_name, action) in self._actions.items(): LOGGER.debug("TutorialRunner :: Installed action %s"%(action_name)) self._pM.install(action, - save_args(self.__action_installed, action_name), - save_args(self.__install_error, action_name)) + save_args(self.action_installed, action_name), + save_args(self.install_error, action_name)) def enterState(self, state_name): """ - Starting from the state_name, the runner execute states until - no automatic transition are found and will wait for an external - event to occur. + Starting from the state_name, the runner execute states from the + tutorial until no automatic transitions are found and will wait + for an external event to occur. - When entering the state, actions and events from the previous + When entering the sate, actions and events from the previous state are respectively uninstalled and unsubscribed and actions and events from the state_name will be installed and subscribed. -- cgit v0.9.1