1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
"""
:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved.
:license: BSD, see LICENSE_BSD_Simple.txt for details.
"""
class PublisherMixin:
"""
Mixin for publishing messages to a topic's listeners. This will be
mixed into topicobj.Topic so that a user can use a Topic object to
send a message to the topic's listeners via a publish() method.
Note that it is important that the PublisherMixin NOT modify any
state data during message sending, because in principle it could
happen that a listener causes another message of same topic to be
sent (presumably, the listener has a way of preventing infinite
loop).
"""
def __init__(self):
pass
def publish(self, **msgKwargs):
self._publish(msgKwargs)
############## IMPLEMENTATION ###############
class IterState:
def __init__(self, msgKwargs):
self.filteredArgs = msgKwargs
self.argsChecked = False
def checkMsgArgs(self, spec):
spec.check(self.filteredArgs)
self.argsChecked = True
def filterMsgArgs(self, topicObj):
if self.argsChecked:
self.filteredArgs = topicObj.filterMsgArgs(self.filteredArgs)
else:
self.filteredArgs = topicObj.filterMsgArgs(self.filteredArgs, True)
self.argsChecked = True
def _mix_prePublish(self, msgKwargs, topicObj=None, iterState=None):
if iterState is None:
# do a first check that all args are there, costly so only do once
iterState = self.IterState(msgKwargs)
if self.hasMDS():
iterState.checkMsgArgs( self._getListenerSpec() )
else:
assert not self.hasListeners()
else:
iterState.filterMsgArgs(topicObj)
assert iterState is not None
return iterState
def _mix_callListener(self, listener, msgKwargs, iterState):
"""Send the message for given topic with data in msgKwargs.
This sends message to listeners of parent topics as well.
Note that at each level, msgKwargs is filtered so only those
args that are defined for the topic are sent to listeners. """
listener(iterState.filteredArgs, self, msgKwargs)
|