Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tutorius
diff options
context:
space:
mode:
Diffstat (limited to 'tutorius')
-rw-r--r--tutorius/TProbe.py64
-rw-r--r--tutorius/dbustools.py16
-rw-r--r--tutorius/engine.py45
3 files changed, 97 insertions, 28 deletions
diff --git a/tutorius/TProbe.py b/tutorius/TProbe.py
index 3a57161..37a5e0f 100644
--- a/tutorius/TProbe.py
+++ b/tutorius/TProbe.py
@@ -1,3 +1,19 @@
+# Copyright (C) 2009, Tutorius.org
+#
+# 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 1 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
+
import logging
LOGGER = logging.getLogger("sugar.tutorius.TProbe")
import os
@@ -13,7 +29,7 @@ from . import addon
from .services import ObjectStore
from .properties import TPropContainer
-from .dbustools import remote_call, save_args
+from .dbustools import remote_call, save_args, ignore, logError
import copy
"""
@@ -305,18 +321,19 @@ class ProbeProxy:
def __clear_action(self, action):
self._actions.pop(action, None)
- def install(self, action, callback, block=False):
+ def install(self, action, action_installed_cb, error_cb):
"""
Install an action on the TProbe's activity
@param action Action to install
- @param block Force a synchroneous dbus call if True
+ @param action_installed_cb The callback function to call once the action is installed
+ @param error_cb The callback function to call when an error happens
@return None
"""
- return remote_call(self._probe.install, (pickle.dumps(action),),
- save_args(self.__update_action, action, callback),
- block=block)
+ self._probe.install(pickle.dumps(action),
+ reply_handler=save_args(self.__update_action, action, action_installed_cb),
+ error_handler=save_args(error_cb, action))
- def update(self, action_address, newaction, block=False):
+ def update(self, action_address, newaction):
"""
Update an already installed action's properties and run it again
@param action_address The address of the action to update. This is
@@ -329,9 +346,9 @@ class ProbeProxy:
if not action_address in self._actions.values():
raise RuntimeWarning("Action not installed")
#TODO Check error handling
- return remote_call(self._probe.update, (action_address, pickle.dumps(newaction._props)), block=block)
+ return remote_call(self._probe.update, (action_address, pickle.dumps(newaction._props)), block=False)
- def uninstall(self, action_address, block=False):
+ def uninstall(self, action_address):
"""
Uninstall an installed action
@param action_address The address of the action to uninstall. This address was given
@@ -340,7 +357,7 @@ class ProbeProxy:
"""
for (this_action, this_address) in self._actions.items():
if this_address == action_address:
- remote_call(self._probe.uninstall,(action_address,), block=block)
+ remote_call(self._probe.uninstall,(action_address,))
del self._actions[this_action]
break
@@ -392,11 +409,13 @@ class ProbeProxy:
else:
LOGGER.debug("ProbeProxy :: unsubsribe address %s inconsistency : not registered", address)
- def subscribe(self, event, callback, block=True):
+ def subscribe(self, event, notification_cb, event_installed_cb=ignore, error_cb=logError, block=True):
"""
Register an event listener
@param event Event to listen for
- @param callback callable that will be called when the event occurs
+ @param notification_cb callable that will be called when the event occurs
+ @param event_installed_cb callable that will be called once the event is subscribed to
+ @param error_cb callable that will be called if the subscription fails
@param block Force a synchroneous dbus call if True (Not allowed yet)
@return address identifier used for unsubscribing
"""
@@ -408,7 +427,8 @@ class ProbeProxy:
# for event types and sources, we will need to revise the lookup
# mecanism for which callback function to call
return remote_call(self._probe.subscribe, (pickle.dumps(event),),
- save_args(self.__update_event, event, callback),
+ return_cb=save_args(self.__update_event, event, notification_cb),
+ error_cb=save_args(error_cb, event),
block=block)
def unsubscribe(self, address, block=True):
@@ -432,10 +452,10 @@ class ProbeProxy:
subscribed events should be removed.
"""
for action_addr in self._actions.keys():
- self.uninstall(action_addr, block)
+ self.uninstall(action_addr)
for address in self._subscribedEvents.keys():
- self.unsubscribe(address, block)
+ self.unsubscribe(address)
class ProbeManager(object):
@@ -471,19 +491,21 @@ class ProbeManager(object):
currentActivity = property(fget=getCurrentActivity, fset=setCurrentActivity)
- def install(self, action, callback, block=False):
+ def install(self, action, action_installed_cb, error_cb):
"""
Install an action on the current activity
@param action Action to install
+ @param action_installed_cb The callback to call once the action is installed
+ @param error_cb The callback that will be called if there is an error during installation
@param block Force a synchroneous dbus call if True
@return None
"""
if self.currentActivity:
- return self._first_proxy(self.currentActivity).install(action, callback, block)
+ return self._first_proxy(self.currentActivity).install(action, action_installed_cb, error_cb)
else:
raise RuntimeWarning("No activity attached")
- def update(self, action_address, newaction, block=False):
+ def update(self, action_address, newaction):
"""
Update an already installed action's properties and run it again
@param action_address Action to update
@@ -492,18 +514,18 @@ class ProbeManager(object):
@return None
"""
if self.currentActivity:
- return self._first_proxy(self.currentActivity).update(action_address, newaction, block)
+ return self._first_proxy(self.currentActivity).update(action_address, newaction)
else:
raise RuntimeWarning("No activity attached")
- def uninstall(self, action_address, block=False):
+ def uninstall(self, action_address):
"""
Uninstall an installed action
@param action Action to uninstall
@param block Force a synchroneous dbus call if True
"""
if self.currentActivity:
- return self._first_proxy(self.currentActivity).uninstall(action_address, block)
+ return self._first_proxy(self.currentActivity).uninstall(action_address)
else:
raise RuntimeWarning("No activity attached")
diff --git a/tutorius/dbustools.py b/tutorius/dbustools.py
index 02acd3d..0973164 100644
--- a/tutorius/dbustools.py
+++ b/tutorius/dbustools.py
@@ -1,3 +1,19 @@
+# Copyright (C) 2009, Tutorius.org
+#
+# 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 1 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
+
import logging
import gobject
diff --git a/tutorius/engine.py b/tutorius/engine.py
index 10c8d14..bb2453a 100644
--- a/tutorius/engine.py
+++ b/tutorius/engine.py
@@ -30,6 +30,7 @@ class TutorialRunner(object):
#Cached objects
self._actions = {}
self._installed_actions = {}
+ self._install_errors = {}
#Temp FIX until event/actions have an activity id
self._activity_id = None
@@ -62,17 +63,45 @@ class TutorialRunner(object):
LOGGER.debug("TutorialRunner :: Uninstalling action %s with address %s"%(action_name, action_address))
self._pM.uninstall(action_address)
self._actions = {}
- self._installed_actions = {}
+ self._installed_actions.clear()
+ self._install_errors.clear()
#Clear the EventFilters
for event in self._sEvents:
self._pM.unsubscribe(event)
self._sEvents.clear()
- def __action_installed(self, action_name, address):
+ 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
+ # 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
+ for (this_action_name, this_action) in self._actions.items():
+ if not this_action_name in self._installed_actions.keys() and not this_action in self._install_errors.keys():
+ # There's at least one uninstalled action, so we still wait
+ install_complete = False
+ break
+
+ if install_complete:
+ LOGGER.debug("TutorialRunner :: All actions installed!")
+ # Raise the All Actions Installed event for the TutorialRunner state
+ self._all_actions_installed()
+
+ 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._install_errors[action_name] = exception
+
+ def _all_actions_installed(self):
+ transitions = self._tutorial.get_transition_dict(self._state)
+
+ if len(transitions) == 0:
+ return
+ for (event, next_state) in transitions.values():
+ self._sEvents.add(self._pM.subscribe(event, save_args(self._handleEvent, next_state)))
+
def _setupState(self):
if self._state is None:
raise RuntimeError("Attempting to setupState without a state")
@@ -88,13 +117,15 @@ class TutorialRunner(object):
state_name = next_state
return state_name
+ if len(self._actions) == 0:
+ self._all_actions_installed()
+ return state_name
+
for (action_name, action) in self._actions.items():
- self._pM.install(action, save_args(self.__action_installed, action_name), True)
+ self._pM.install(action, save_args(self.__action_installed, action_name),
+ save_args(self.__install_error, action_name))
LOGGER.debug("TutorialRunner :: Installed action %s"%(action_name))
-
- for (event, next_state) in transitions.values():
- self._sEvents.add(self._pM.subscribe(event, save_args(self._handleEvent, next_state)))
-
+
return state_name
def enterState(self, state_name):