def subscribe_locally(self, messagetype, instance, callback): MessageBus.subscribe_locally(self, messagetype, instance, callback) for message in self.message_queue[messagetype]: if (message, message.sender) == (messagetype, instance): self.broadcast(message) self.message_queue[messagetype].remove(message)
def discard(cls, callback, sender=None): """Similar to `Message.unsubscribe`, but does not raise an error if the callback has not been registered before. """ if sender: MessageBus().discard_locally(cls, sender, callback) else: MessageBus().discard_globally(cls, callback)
def broadcast(self, message): messagetype = message.__class__ pair = (messagetype, message.sender) # check if the message will go anywhere, if not, then queue it if not len(self.global_receivers[messagetype]) and not len(self.local_receivers[pair]): self.message_queue[messagetype].append(message) else: MessageBus.broadcast(self, message)
def broadcast(self, message): messagetype = message.__class__ pair = (messagetype, message.sender) # check if the message will go anywhere, if not, then queue it if not len(self.global_receivers[messagetype]) and not len( self.local_receivers[pair]): self.message_queue[messagetype].append(message) else: MessageBus.broadcast(self, message)
def subscribe(cls, callback, sender=None): """Register a callback to be called whenever a message of this type is send. callback - Callable that receives an instance of a message as only argument. sender - If specified, the callback receives only messages that originated from sender. By default, all messages are received. Example: >>> def cb(msg): ... print 'Received', msg >>> MessageClass.subscribe(cb) # Global >>> MessageClass.subscribe(cb, sender=foo) # Specific sender """ if sender: MessageBus().subscribe_locally(cls, sender, callback) else: MessageBus().subscribe_globally(cls, callback)
def unsubscribe(cls, callback, sender=None): """Stop your subscription of this message type for the specified callback. callback - Callable that receives an instance of a message as only argument. The same you've been using with `Message.subscribe`. sender - If specified, the subscription will only be stopped for messages from this sender. By default, all subscriptions are ended. Note: There has to be a subscription, otherwise an error will be raised. Example: >>> MessageClass.subscribe(cb) >>> MessageClass.broadcast('sender') message received >>> MessageClass.unsubscribe(cb) >>> MessageClass.broadcast('sender') """ if sender: MessageBus().unsubscribe_locally(cls, sender, callback) else: MessageBus().unsubscribe_globally(cls, callback)
def broadcast(cls, *args): """Send a message that is initialized with `args`. The first argument is always a sender, the number of arguments has to be N + 1, with N being the number of arguments defined on the message class. Example: >>> class Foo(Message): ... arguments = ('a', 'b', ) >>> Foo.broadcast('sender', 1, 2) """ MessageBus().broadcast(cls(*args))
def subscribe_globally(self, messagetype, callback): MessageBus.subscribe_globally(self, messagetype, callback) while len(self.message_queue[messagetype]): self.broadcast(self.message_queue[messagetype].popleft())
def __init__(self): MessageBus.__init__(self) # Queue up messages if there is no registered subscriber self.message_queue = defaultdict(deque)
def discard(cls, callback): """Similar to `Message.unsubscribe`, but does not raise an error if the callback has not been registered before. """ MessageBus().discard_globally(cls, callback)
def subscribe_globally(self, messagetype, callback): MessageBus.subscribe_globally(self, messagetype, callback) while self.message_queue[messagetype]: self.broadcast(self.message_queue[messagetype].popleft())