Make joining asynchronous on the activity side
This commit is contained in:
parent
46d97015e6
commit
7774073276
@ -42,6 +42,7 @@ class ActivityToolbar(gtk.Toolbar):
|
|||||||
|
|
||||||
self._activity = activity
|
self._activity = activity
|
||||||
activity.connect('shared', self._activity_shared_cb)
|
activity.connect('shared', self._activity_shared_cb)
|
||||||
|
activity.connect('joined', self._activity_shared_cb)
|
||||||
|
|
||||||
button = ToolButton('window-close')
|
button = ToolButton('window-close')
|
||||||
button.connect('clicked', self._close_button_clicked_cb)
|
button.connect('clicked', self._close_button_clicked_cb)
|
||||||
@ -105,7 +106,8 @@ class Activity(Window, gtk.Container):
|
|||||||
__gtype_name__ = 'SugarActivity'
|
__gtype_name__ = 'SugarActivity'
|
||||||
|
|
||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
'shared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
|
'shared': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])),
|
||||||
|
'joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, handle):
|
def __init__(self, handle):
|
||||||
@ -133,53 +135,64 @@ class Activity(Window, gtk.Container):
|
|||||||
|
|
||||||
self.connect('destroy', self._destroy_cb)
|
self.connect('destroy', self._destroy_cb)
|
||||||
|
|
||||||
self._shared = False
|
|
||||||
self._activity_id = handle.activity_id
|
self._activity_id = handle.activity_id
|
||||||
self._pservice = presenceservice.get_instance()
|
self._pservice = presenceservice.get_instance()
|
||||||
self._service = None
|
self._shared_activity = None
|
||||||
self._share_sigid = None
|
self._share_id = None
|
||||||
|
self._join_id = None
|
||||||
|
|
||||||
service = handle.get_presence_service()
|
shared_activity = handle.get_shared_activity()
|
||||||
if service:
|
if shared_activity:
|
||||||
self._join(service)
|
# Join an existing instance of this activity on the network
|
||||||
|
self._shared_activity = shared_activity
|
||||||
|
self._join_id = self._shared_activity.connect("joined", self._internal_joined_cb)
|
||||||
|
if not self._shared_activity.props.joined:
|
||||||
|
self._shared_activity.join()
|
||||||
|
else:
|
||||||
|
self._joined_cb(self._shared_activity, True, None)
|
||||||
|
|
||||||
self._bus = ActivityService(self)
|
self._bus = ActivityService(self)
|
||||||
|
|
||||||
|
def _internal_joined_cb(self, activity, success, err):
|
||||||
|
"""Callback when join has finished"""
|
||||||
|
self._shared_activity.disconnect(self._join_id)
|
||||||
|
self._join_id = None
|
||||||
|
if not success:
|
||||||
|
logging.debug("Failed to join activity: %s" % err)
|
||||||
|
return
|
||||||
|
self.present()
|
||||||
|
self.emit('joined')
|
||||||
|
|
||||||
def get_service_name(self):
|
def get_service_name(self):
|
||||||
"""Gets the activity service name."""
|
"""Gets the activity service name."""
|
||||||
return os.environ['SUGAR_BUNDLE_SERVICE_NAME']
|
return os.environ['SUGAR_BUNDLE_SERVICE_NAME']
|
||||||
|
|
||||||
def get_shared(self):
|
def get_shared(self):
|
||||||
"""Returns TRUE if the activity is shared on the mesh."""
|
"""Returns TRUE if the activity is shared on the mesh."""
|
||||||
return self._shared
|
if not self._shared_activity:
|
||||||
|
return False
|
||||||
|
return self._shared_activity.props.joined
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
"""Get the unique activity identifier."""
|
"""Get the unique activity identifier."""
|
||||||
return self._activity_id
|
return self._activity_id
|
||||||
|
|
||||||
def _join(self, service):
|
def _internal_share_cb(self, ps, success, activity, err):
|
||||||
"""Join an existing instance of this activity on the network."""
|
self._pservice.disconnect(self._share_id)
|
||||||
self._service = service
|
self._share_id = None
|
||||||
self._shared = True
|
if not success:
|
||||||
self._service.join()
|
logging.debug('Share of activity %s failed: %s.' % (self._activity_id, err))
|
||||||
self.present()
|
return
|
||||||
|
logging.debug('Share of activity %s successful.' % self._activity_id)
|
||||||
|
self.shared_activity = activity
|
||||||
self.emit('shared')
|
self.emit('shared')
|
||||||
|
|
||||||
def _share_cb(self, ps, success, service, err):
|
|
||||||
self._pservice.disconnect(self._share_sigid)
|
|
||||||
self._share_sigid = None
|
|
||||||
if success:
|
|
||||||
logging.debug('Share of activity %s successful.' % self.get_id())
|
|
||||||
self._service = service
|
|
||||||
self._shared = True
|
|
||||||
self.emit('shared')
|
|
||||||
else:
|
|
||||||
logging.debug('Share of activity %s failed: %s.' % (self.get_id(), err))
|
|
||||||
|
|
||||||
def share(self):
|
def share(self):
|
||||||
"""Request that the activity be shared on the network."""
|
"""Request that the activity be shared on the network."""
|
||||||
logging.debug('Requesting share of activity %s.' % self.get_id())
|
if self._shared_activty and self._shared_activity.props.joined:
|
||||||
self._share_sigid = self._pservice.connect("activity-shared", self._share_cb)
|
raise RuntimeError("Activity %s already shared." % self._activity_id)
|
||||||
|
logging.debug('Requesting share of activity %s.' % self._activity_id)
|
||||||
|
self._share_id = self._pservice.connect("activity-shared", self._internal_share_cb)
|
||||||
self._pservice.share_activity(self)
|
self._pservice.share_activity(self)
|
||||||
|
|
||||||
def execute(self, command, args):
|
def execute(self, command, args):
|
||||||
@ -191,8 +204,8 @@ class Activity(Window, gtk.Container):
|
|||||||
if self._bus:
|
if self._bus:
|
||||||
del self._bus
|
del self._bus
|
||||||
self._bus = None
|
self._bus = None
|
||||||
if self._service:
|
if self._shared_activity:
|
||||||
self._pservice.unregister_service(self._service)
|
self._shared_activity.leave()
|
||||||
|
|
||||||
def _handle_close_cb(self, toolbar):
|
def _handle_close_cb(self, toolbar):
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
@ -52,8 +52,8 @@ class ActivityHandle(object):
|
|||||||
self.object_id = object_id
|
self.object_id = object_id
|
||||||
self.uri = uri
|
self.uri = uri
|
||||||
|
|
||||||
def get_presence_service(self):
|
def get_shared_activity(self):
|
||||||
"""Retrieve the "sharing service" for this activity
|
"""Retrieve the shared instance of this activity
|
||||||
|
|
||||||
Uses the PresenceService to find any existing dbus
|
Uses the PresenceService to find any existing dbus
|
||||||
service which provides sharing mechanisms for this
|
service which provides sharing mechanisms for this
|
||||||
|
@ -36,10 +36,12 @@ class Activity(gobject.GObject):
|
|||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
'buddy-joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
'buddy-joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
||||||
([gobject.TYPE_PYOBJECT])),
|
([gobject.TYPE_PYOBJECT])),
|
||||||
'buddy-left': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
'buddy-left': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
||||||
([gobject.TYPE_PYOBJECT])),
|
([gobject.TYPE_PYOBJECT])),
|
||||||
'new-channel': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
'new-channel': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
||||||
([gobject.TYPE_PYOBJECT]))
|
([gobject.TYPE_PYOBJECT])),
|
||||||
|
'joined': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
||||||
|
([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]))
|
||||||
}
|
}
|
||||||
|
|
||||||
__gproperties__ = {
|
__gproperties__ = {
|
||||||
@ -137,15 +139,22 @@ class Activity(gobject.GObject):
|
|||||||
buddies.append(self._ps_new_object(item))
|
buddies.append(self._ps_new_object(item))
|
||||||
return buddies
|
return buddies
|
||||||
|
|
||||||
|
def _join_cb(self):
|
||||||
|
self._joined = True
|
||||||
|
self.emit("joined", True, None)
|
||||||
|
|
||||||
|
def _join_error_cb(self, err):
|
||||||
|
self.emit("joined", False, str(err))
|
||||||
|
|
||||||
def join(self):
|
def join(self):
|
||||||
"""Join this activity
|
"""Join this activity
|
||||||
|
|
||||||
XXX if these are all activities, can I join my own activity?
|
XXX if these are all activities, can I join my own activity?
|
||||||
"""
|
"""
|
||||||
if self._joined:
|
if self._joined:
|
||||||
|
self.emit("joined", True, None)
|
||||||
return
|
return
|
||||||
self._activity.Join()
|
self._activity.Join(reply_handler=self._join_cb, error_handler=self._join_error_cb)
|
||||||
self._joined = True
|
|
||||||
|
|
||||||
def get_channels(self):
|
def get_channels(self):
|
||||||
"""Retrieve communications channel descriptions for the activity
|
"""Retrieve communications channel descriptions for the activity
|
||||||
@ -157,7 +166,6 @@ class Activity(gobject.GObject):
|
|||||||
(bus_name, connection, channels) = self._activity.GetChannels()
|
(bus_name, connection, channels) = self._activity.GetChannels()
|
||||||
return bus_name, connection, channels
|
return bus_name, connection, channels
|
||||||
|
|
||||||
def owner_has_joined(self):
|
def leave(self):
|
||||||
"""Retrieve whether the owner of the activity is active within it"""
|
|
||||||
# FIXME
|
# FIXME
|
||||||
return False
|
self._joined = False
|
||||||
|
@ -160,6 +160,11 @@ class PresenceService(gobject.GObject):
|
|||||||
elif object_path.startswith(self._PS_ACTIVITY_OP):
|
elif object_path.startswith(self._PS_ACTIVITY_OP):
|
||||||
obj = activity.Activity(self._bus, self._new_object,
|
obj = activity.Activity(self._bus, self._new_object,
|
||||||
self._del_object, object_path)
|
self._del_object, object_path)
|
||||||
|
try:
|
||||||
|
# Pre-fill the activity's ID
|
||||||
|
foo = obj.props.id
|
||||||
|
except dbus.exceptions.DBusException, err:
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unknown object type")
|
raise RuntimeError("Unknown object type")
|
||||||
self._objcache[object_path] = obj
|
self._objcache[object_path] = obj
|
||||||
@ -322,7 +327,9 @@ class PresenceService(gobject.GObject):
|
|||||||
|
|
||||||
def _share_activity_cb(self, activity, op):
|
def _share_activity_cb(self, activity, op):
|
||||||
"""Notify with GObject event of successful sharing of activity"""
|
"""Notify with GObject event of successful sharing of activity"""
|
||||||
self.emit("activity-shared", True, self._new_object(op), None)
|
psact = self._new_object(op)
|
||||||
|
psact._joined = True
|
||||||
|
self.emit("activity-shared", True, psact, None)
|
||||||
|
|
||||||
def _share_activity_error_cb(self, activity, err):
|
def _share_activity_error_cb(self, activity, err):
|
||||||
"""Notify with GObject event of unsuccessful sharing of activity"""
|
"""Notify with GObject event of unsuccessful sharing of activity"""
|
||||||
@ -343,6 +350,14 @@ class PresenceService(gobject.GObject):
|
|||||||
returns None
|
returns None
|
||||||
"""
|
"""
|
||||||
actid = activity.get_id()
|
actid = activity.get_id()
|
||||||
|
|
||||||
|
# Ensure the activity is not already shared/joined
|
||||||
|
for obj in self._objcache.values():
|
||||||
|
if not isinstance(object, activity.Activity):
|
||||||
|
continue
|
||||||
|
if obj.props.id == actid or obj.props.joined:
|
||||||
|
raise RuntimeError("Activity %s is already shared." % actid)
|
||||||
|
|
||||||
atype = activity.get_service_name()
|
atype = activity.get_service_name()
|
||||||
name = activity.props.title
|
name = activity.props.title
|
||||||
self._ps.ShareActivity(actid, atype, name, properties,
|
self._ps.ShareActivity(actid, atype, name, properties,
|
||||||
|
Loading…
Reference in New Issue
Block a user