[Zope3-checkins] CVS: Zope3/src/zope/event - __init__.py:1.1.2.1 eventchannel.py:1.1.2.1 subscribable.py:1.1.2.1
Jim Fulton
jim@zope.com
Mon, 23 Dec 2002 14:32:49 -0500
Update of /cvs-repository/Zope3/src/zope/event
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/event
Added Files:
Tag: NameGeddon-branch
__init__.py eventchannel.py subscribable.py
Log Message:
Initial renaming before debugging
=== Added File Zope3/src/zope/event/__init__.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Revision information:
$Id: __init__.py,v 1.1.2.1 2002/12/23 19:32:48 jim Exp $
"""
from zope.component import getService
from zope.interfaces.event import IEvent
def getEventService(context):
return getService(context, 'Events')
def publish(context, event):
return getEventService(context).publish(event)
def subscribe(subscriber, event_type=IEvent, filter=None, context=None):
if context is None:
context = subscriber
return getEventService(context).subscribe(
subscriber, event_type, filter)
def subscribeMany(subscriber, event_types=(IEvent,),
filter=None, context=None):
if context is None:
context = subscriber
subscribe = getEventService(context).subscribe
for event_type in event_types:
subscribe(subscriber, event_type, filter)
def unsubscribe(subscriber, event_type=None, filter=None, context=None):
if context is None: context=subscriber
return getEventService(context).unsubscribe(
subscriber, event_type, filter)
def listSubscriptions(subscriber, event_type=None, context=None):
if context is None: context=subscriber
return getEventService(context).listSubscriptions(
subscriber, event_type)
=== Added File Zope3/src/zope/event/eventchannel.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Revision information:
$Id: eventchannel.py,v 1.1.2.1 2002/12/23 19:32:48 jim Exp $
"""
from zope.event.subscribable import Subscribable
from zope.interfaces.event import IEventChannel
class EventChannel(Subscribable):
__implements__ = IEventChannel
def notify(self, event):
for subscriptions in self.subscriptionsForEvent(event):
for subscriber, filter in subscriptions:
if filter is not None and not filter(event):
continue
subscriber.notify(event)
=== Added File Zope3/src/zope/event/subscribable.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Revision information:
$Id: subscribable.py,v 1.1.2.1 2002/12/23 19:32:48 jim Exp $
"""
__metaclass__ = type
from zope.interface.type import TypeRegistry
from zope.exceptions import NotFoundError
from zope.interfaces.event import ISubscribable
from zope.interfaces.event import ISubscriptionAware
from zope.interfaces.event import IEvent
from zope.proxy.introspection import removeAllProxies
class Subscribable:
"""a global mix-in"""
__implements__ = ISubscribable
# plus has subscriptionsForEvent
def __init__(self):
self._registry = TypeRegistry()
self._subscribers = [] # using a list rather than a dict so
# that subscribers may define custom __eq__ methods
_clear = __init__
def subscribe(self, subscriber, event_type=IEvent, filter=None):
clean_subscriber = removeAllProxies(subscriber)
if ISubscriptionAware.isImplementedBy(subscriber):
subscriber.subscribedTo(self, event_type, filter)
if event_type is IEvent:
event_type = None # optimization
subscribers = self._registry.setdefault(event_type, [])
subscribers.append((clean_subscriber, filter))
for sub in self._subscribers:
if sub[0] == clean_subscriber:
sub[1][event_type] = 1
break
else:
self._subscribers.append((clean_subscriber, {event_type: 1}))
self._registry = self._registry #trigger persistence, if pertinent
def unsubscribe(self, subscriber, event_type=None, filter=None):
clean_subscriber=removeAllProxies(subscriber)
for subscriber_index in range(len(self._subscribers)):
sub=self._subscribers[subscriber_index]
if sub[0]==clean_subscriber:
ev_set=sub[1]
break
else:
if event_type: raise NotFoundError(subscriber)
else: return # this was a generic unsubscribe all request;
# work may have been done by a local service
do_alert=ISubscriptionAware.isImplementedBy(clean_subscriber)
if event_type:
ev_type=event_type
if event_type is IEvent:
ev_type=None # handle optimization
if ev_type not in ev_set:
raise NotFoundError(subscriber, event_type, filter)
subscriptions = self._registry.get(ev_type)
if not subscriptions:
raise NotFoundError(subscriber, event_type, filter)
try:
subscriptions.remove((clean_subscriber, filter))
except ValueError:
raise NotFoundError(subscriber, event_type, filter)
if do_alert:
subscriber.unsubscribedFrom(self, event_type, filter)
if len(ev_set)==1:
for sub in subscriptions:
if sub[0]==clean_subscriber:
break
else:
del self._subscribers[subscriber_index]
else:
for ev_type in ev_set:
subscriptions = self._registry.get(ev_type)
subs=subscriptions[:]
subscriptions[:] = []
for sub in subs:
if sub[0] == clean_subscriber: # deleted (not added back)
if do_alert:
subscriber.unsubscribedFrom(
self, ev_type or IEvent, sub[1])
# IEvent switch is to make optimization transparent
else: # kept (added back)
subscriptions.append(sub)
del self._subscribers[subscriber_index]
self._registry=self._registry #trigger persistence, if pertinent
def subscriptionsForEvent(self, event):
# XXX currently a non-interface method:
# just a more readable prettification
# used only for notify methods now. Could this be replaced
# with an explanatory comment in the code that uses it?
return self._registry.getAllForObject(event)
def listSubscriptions(self, subscriber, event_type=None):
subscriber=removeAllProxies(subscriber)
result=[]
if event_type:
ev_type=event_type
if event_type is IEvent:
ev_type=None # handle optimization
subscriptions = self._registry.get(ev_type)
if subscriptions:
for sub in subscriptions:
if sub[0]==subscriber:
result.append((event_type, sub[1]))
else:
for subscriber_index in range(len(self._subscribers)):
sub=self._subscribers[subscriber_index]
if sub[0]==subscriber:
ev_set=sub[1]
break
else:
return result
for ev_type in ev_set:
subscriptions = self._registry.get(ev_type)
if subscriptions:
for sub in subscriptions:
if sub[0]==subscriber:
result.append((ev_type or IEvent, sub[1]))
return result