notification.py
125 lines
| 4.3 KiB
| text/x-python
|
PythonLexer
Barry Wark
|
r1410 | # encoding: utf-8 | ||
"""The IPython Core Notification Center. | ||||
Barry Wark
|
r1443 | See docs/source/development/notification_blueprint.txt for an overview of the | ||
Barry Wark
|
r1410 | 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. | ||||
#----------------------------------------------------------------------------- | ||||
Brian Granger
|
r1973 | # Tell nose to skip the testing of this module | ||
__test__ = {} | ||||
Barry Wark
|
r1410 | |||
class NotificationCenter(object): | ||||
Barry Wark
|
r1412 | """Synchronous notification center | ||
Fernando Perez
|
r2109 | Examples | ||
-------- | ||||
Barry Wark
|
r1412 | >>> import IPython.kernel.core.notification as notification | ||
>>> def callback(theType, theSender, args={}): | ||||
... print theType,theSender,args | ||||
... | ||||
>>> notification.sharedCenter.add_observer(callback, 'NOTIFICATION_TYPE', None) | ||||
Barry Wark
|
r1444 | >>> notification.sharedCenter.post_notification('NOTIFICATION_TYPE', object()) # doctest:+ELLIPSIS | ||
Barry Wark
|
r1443 | NOTIFICATION_TYPE ... | ||
Barry Wark
|
r1412 | |||
""" | ||||
Barry Wark
|
r1410 | def __init__(self): | ||
super(NotificationCenter, self).__init__() | ||||
Barry Wark
|
r1411 | self._init_observers() | ||
def _init_observers(self): | ||||
"""Initialize observer storage""" | ||||
Barry Wark
|
r1443 | self.registered_types = set() #set of types that are observed | ||
self.registered_senders = set() #set of senders that are observed | ||||
Barry Wark
|
r1410 | self.observers = {} #map (type,sender) => callback (callable) | ||
def post_notification(self, theType, sender, **kwargs): | ||||
"""Post notification (type,sender,**kwargs) to all registered | ||||
Fernando Perez
|
r2109 | observers. | ||
Implementation notes: | ||||
Barry Wark
|
r1410 | * 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
|
r1443 | if((theType not in self.registered_types and | ||
None not in self.registered_types) or | ||||
(sender not in self.registered_senders and | ||||
None not in self.registered_senders)): | ||||
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
|
r1443 | self.registered_types.add(theType) | ||
self.registered_senders.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 | |||
Fernando Perez
|
r2109 | sharedCenter = NotificationCenter() | ||