Welcome, guest | Sign In | My Account | Store | Cart
#!/usr/bin/env python
# -*- coding: utf-8 -*-


# -----------------------------------------------------------------------------
# Event and EventDispatcher classes
# -----------------------------------------------------------------------------
   
class Event( object ):
   
"""
    Generic event to use with EventDispatcher.
    """

   
   
def __init__(self, event_type, data=None):
       
"""
        The constructor accepts an event type as string and a custom data
        """

       
self._type = event_type
       
self._data = data
       
   
@property
   
def type(self):
       
"""
        Returns the event type
        """

       
return self._type
       
   
@property
   
def data(self):
       
"""
        Returns the data associated to the event
        """

       
return self._data


class EventDispatcher( object ):
   
"""
    Generic event dispatcher which listen and dispatch events
    """

   
   
def __init__(self):
       
self._events = dict()
       
   
def __del__(self):
       
"""
        Remove all listener references at destruction time
        """

       
self._events = None
   
   
def has_listener(self, event_type, listener):
       
"""
        Return true if listener is register to event_type
        """

       
# Check for event type and for the listener
       
if event_type in self._events.keys():
           
return listener in self._events[ event_type ]
       
else:
           
return False
       
   
def dispatch_event(self, event):
       
"""
        Dispatch an instance of Event class
        """

       
# Dispatch the event to all the associated listeners
       
if event.type in self._events.keys():
            listeners
= self._events[ event.type ]
           
           
for listener in listeners:
                listener
( event )
       
   
def add_event_listener(self, event_type, listener):
       
"""
        Add an event listener for an event type
        """

       
# Add listener to the event type
       
if not self.has_listener( event_type, listener ):
            listeners
= self._events.get( event_type, [] )
       
            listeners
.append( listener )
           
           
self._events[ event_type ] = listeners
   
   
def remove_event_listener(self, event_type, listener):
       
"""
        Remove event listener.
        """

       
# Remove the listener from the event type
       
if self.has_listener( event_type, listener ):
            listeners
= self._events[ event_type ]
           
           
if len( listeners ) == 1:
               
# Only this listener remains so remove the key
               
del self._events[ event_type ]
               
           
else:
               
# Update listeners chain
                listeners
.remove( listener )
               
               
self._events[ event_type ] = listeners


# ------------------------------------------------------------------------------
# Events and Dispatcher example
#
# In this example we create a simple event MyEvent with only two event types,
# ASK and RESPOND, and two classes: WhoAsk, which send AKS event and listen for
# the RESPOND event, and WhoRespond, which listen for ASK events and send back
# a RESPOND event
# -----------------------------------------------------------------------------

class MyEvent( Event ):
   
"""
    When subclassing Event class the only thing you must do is to define
    a list of class level constants which defines the event types and the
    string associated to them
    """

   
    ASK    
= "askMyEvent"
    RESPOND
= "respondMyEvent"


class WhoAsk( object ):
   
"""
    First class which ask who is listening to it
    """

   
def __init__(self, event_dispatcher):
       
# Save a reference to the event dispatch
       
self.event_dispatcher = event_dispatcher
       
       
# Listen for the RESPOND event type
       
self.event_dispatcher.add_event_listener(
           
MyEvent.RESPOND, self.on_answer_event
       
)
       
   
def ask(self):
       
"""
        Dispatch the ask event
        """

       
print ">>> I'm instance {0}. Who are listening to me ?".format( self )

       
self.event_dispatcher.dispatch_event(
           
MyEvent( MyEvent.ASK, self )
       
)
       
   
def on_answer_event(self, event):
       
"""
        Event handler for the RESPOND event type
        """

       
print "<<< Thank you instance {0}".format( event.data )
       

class WhoRespond( object ):
   
"""
    Second class who respond to ASK events
    """

   
def __init__(self, event_dispatcher):
       
# Save event dispatcher reference
       
self.event_dispatcher = event_dispatcher
       
       
# Listen for ASK event type
       
self.event_dispatcher.add_event_listener(
           
MyEvent.ASK, self.on_ask_event
       
)
       
   
def on_ask_event(self, event):
       
"""
        Event handler for ASK event type
        """

       
self.event_dispatcher.dispatch_event(
           
MyEvent ( MyEvent.RESPOND, self )
       
)


if __name__ == "__main__":
   
# Create and instance of event dispatcher
    dispatcher
= EventDispatcher()
   
   
# Create an instance of WhoAsk class and two instance of WhoRespond class
    who_ask
= WhoAsk( dispatcher )
    who_responde1
= WhoRespond( dispatcher )
    who_responde2
= WhoRespond( dispatcher )
   
   
# WhoAsk ask :-)
    who_ask
.ask()

History