Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tutorius/TProbe.py
diff options
context:
space:
mode:
authorVincent Vinet <vince.vinet@gmail.com>2009-09-30 12:40:42 (GMT)
committer Vincent Vinet <vince.vinet@gmail.com>2009-09-30 12:40:42 (GMT)
commitc22371ef8af9b2aff165e801119912532a5edf08 (patch)
treec41d93fbb376601da1c1c5de957919c338f3dd52 /tutorius/TProbe.py
parent56aa5ada82c014ca0c7cdc6675b93496e0a6967a (diff)
WIP for running tutorials with the ProbeProxy
Diffstat (limited to 'tutorius/TProbe.py')
-rw-r--r--tutorius/TProbe.py169
1 files changed, 147 insertions, 22 deletions
diff --git a/tutorius/TProbe.py b/tutorius/TProbe.py
index 6dd3afb..c4fae81 100644
--- a/tutorius/TProbe.py
+++ b/tutorius/TProbe.py
@@ -1,6 +1,10 @@
+import logging
+import os
+
import gobject
import dbus
+import dbus.service
import cPickle as pickle
import sugar.tutorius.addon as addon
@@ -10,10 +14,13 @@ from sugar.tutorius.services import ObjectStore
import copy
"""
-The TProbe module defines two connected classes, TProbe and ProbeProxy.
-
+ --------------------
+ | ProbeManager |
+ --------------------
+ |
+ V
-------------------- ----------
- | ProbeProxy |----- DBus ---->| TProbe |
+ | ProbeProxy |<---- DBus ---->| TProbe |
-------------------- ----------
"""
@@ -45,6 +52,9 @@ class TProbe(dbus.service.Object):
@param activity_name unique activity_id
@param activity activity reference, must be a gtk container
"""
+ logging.debug("TProbe :: Creating TProbe for %s (%d)", activity_name, os.getpid())
+ logging.debug("TProbe :: Current gobject context: %s", str(gobject.main_context_default()))
+ logging.debug("TProbe :: Current gobject depth: %s", str(gobject.main_depth()))
# Moving the ObjectStore assignment here, in the meantime
# the reference to the activity shouldn't be share as a
# global variable but passed by the Probe to the objects
@@ -230,8 +240,6 @@ class TProbe(dbus.service.Object):
return name + str(suffix)
-
-
class ProbeProxy:
"""
ProbeProxy is a Proxy class for connecting to a remote TProbe.
@@ -241,21 +249,28 @@ class ProbeProxy:
Public Methods:
ProbeProxy(string activityName) :: Constructor
- string install(Action action) -> action address
- void update(string address, Action action)
- void uninstall(string address)
- string subscribe(Event event, callable callback) -> event address
- void unsubscribe(string address)
+ string install(Action action)
+ void update(Action action)
+ void uninstall(Action action)
+ void uninstall_all()
+ string subscribe(Event event, callable callback)
+ void unsubscribe(Event event, callable callback)
+ void unsubscribe_all()
"""
def __init__(self, activityName):
"""
Constructor
@param activityName unique activity id
"""
+ logging.debug("ProbeProxy :: Creating ProbeProxy for %s (%d)", activityName, os.getpid())
+ logging.debug("ProbeProxy :: Current gobject context: %s", str(gobject.main_context_default()))
+ logging.debug("ProbeProxy :: Current gobject depth: %s", str(gobject.main_depth()))
bus = dbus.SessionBus()
self._object = bus.get_object(activityName, "/tutorius/Probe")
self._probe = dbus.Interface(self._object, "org.tutorius.ProbeInterface")
+ self._actions = {}
+ self._events = {}
# We keep those two data structures to be able to have multiple callbacks
# for the same event and be able to remove them independently
self._subscribedEvents = {}
@@ -269,31 +284,47 @@ class ProbeProxy:
self._object.connect_to_signal("eventOccured", _handle_signal, dbus_interface="org.tutorius.ProbeInterface")
+ def isAlive(self):
+ try:
+ return self._probe.ping() == "alive"
+ except:
+ return False
+
def install(self, action):
"""
Install an action on the TProbe's activity
@param action Action to install
- @return address identifier used for update and uninstall
+ @return None
"""
address = str(self._probe.install(pickle.dumps(action)))
- return address
+ self._actions[action] = address
def update(self, address, action):
"""
Update an already installed action's properties and run it again
- @param address identifier returned by the action install
- @param action Action to get properties from
+ @param action Action to update
@return None
"""
- self._probe.update(address, pickle.dumps(action._props))
+ if not action in self._actions:
+ raise RuntimeWarning("Action not installed")
+ return
+ self._probe.update(self._actions[action], pickle.dumps(action._props))
- def uninstall(self, address):
+ def uninstall(self, action):
+ """
+ Uninstall an installed action
+ @param action Action to uninstall
+ """
+ if action in self._actions:
+ self._probe.uninstall(self._actions.pop(action))
+
+ def uninstall_all(self):
"""
- Uninstall an installd action
- @param address identifier returned by the action install
+ Uninstall all installed actions
@return None
"""
- self._probe.uninstall(address)
+ for action in self._actions.keys():
+ self.uninstall(action)
def subscribe(self, event, callback):
"""
@@ -305,7 +336,9 @@ class ProbeProxy:
# TODO elavoie 2009-07-25 When we will allow for patterns both
# for event types and sources, we will need to revise the lookup
# mecanism for which callback function to call
-
+ if (event, callback) in self._events:
+ raise RuntimeError("event already registered for callback")
+ return
# Since multiple callbacks could be associated to the same
# event signature, we will store multiple callbacks
@@ -314,6 +347,8 @@ class ProbeProxy:
# dictionary from another one indexed by event
address = str(self._probe.subscribe(pickle.dumps(event)))
+ self._events[(event, callback)] = address
+
# We use the event object as a key
if not self._registeredCallbacks.has_key(event):
self._registeredCallbacks[event] = {}
@@ -336,13 +371,18 @@ class ProbeProxy:
return address
- def unsubscribe(self, address):
+ def unsubscribe(self, event, callback):
"""
Unregister an event listener
@param address identifier given by subscribe()
@return None
"""
- self._probe.unsubscribe(address)
+ if not (event, callback) in self._events:
+ raise RuntimeWarning("callback/event not subscribed")
+ return
+
+ address = self._events.pop((event, callback))
+ self._probe.unsubscribe()
# Cleanup everything
if self._subscribedEvents.has_key(address):
@@ -357,4 +397,89 @@ class ProbeProxy:
self._subscribedEvents.pop(address)
+ def unsubscribe_all(self):
+ """
+ Unregister all event listeners
+ @return None
+ """
+ for event, callback in self._events.keys():
+ self.unsubscribe(event, callback)
+
+class ProbeManager(object):
+ """
+ The ProbeManager provides multiplexing across multiple activity ProbeProxies
+
+ For now, it only handles one at a time, though.
+ """
+ def __init__(self):
+ self._probes = {}
+ self._current_activity = None
+
+ def setCurrentActivity(self, activity_id):
+ if not activity_id in self._probes:
+ raise RuntimeError("Activity not attached")
+ self._current_activity = activity_id
+
+ def getCurrentActivity(self):
+ return self._current_activity
+
+ currentActivity = property(fget=getCurrentActivity, fset=setCurrentActivity)
+ def attach(self, activity_id):
+ if activity_id in self._probes:
+ raise RuntimeWarning("Activity already attached")
+ return
+
+ self._probes[activity_id] = ProbeProxy(activity_id)
+ if self._probes[activity_id].isAlive():
+ print "Alive!"
+ else:
+ print "FAil!"
+
+ def detach(self, activity_id):
+ if activity_id in self._probes:
+ probe = self._probes.pop(activity_id)
+ probe.unsubscribe_all()
+ probe.uninstall_all()
+
+ def install(self, action):
+ if self.currentActivity:
+ return self._probes[self.currentActivity].install(action)
+ else:
+ raise RuntimeWarning("No activity attached")
+
+ def update(self, action):
+ if self.currentActivity:
+ return self._probes[self.currentActivity].update(action)
+ else:
+ raise RuntimeWarning("No activity attached")
+
+ def uninstall(self, action):
+ if self.currentActivity:
+ return self._probes[self.currentActivity].uninstall(action)
+ else:
+ raise RuntimeWarning("No activity attached")
+
+ def uninstall_all(self):
+ if self.currentActivity:
+ return self._probes[self.currentActivity].uninstall_all()
+ else:
+ raise RuntimeWarning("No activity attached")
+
+ def subscribe(self, event, callback):
+ if self.currentActivity:
+ return self._probes[self.currentActivity].subscribe(event, callback)
+ else:
+ raise RuntimeWarning("No activity attached")
+
+ def unsubscribe(self, event, callback):
+ if self.currentActivity:
+ return self._probes[self.currentActivity].unsubscribe(event, callback)
+ else:
+ raise RuntimeWarning("No activity attached")
+
+ def unsubscribe_all(self):
+ if self.currentActivity:
+ return self._probes[self.currentActivity].unsubscribe_all()
+ else:
+ raise RuntimeWarning("No activity attached")