SF.net SVN: fclient: [134] trunk/sandbox/fcp/fcp_lib/events.py
Status: Pre-Alpha
Brought to you by:
jurner
From: <ju...@us...> - 2008-02-04 11:49:35
|
Revision: 134 http://fclient.svn.sourceforge.net/fclient/?rev=134&view=rev Author: jurner Date: 2008-02-04 03:49:28 -0800 (Mon, 04 Feb 2008) Log Message: ----------- reworked events Modified Paths: -------------- trunk/sandbox/fcp/fcp_lib/events.py Modified: trunk/sandbox/fcp/fcp_lib/events.py =================================================================== --- trunk/sandbox/fcp/fcp_lib/events.py 2008-02-04 03:17:38 UTC (rev 133) +++ trunk/sandbox/fcp/fcp_lib/events.py 2008-02-04 11:49:28 UTC (rev 134) @@ -1,104 +1,63 @@ """Signals and events""" -#*********************************************************************** +#********************************************************************* # -# event handler. Mostly taken from -#http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410686 -# -#*********************************************************************** -class EventMeta(type): - """Metaclass for events""" - - class Event(object): - """Event handler - - @ivar observers: list of observers of the event - """ - - def __init__(self, name): - """ - @param name: (str) name of the event - """ - self.name = name - self.observers = [] - - def __call__(self, *args, **kwargs): - """Dispatches the event and additional parameters to all observers registerd""" - for o in self.observers: - o(self, *args, **kwargs) - - def __contains__(self, observer): - """Checks if an observer is aleady registered - @return: bool - """ - return observer in self.observers - - def __iadd__(self, observer): - """Adds an observer to the event - @note: the observer will be called with the event as first paraeter, - followed by any number of *args or **kwargs passed by the caller of an event - """ - self.observers.append(observer) - return self - - def __isub__(self, observer): - """Removes the first occurence of an observer from the event""" - self.observers.remove(observer) - return self - - def __new__(clss, name, bases, kws): - events = kws.get('_events_', None) - if events is None: - raise ValueError('Event classes must implement an "_event_" attribute') - for event_name in events: - kws[event_name] = clss.Event(event_name) - return type.__new__(clss, name, bases, kws) - - +#********************************************************************* class Events(object): - """Base class for events + """Events - Derrived classes should list events they support in the "_events_" tuple. - Each event name is automagically set as attribute of the event - class. + Class to bundle events. Usually you would add events to it by + adding one or more event classes as inner classes. As soon + as the class is instantiated the events will be auto initialized + and available as callable objects. - Listeners may register to receiving events by calling __iadd__, - unregister by calling __isub__ on these attributes. Callback are - always called with the event as first argument, followed by additional - arguments, depending on the event. + >>> class MyEvents(Events): + ... class event1(Event): pass + ... class event2(Event): pass - @note: always make shure to disconnnect when event notification is no longer desired - - - >>> class MyEvents(Events): - ... _events_ = ('FooEvent', 'BarEvent') - ... >>> events = MyEvents() - >>> def cb(event): - ... print 'Received: %s' % event.name + >>> sorted([event.name for event in events]) + ['event1', 'event2'] - >>> events.FooEvent += cb - >>> events.FooEvent() - Received: FooEvent + >>> def myCallback(event, arg): print arg + >>> events += (events.event1, myCallback), (events.event2, myCallback) + >>> events.event1('foo') + foo + >>> events.event2('bar') + bar - >>> events.FooEvent -= cb - >>> events.FooEvent() + >>> events -= (events.event1, myCallback), (events.event2, myCallback) + >>> events.event1('foo') - >>> events += ( (events.FooEvent, cb), (events.BarEvent, cb) ) - >>> events.FooEvent() - Received: FooEvent - >>> events.BarEvent() - Received: BarEvent + >>> events.event1 += myCallback + >>> events.event1('foo') + foo - >>> events -= ( (events.FooEvent, cb), (events.BarEvent, cb) ) - >>> events.FooEvent() + >>> events.event1 -= myCallback + >>> events.event1('foo') + + @note: this class is a bit of a hack. You may not add any (not with underscore starting) + attrs, methods to it except from events + """ - >>> events.BarEvent() + def __init__(self): + """""" + for name in dir(self): + if not name.startswith('_'): + event = getattr(self, name) + setattr(self, name, event(name)) + + - """ - __metaclass__ = EventMeta - _events_ = () - + def __iter__(self): + """Iterator over all events of the instance + @return: (L{Event}) next event in turn + """ + for name in dir(self): + if not name.startswith('_'): + event = getattr(self, name) + yield getattr(self, name) + def __iadd__(self, events): """Adds one or more events / observers at once @param events: tuple( (event, observer), (event, observer), ...) @@ -114,8 +73,60 @@ for event, observer in events: event -= observer return self + +#********************************************************************* +# +#********************************************************************* +class Event(object): + """Event class + + @ivar name: name of the event + @ivar observers: observers listening to the event + + >>> event = Event('myEventsName') + >>> event.name + 'myEventsName' + + >>> def myCallback(event, arg): print arg + >>> event += myCallback + >>> event('foo') + foo + + >>> event -= myCallback + >>> event('foo') + """ + + def __init__(self, name): + """ + @param name: name of the event + """ + self.name = name + self.observers = [] + + def __call__(self, *args, **kwargs): + """Dispatches the event and additional parameters to all observers registerd""" + for o in self.observers: + o(self, *args, **kwargs) + + def __contains__(self, observer): + """Checks if an observer is aleady registered + @return: bool + """ + return observer in self.observers - + def __iadd__(self, observer): + """Adds an observer to the event + @note: the observer will be called with the event as first paraeter, + followed by any number of *args or **kwargs passed by the caller of an event + """ + self.observers.append(observer) + return self + + def __isub__(self, observer): + """Removes the first occurence of an observer from the event""" + self.observers.remove(observer) + return self + #********************************************************************* # #********************************************************************* This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |