473,226 Members | 1,668 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,226 software developers and data experts.

Publish/subscribe event manager using weakrefs

'''

event.py

An event manager using publish/subscribe, and weakrefs.
Any function can publish any event without registering it first, and
any
object can register interest in any event, even if it doesn't exist
yet.
The event manager uses weakrefs, so lists of listeners won't stop them
from being garbage collected when they're deleted.

Any suggestions are appreciated!

Sample output:

EVENT init (0 listeners, possibly dead) ('No one is interested in this
event',)
EVENT ball (0 listeners, possibly dead) ('Look! A ball, but no one is
watching.',)
*** Fido is interested in Bone
*** Fido is interested in Ball
EVENT ball (1 listeners, possibly dead) ('Another ball! Watch, Fido!',)
*** Fido noses the ball forward
*** Fido is dead.
EVENT ball (1 listeners, possibly dead) ('No one is watching because
Fido is dead.',)
Removing <weakref at 00CE9F90; dead> from ball
*** Snowball is interested in Ball
*** Snowball is interested in Yarn
*** Snowball is interested in Fluffy chick
*** Spot is interested in Bone
*** Spot is interested in Ball
EVENT bone (2 listeners, possibly dead) ('Only dogs eat bones.',)
Removing <weakref at 00CE9F90; dead> from bone
*** Spot slobbers on the bone
EVENT ball (2 listeners, possibly dead) ('Cats and dogs both love this
one!',)
*** Snowball chases the ball
*** Spot noses the ball forward
EVENT yarn (1 listeners, possibly dead) ('ball of pink yarn',)
*** Snowball bats at the yarn.
EVENT raking (0 listeners, possibly dead) ('Humans working in the
yard',)
EVENT fluffychick (1 listeners, possibly dead) ('Ooh, how cute! An
Easter leftover walking in the yard.',)
*** Snowball eats the fluffy chick.
Removing listener {'name': 'Snowball'} from event fluffychick
EVENT fluffychick (0 listeners, possibly dead) ('The cat is full and no
longer interested in chicks.',)
*** Snowball is dead.
*** Spot is dead.
EVENT ball (2 listeners, possibly dead) ('Ball anyone? Fluffy? Spot?
Fido?',)
Removing <weakref at 00CE9FC0; dead> from ball
Removing <weakref at 00CFA030; dead> from ball
Done!


'''

import weakref

_events = {}

def Subscribe(eventname, self):
" Subscribe to an event, even if it doesn't exist yet."
eventname = eventname.lower()
eventname = eventname.replace(' ', '')
if not eventname in _events:
_events[eventname] = []
listeners = _events[eventname]
obj = weakref.ref(self)
if not obj in listeners:
listeners.append(obj)

def Unsubscribe(eventname, self):
" Unsubscribe from an event, even if it never existed."
eventname = eventname.lower()
eventname = eventname.replace(' ', '')
if not eventname in _events:
return
listeners = _events[eventname]
obj = weakref.ref(self)
if obj in listeners:
print "Removing listener %s from event %s" % (str(self),
eventname)
listeners.remove(obj)

def Raise(eventname, *args, **kwargs):
" Publish an event, no need to register it first."
eventname = eventname.lower()
eventname = eventname.replace(' ', '')
if not eventname in _events:
_events[eventname] = []
listeners = _events[eventname]
print "EVENT %s (%d listeners, possibly dead) %s" % (eventname,
len(listeners), str(args))
i = 0
while i < len(listeners):
obj = listeners[i]
listener = obj()
if listener:
fnname = 'On' + eventname[0].upper() +
eventname[1:].lower()
fn = getattr(listener, fnname, None)
if fn == None:
fn = getattr(listener, 'OnEvent')
fn(eventname, *args, **kwargs)
i += 1
else:
print "Removing %s from %s" % (str(obj), eventname)
listeners.remove(obj)
class Listener:
'''
Objects that want to be notified of events.
They should have an 'OnEventname' function for
every event they're interested in, or a single
function called 'OnEvent' to receive all events.
'''
_listen = []
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
for eventname in self._listen:
Subscribe(eventname, self)
print "*** %s is interested in %s" % (self.name, eventname)
def OnEvent(self, eventname, *args, **kwargs):
print "*** %s(%s, %s)" % (eventname, str(args), str(kwargs))
def __str__(self):
return str(self.__dict__)
def __del__(self):
print "*** %s is dead." % self.name


def main():

class Dog(Listener):
name = 'Dog'
_listen = ['Bone', 'Ball']
def OnEvent(self, eventname, *args, **kwargs):
if eventname == 'bone':
print "*** %s slobbers on the bone" % self.name
elif eventname == 'ball':
print "*** %s noses the ball forward" % self.name

class Cat(Listener):
name = 'Cat'
_listen = ['Ball', 'Yarn', 'Fluffy chick']
def OnBall(self, *args, **kwargs):
print "*** %s chases the ball" % self.name
def OnYarn(self, *args, **kwargs):
print "*** %s bats at the yarn." % self.name
def OnFluffychick(self, *args, **kwargs):
print "*** %s eats the fluffy chick." % self.name

Raise('INIT', 'No one is interested in this event')
Raise('BALL', 'Look! A ball, but no one is watching.')
dog = Dog(name = 'Fido')
Raise('BALL', 'Another ball! Watch, Fido!')
del dog
Raise('BALL', 'No one is watching because Fido is dead.')
cat = Cat(name = 'Snowball')
dog = Dog(name = 'Spot')
Raise('BONE', "Only dogs eat bones.")
Raise('BALL', "Cats and dogs both love this one!")
Raise('YARN', "ball of pink yarn")
Raise('RAKING', 'Humans working in the yard')
Raise('Fluffy chick', 'Ooh, how cute! An Easter leftover walking in
the yard.')
Unsubscribe('fluffy chick', cat)
Raise('Fluffy chick', 'The cat is full and no longer interested in
chicks.')
del cat
del dog
Raise('BALL', 'Ball anyone? Fluffy? Spot? Fido?')
print "Done!"

if __name__ == '__main__':
main()

Feb 15 '06 #1
0 2045

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: Adrian B. | last post by:
Does anyone know of a framework or library that will enable me to use publish/subscribe comms? I want to create a server (using Python) running on a Unix box that will accept client connections...
12
by: Ron Garret | last post by:
Why doesn't this work? >>> from weakref import ref >>> class C(str): pass .... >>> ref(C()) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: cannot create weak...
1
by: SKumar | last post by:
Hello: I am trying to implement a publish/subscribe model for an applications I am working on. I would very greatful if anybody could offer me some suggestions. The application basically is a...
4
by: Veriblue | last post by:
Hello Folks I am working on a applications which needs a publish/subscribe model to handle events. There can be various components involved and some maybe out of process. Ideally I would like...
5
by: NoNickname | last post by:
Basically, how do I know that the release versions of all components are being published? The Build | Configuration Manager is confusing me a little in VS2005. I have three projects in my...
21
by: Al Christoph | last post by:
I posted this last week end in the MSDN forums. No luck there. Let's see what the experts here have to say:-)))) I have a rather convoluted project. The distributable will come in eight...
1
by: kurt sune | last post by:
I am having trouble publishing a website for RELEASE. 1. web.config: <compilation defaultLanguage="vb" debug="false"> 2. in Configuration manager I set the configuration to Release for the...
3
by: Ludwig Wittgenstein | last post by:
Hello, all. Does anyone know of documentation about implementing a publish- subscribe model between a .NET Web service provide and a Java service consumer? I have this problem I am trying to...
3
by: =?Utf-8?B?Sm9obiBT?= | last post by:
Hi, I'm trying to publish a new web service that I've written. It's fine when I publish it on the local PC but I get Publish failed in the development environment when I try to publish it to...
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.