notification.py
109 lines
| 3.8 KiB
| text/x-python
|
PythonLexer
Barry Wark
|
r1410 | # encoding: utf-8 | |
"""The IPython Core Notification Center. | |||
See docs/blueprints/notification_blueprint.txt for an overview of the | |||
notification module. | |||
""" | |||
__docformat__ = "restructuredtext en" | |||
#----------------------------------------------------------------------------- | |||
# Copyright (C) 2008 The IPython Development Team | |||
# | |||
# Distributed under the terms of the BSD License. The full license is in | |||
# the file COPYING, distributed as part of this software. | |||
#----------------------------------------------------------------------------- | |||
class NotificationCenter(object): | |||
"""Synchronous notification center""" | |||
def __init__(self): | |||
super(NotificationCenter, self).__init__() | |||
Barry Wark
|
r1411 | self._init_observers() | |
def _init_observers(self): | |||
"""Initialize observer storage""" | |||
Barry Wark
|
r1410 | self.registeredTypes = set() #set of types that are observed | |
self.registeredSenders = set() #set of senders that are observed | |||
self.observers = {} #map (type,sender) => callback (callable) | |||
def post_notification(self, theType, sender, **kwargs): | |||
"""Post notification (type,sender,**kwargs) to all registered | |||
observers. | |||
Implementation | |||
-------------- | |||
* If no registered observers, performance is O(1). | |||
* Notificaiton order is undefined. | |||
* Notifications are posted synchronously. | |||
""" | |||
if(theType==None or sender==None): | |||
raise Exception("NotificationCenter.post_notification requires \ | |||
type and sender.") | |||
# If there are no registered observers for the type/sender pair | |||
Barry Wark
|
r1411 | if((theType not in self.registeredTypes and None not in self.registeredTypes) or | |
(sender not in self.registeredSenders and None not in self.registeredSenders)): | |||
print theType,sender,self.registeredTypes,self.registeredSenders | |||
Barry Wark
|
r1410 | return | |
Barry Wark
|
r1411 | for o in self._observers_for_notification(theType, sender): | |
Barry Wark
|
r1410 | o(theType, sender, args=kwargs) | |
Barry Wark
|
r1411 | ||
def _observers_for_notification(self, theType, sender): | |||
"""Find all registered observers that should recieve notification""" | |||
Barry Wark
|
r1410 | ||
Barry Wark
|
r1411 | keys = ( | |
(theType,sender), | |||
(theType, None), | |||
(None, sender), | |||
(None,None) | |||
) | |||
obs = set() | |||
for k in keys: | |||
obs.update(self.observers.get(k, set())) | |||
return obs | |||
Barry Wark
|
r1410 | ||
Barry Wark
|
r1411 | ||
def add_observer(self, callback, theType, sender): | |||
Barry Wark
|
r1410 | """Add an observer callback to this notification center. | |
The given callback will be called upon posting of notifications of | |||
the given type/sender and will receive any additional kwargs passed | |||
to post_notification. | |||
Parameters | |||
---------- | |||
observerCallback : callable | |||
Callable. Must take at least two arguments:: | |||
observerCallback(type, sender, args={}) | |||
theType : hashable | |||
The notification type. If None, all notifications from sender | |||
will be posted. | |||
sender : hashable | |||
The notification sender. If None, all notifications of theType | |||
will be posted. | |||
""" | |||
Barry Wark
|
r1411 | assert(callback != None) | |
Barry Wark
|
r1410 | self.registeredTypes.add(theType) | |
self.registeredSenders.add(sender) | |||
Barry Wark
|
r1411 | self.observers.setdefault((theType,sender), set()).add(callback) | |
def remove_all_observers(self): | |||
"""Removes all observers from this notification center""" | |||
self._init_observers() | |||
Barry Wark
|
r1410 | ||
sharedCenter = NotificationCenter() |