Skip to content
Snippets Groups Projects
Commit cab86421 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Notifier listeners are now passed the topic name. Notifier.skip allows

multiple topics to be specified.
parent 245c7db0
No related branches found
No related tags found
No related merge requests found
Pipeline #
...@@ -14,6 +14,8 @@ import inspect ...@@ -14,6 +14,8 @@ import inspect
import contextlib import contextlib
import collections import collections
import six
import props import props
import fsl.utils.async as async import fsl.utils.async as async
...@@ -120,6 +122,9 @@ class Notifier(object): ...@@ -120,6 +122,9 @@ class Notifier(object):
- this ``Notifier`` instance. - this ``Notifier`` instance.
- The topic, which may be ``None`` - see
:meth:`notify`.
- A value, which may be ``None`` - see - A value, which may be ``None`` - see
:meth:`notify`. :meth:`notify`.
...@@ -270,17 +275,27 @@ class Notifier(object): ...@@ -270,17 +275,27 @@ class Notifier(object):
# if a notification is triggered # if a notification is triggered
# by the code here, the __myListener # by the code here, the __myListener
# function will not be called. # function will not be called.
:arg name: Name of the listener to skip
:arg topic: Topic or topics that the listener is registered on.
""" """
state = self.isEnabled(name, topic) if topic is None or isinstance(topic, six.string_types):
self.disable(name, topic) topic = [topic]
topics = topic
states = [self.isEnabled(name, t) for t in topics]
for topic in topics:
self.disable(name, topic)
try: try:
yield yield
finally: finally:
if state: self.enable( name, topic) for topic, state in zip(topics, states):
else: self.disable(name, topic) self.enable(name, topic, state)
def notify(self, *args, **kwargs): def notify(self, *args, **kwargs):
...@@ -303,54 +318,66 @@ class Notifier(object): ...@@ -303,54 +318,66 @@ class Notifier(object):
See :meth:`register`. See :meth:`register`.
""" """
topic = kwargs.get('topic', DEFAULT_TOPIC) topic = kwargs.get('topic', None)
value = kwargs.get('value', None) value = kwargs.get('value', None)
isDefault = topic == DEFAULT_TOPIC listeners = self.__getListeners(topic)
allEnabled = self.__enabled.get(DEFAULT_TOPIC, True)
topicEnabled = ((isDefault and allEnabled) or
self.__enabled.get(topic), True)
if not allEnabled:
return
if topicEnabled: if len(listeners) == 0:
listeners = [self.__listeners[topic]]
if not isDefault:
listeners.append(self.__listeners[DEFAULT_TOPIC])
if sum(map(len, listeners)) == 0:
return return
if log.getEffectiveLevel() >= logging.DEBUG: if log.getEffectiveLevel() <= logging.DEBUG:
stack = inspect.stack() stack = inspect.stack()
frame = stack[1] frame = stack[1]
srcMod = '...{}'.format(frame[1][-20:]) srcMod = '...{}'.format(frame[1][-20:])
srcLine = frame[2] srcLine = frame[2]
log.debug('{}: Notifying {} listeners (topic: {}) [{}:{}]'.format( log.debug('{}: Notifying {} listeners (topic: {}) [{}:{}]'.format(
type(self).__name__, type(self).__name__,
sum(map(len, listeners)), len(listeners),
topic, topic,
srcMod, srcMod,
srcLine)) srcLine))
for ldict in listeners: for listener in listeners:
for name, listener in list(ldict.items()):
callback = listener.callback callback = listener.callback
name = listener.name
# The callback, or the owner of the
# callback function may have been # The callback, or the owner of the
# gc'd - remove it if this is the case. # callback function may have been
if callback is None: # gc'd - remove it if this is the case.
log.debug('Listener {} has been gc\'d - ' if callback is None:
'removing from list'.format(name)) log.debug('Listener {} has been gc\'d - '
ldict.pop(name) 'removing from list'.format(name))
self.__listeners[listener.topic].pop(name)
elif not listener.enabled:
continue elif not listener.enabled:
continue
elif listener.runOnIdle: async.idle(callback, self, value)
else: callback( self, value) elif listener.runOnIdle: async.idle(callback, self, topic, value)
else: callback( self, topic, value)
def __getListeners(self, topic):
"""Called by :meth:`notify`. Returns all listeners which should be
notified for the specified ``topic``.
"""
isDefault = topic is None
allEnabled = self.__enabled.get(DEFAULT_TOPIC, True)
topicEnabled = ((isDefault and allEnabled) or
self.__enabled.get(topic), True)
if isDefault:
topic = DEFAULT_TOPIC
if not allEnabled:
return []
if topicEnabled:
listeners = list(self.__listeners.get(topic, {}).values())
if not isDefault:
listeners.extend(self.__listeners.get(DEFAULT_TOPIC, {}).values())
return listeners
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment