Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorgan Collett <morgan.collett@collabora.co.uk>2007-06-29 13:39:26 (GMT)
committer Morgan Collett <morgan.collett@collabora.co.uk>2007-06-29 13:39:26 (GMT)
commit2fd702e4272252ea8cc5cced95c4a88af12ce007 (patch)
tree4e45738dbf291be54dd48624ed9e8b7ef6994cb9
parent33ce6546d7e2dede68e1b20a9dbfcf19eee1972b (diff)
Implement communication over the Tube with a signal and a method
-rw-r--r--activity.py113
1 files changed, 107 insertions, 6 deletions
diff --git a/activity.py b/activity.py
index 6b921dc..3ba6acf 100644
--- a/activity.py
+++ b/activity.py
@@ -22,10 +22,14 @@ import logging
import telepathy
import telepathy.client
+from dbus import Interface
+from dbus.service import method, signal
+from dbus.gobject_service import ExportedGObject
+
from sugar.activity.activity import Activity, ActivityToolbox
from sugar.presence import presenceservice
-# will eventually be imported from telepathy.tubes or something
+# will eventually be imported from sugar
from tubeconn import TubeConnection
SERVICE = "org.laptop.HelloMesh"
@@ -61,13 +65,14 @@ class HelloMeshActivity(Activity):
self.set_canvas(canvas)
self.show_all()
+ self.hellotube = None
+
# get the Presence Service
self.pservice = presenceservice.get_instance()
name, path = self.pservice.get_preferred_connection()
self.tp_conn_name = name
self.tp_conn_path = path
self.conn = telepathy.client.Connection(name, path)
- self.initiating = None
self.connect('shared', self._shared_cb)
@@ -88,11 +93,11 @@ class HelloMeshActivity(Activity):
def _shared_cb(self, activity):
logger.debug('My activity was shared')
- self.initiating = True
self._setup()
for buddy in self._shared_activity.get_joined_buddies():
- pass # Can do stuff with newly acquired buddies here
+ logger.debug('Buddy %s is already in the activity' %
+ buddy.props.nick)
self._shared_activity.connect('buddy-joined', self._buddy_joined_cb)
self._shared_activity.connect('buddy-left', self._buddy_left_cb)
@@ -160,11 +165,11 @@ class HelloMeshActivity(Activity):
if not self._shared_activity:
return
+ # Find out who's already in the shared activity:
for buddy in self._shared_activity.get_joined_buddies():
- pass # XXX do stuff with buddy
+ logger.debug('Buddy %s is already in the activity' % buddy.props.nick)
logger.debug('Joined an existing shared activity')
- self.initiating = False
self._setup()
logger.debug('This is not my activity: waiting for a tube...')
@@ -185,9 +190,105 @@ class HelloMeshActivity(Activity):
tube_conn = TubeConnection(self.conn,
self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES],
id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP])
+ self.hellotube = HelloTube(tube_conn, self._get_buddy)
def _buddy_joined_cb (self, activity, buddy):
logger.debug('Buddy %s joined' % buddy.props.nick)
def _buddy_left_cb (self, activity, buddy):
logger.debug('Buddy %s left' % buddy.props.nick)
+
+ def _get_buddy(self, cs_handle):
+ """Get a Buddy from a channel specific handle."""
+ logger.debug('Trying to find owner of handle %u...', cs_handle)
+ group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]
+ my_csh = group.GetSelfHandle()
+ logger.debug('My handle in that group is %u', my_csh)
+ if my_csh == cs_handle:
+ handle = self.conn.GetSelfHandle()
+ logger.debug('CS handle %u belongs to me, %u', cs_handle, handle)
+ else:
+ handle = group.GetHandleOwners([cs_handle])[0]
+ logger.debug('CS handle %u belongs to %u', cs_handle, handle)
+
+ # XXX: deal with failure to get the handle owner
+ assert handle != 0
+
+ # XXX: we're assuming that we have Buddy objects for all contacts -
+ # this might break when the server becomes scalable.
+ return self.pservice.get_buddy_by_telepathy_handle(self.tp_conn_name,
+ self.tp_conn_path, handle)
+
+class HelloTube(ExportedGObject):
+ """The bit that talks over the TUBES!!!"""
+
+ def __init__(self, tube, get_buddy):
+ self.tube = tube
+ self.entered = False # Have we set up the tube?
+ self.helloworld = False # Have we said Hello and received World?
+ self._get_buddy = get_buddy # Converts handle to Buddy object
+ self.tube.watch_participants(self.participant_change_cb)
+
+ def participant_change_cb(self, added, removed):
+ logger.debug('Adding participants: %r' % added)
+ logger.debug('Removing participants: %r' % removed)
+
+ for handle, bus_name in added:
+ buddy = self._get_buddy(handle)
+ if buddy is not None:
+ logger.debug('Buddy %s was added' % buddy.props.nick)
+
+ for handle in removed:
+ buddy = self._get_buddy(handle)
+ if buddy is not None:
+ logger.debug('Buddy %s was removed' % buddy.props.nick)
+ # Do activity logic with new or removed buddies
+
+ if not self.entered:
+ self.tube.add_signal_receiver(self.insert_cb, 'Insert', IFACE,
+ path=PATH, sender_keyword='sender')
+ if self.is_initiator:
+ _logger.debug('I am the initiator, so making myself player 0')
+ self.add_hello_handler()
+ self.ordered_bus_names = [self.tube.get_unique_name()]
+ self.player_id = 0
+ self.buddies_panel.add_player(self.owner)
+ else:
+ _logger.debug('Hello, everyone! What did I miss?')
+ self.Hello()
+ self.entered = True
+
+ @signal(dbus_interface=IFACE, signature='')
+ def Hello(self):
+ """Say Hello to whoever else is in the tube."""
+ _logger.debug('I said Hello.')
+
+ @method(dbus_interface=IFACE, in_signature='as', out_signature='')
+ def World(self, name):
+ """To be called on the incoming XO after they Hello."""
+ if not self.helloworld:
+ _logger.debug('%s said World.')
+ # now I can World others
+ self.add_hello_handler()
+
+ #buddy = self._get_buddy(self.tube.bus_name_to_handle[bus_names[0]])
+ else:
+ _logger.debug("I've already been welcomed, doing nothing")
+
+ def add_hello_handler(self):
+ self.tube.add_signal_receiver(self.hello_cb, 'Hello', IFACE,
+ path=PATH, sender_keyword='sender')
+
+ def hello_cb(self, sender=None):
+ """Somebody Helloed me. World them."""
+ _logger.debug('Newcomer %s has joined', sender)
+ self.ordered_bus_names.append(sender)
+ if len(self.ordered_bus_names) == 2:
+ buddy = self._get_buddy(self.tube.bus_name_to_handle[sender])
+ self.buddies_panel.add_player(buddy)
+ _logger.debug('Bus names are now: %r', self.ordered_bus_names)
+ _logger.debug('Welcoming newcomer and sending them the game state')
+ self.tube.get_object(sender, PATH).World(self.ordered_bus_names,
+ dbus_interface=IFACE)
+
+