Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tutorius/engine.py
diff options
context:
space:
mode:
Diffstat (limited to 'tutorius/engine.py')
-rw-r--r--tutorius/engine.py111
1 files changed, 101 insertions, 10 deletions
diff --git a/tutorius/engine.py b/tutorius/engine.py
index e77a018..b0a49a8 100644
--- a/tutorius/engine.py
+++ b/tutorius/engine.py
@@ -4,17 +4,100 @@ from jarabe.model import shell
from sugar.bundle.activitybundle import ActivityBundle
from .vault import Vault
+from .TProbe import ProbeManager
+from .dbustools import save_args
+
+
+class TutorialRunner(object):
+ """
+ Driver for the execution of one tutorial
+ """
+ def __init__(self, tutorial, probeManager):
+ """Constructor
+ @param tutorial Tutorial to execute
+ @param probeManager probeManager to use
+ """
+ self._tutorial = tutorial
+ self._pM = probeManager
+
+ #State
+ self._state = None
+ self._sEvents = set() #Subscribed Events
+
+ #Cached objects
+ self._actions = {}
+
+ #Temp FIX until event/actions have an activity id
+ self._activity_id = None
+
+ #Temp FIX until event, actions have an activity id
+ def setCurrentActivity(self):
+ self._pM.currentActivity = self._activity_id
+
+ def start(self):
+ self.setCurrentActivity() #Temp Hack until activity in events/actions
+ self.setState(self._tutorial.INIT)
+
+ def stop(self):
+ self.setCurrentActivity() #Temp Hack until activity in events/actions
+ self.setState(self._tutorial.END)
+ self._teardownState()
+ self._state = None
+
+ def _handleEvent(self, next_state, event):
+ #FIXME sanity check
+ self.setState(next_state)
+
+ def _teardownState(self):
+ if self._state is None:
+ #No state, no teardown
+ return
+
+ #Clear the current actions
+ for action in self._actions.values():
+ self._pM.uninstall(action)
+ self._actions = {}
+
+ #Clear the EventFilters
+ for event in self._sEvents:
+ self._pM.unsubscribe(event)
+ self._sEvents.clear()
+
+ def _setupState(self):
+ if self._state is None:
+ raise RuntimeError("Attempting to setupState without a state")
+
+ self._actions = self._tutorial.get_action_dict(self._state)
+ transitions = self._tutorial.get_transition_dict(self._state)
+ for (event, next_state) in transitions.values():
+ self._sEvents.add(self._pM.subscribe(event, save_args(self._handleEvent, next_state)))
+ for action in self._actions.values():
+ self._pM.install(action)
+
+ def setState(self, state_name):
+ self.setCurrentActivity() #Temp Hack until activity in events/actions
+ if state_name == self._state:
+ #Nothing to do
+ return
+
+ self._teardownState()
+ self._state = state_name
+ self._setupState()
+
class Engine:
"""
Driver for the execution of tutorials
"""
- def __init__(self):
- # FIXME Probe management should be in the probe manager
+ def __init__(self, probeManager=None):
+ """Constructor
+ @param probeManager (optional) ProbeManager instance to use
+ """
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
#FIXME shell.get_model() will only be useful in the shell process
self._shell = shell.get_model()
+ self._probeManager = probeManager or ProbeManager()
self._tutorial = None
def launch(self, tutorialID):
@@ -22,25 +105,33 @@ class Engine:
@param tutorialID unique tutorial identifier used to retrieve it from the disk
"""
if self._tutorial:
- self._tutorial.detach()
- self._tutorial = None
+ self.stop()
+
+ self._tutorial = TutorialRunner(Vault.loadTutorial(tutorialID), self._probeManager)
#Get the active activity from the shell
activity = self._shell.get_active_activity()
- self._tutorial = Vault.loadTutorial(tutorialID)
-
#TProbes automatically use the bundle id, available from the ActivityBundle
bundle = ActivityBundle(activity.get_bundle_path())
- self._tutorial.attach(bundle.get_bundle_id())
- def stop(self):
+ self._tutorial._activity_id = bundle.get_bundle_id() #HACK until we have activity id's in action/events
+
+ self._tutorial.start()
+
+ def stop(self, tutorialID=None):
""" Stop the current tutorial
"""
- self._tutorial.detach()
+ if tutorialID is None:
+ logging.warning(
+ "stop() without a tutorialID will become deprecated")
+ self._tutorial.stop()
self._tutorial = None
- def pause(self):
+ def pause(self, tutorialID=None):
""" Interrupt the current tutorial and save its state in the journal
"""
+ if tutorialID is None:
+ logging.warning( \
+ "pause() without a tutorialID will become deprecated")
raise NotImplementedError("Unable to store tutorial state")