notification.py
122 lines
| 4.2 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. | |||
#----------------------------------------------------------------------------- | |||
class NotificationCenter(object): | |||
Barry Wark
|
r1412 | """Synchronous notification center | |
Example | |||
------- | |||
>>> 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 | |||
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
|
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 | ||
sharedCenter = NotificationCenter() |