quick frontends: signal cache: if a signal arrives between the beginning of profile plugging, and the when the profile is actually ready, it is cached and replayed when the profile is ready.
This commit is contained in:
parent
90b4969e39
commit
3ed295e7b1
1 changed files with 25 additions and 11 deletions
|
|
@ -204,6 +204,8 @@ class QuickApp(object):
|
|||
"""
|
||||
ProfileManager.host = self
|
||||
self.profiles = ProfilesManager()
|
||||
self.ready_profiles = set() # profiles which are connected and ready
|
||||
self.signals_cache = {} # used to keep signal received between start of plug_profile and when the profile is actualy ready
|
||||
self.contact_lists = {}
|
||||
self.widgets = QuickWidgetsManager(self)
|
||||
if check_options is not None:
|
||||
|
|
@ -281,18 +283,18 @@ class QuickApp(object):
|
|||
"""widgets currently visible (must be implemented by frontend)"""
|
||||
raise NotImplementedError
|
||||
|
||||
def registerSignal(self, functionName, handler=None, iface="core", with_profile=True):
|
||||
def registerSignal(self, function_name, handler=None, iface="core", with_profile=True):
|
||||
"""Register a handler for a signal
|
||||
|
||||
@param functionName (str): name of the signal to handle
|
||||
@param handler (instancemethod): method to call when the signal arrive, None for calling an automatically named handler (functionName + 'Handler')
|
||||
@param function_name (str): name of the signal to handle
|
||||
@param handler (instancemethod): method to call when the signal arrive, None for calling an automatically named handler (function_name + 'Handler')
|
||||
@param iface (str): interface of the bridge to use ('core' or 'plugin')
|
||||
@param with_profile (boolean): True if the signal concerns a specific profile, in that case the profile name has to be passed by the caller
|
||||
"""
|
||||
if handler is None:
|
||||
handler = getattr(self, "{}{}".format(functionName, 'Handler'))
|
||||
handler = getattr(self, "{}{}".format(function_name, 'Handler'))
|
||||
if not with_profile:
|
||||
self.bridge.register(functionName, handler, iface)
|
||||
self.bridge.register(function_name, handler, iface)
|
||||
return
|
||||
|
||||
def signalReceived(*args, **kwargs):
|
||||
|
|
@ -301,10 +303,14 @@ class QuickApp(object):
|
|||
if not args:
|
||||
raise exceptions.ProfileNotSetError
|
||||
profile = args[-1]
|
||||
if profile is not None and not self.check_profile(profile):
|
||||
return # we ignore signal for profiles we don't manage
|
||||
if profile is not None:
|
||||
if not self.check_profile(profile):
|
||||
if profile in self.profiles:
|
||||
# profile is not ready but is in self.profiles, that's mean that it's being connecting and we need to cache the signal
|
||||
self.signals_cache.setdefault(profile, []).append((function_name, handler, args, kwargs))
|
||||
return # we ignore signal for profiles we don't manage
|
||||
handler(*args, **kwargs)
|
||||
self.bridge.register(functionName, signalReceived, iface)
|
||||
self.bridge.register(function_name, signalReceived, iface)
|
||||
|
||||
def addListener(self, type_, callback, profiles_filter=None):
|
||||
"""Add a listener for an event
|
||||
|
|
@ -354,8 +360,8 @@ class QuickApp(object):
|
|||
listener(*args, **kwargs)
|
||||
|
||||
def check_profile(self, profile):
|
||||
"""Tell if the profile is currently followed by the application"""
|
||||
return profile in self.profiles
|
||||
"""Tell if the profile is currently followed by the application, and ready"""
|
||||
return profile in self.ready_profiles
|
||||
|
||||
def postInit(self, profile_manager):
|
||||
"""Must be called after initialization is done, do all automatic task (auto plug profile)
|
||||
|
|
@ -368,9 +374,17 @@ class QuickApp(object):
|
|||
def profilePlugged(self, profile):
|
||||
"""Method called when the profile is fully plugged, to launch frontend specific workflow
|
||||
|
||||
/!\ if you override the method and don't call the parent, be sure to add the profile to ready_profiles !
|
||||
if you don't, all signals will stay in cache
|
||||
|
||||
@param profile(unicode): %(doc_profile)s
|
||||
"""
|
||||
pass
|
||||
self.ready_profiles.add(profile)
|
||||
|
||||
# profile is ready, we can call send signals that where is cache
|
||||
cached_signals = self.signals_cache.pop(profile, [])
|
||||
for function_name, handler, args, kwargs in cached_signals:
|
||||
log.debug(u"Calling cached signal [%s] with args %s and kwargs %s" % (function_name, args, kwargs))
|
||||
|
||||
def asyncConnect(self, profile, callback=None, errback=None):
|
||||
if not callback:
|
||||
|
|
|
|||
Loading…
Reference in a new issue