#
#
# vim: ts=4 sw=4 sts=0 expandtab:
import os
import copy
import traceback
import logging

import generator

logger = logging.getLogger(__name__)

class Event(object):
    """
    This is a simple object which represent an event it can be dispatched which
    notifies every observer of this event
    """
    name = ""
    types = None
    def __init__(self, *args):
        """
        Init procedure
        """
        self.clear()
        self.uid_gen = generator.uid_generator()
        if len(args) != 0:
            self.types = args

    def addObserver(self, obj, *args, **kwarg):
        """
        This method add an observer for this event. Every argument passed to
        this function will be forwarded to the callback when the event is fired
        """
        if not callable(obj):
            raise RuntimeError("Callback must be callable")

        oid = self.uid_gen.next() if 'id' not in kwarg else kwarg.pop('id')
        self.observers[oid] = (obj, args)
        return oid

    def removeObserver(self, obj):
        """
        This method remove an observer for the event.
        """
        del self.observers[obj]

    def dispatch(self, *args):
        """
        This method dispatch the events with arguments which are forwarded to
        the listener functions.
        """
        for callback, cargs in self.observers.itervalues():
            try:
                callback(*(args + cargs))
            except Exception, e:
                traceback.print_exc()

    def __call__(self, *args):
        self.dispatch(*args)

    def clear(self):
        """
        Clear the observer dictionary.
        """
        self.observers = {}

    def __len__(self):
        return len(self.observers)

class ThreadedEvent(Event):
    def dispatch(self, *args):
        o2 = copy.copy(self.observers)
        for callback, cargs in o2.itervalues():
            try:
                callback(*(args + cargs))
            except Exception, e:
                traceback.print_exc()

class EventDispatcherBase(object):
    """
    This object act as a base object for an aglomerate of events. It provides
    the possibility tp register a single object for every events in the object.
    It is also in charge of initializing events.
    """
    events = []
    event_type = Event
    def __init__(self):
        """
        Simple Init method which creates the events
        """
        for evt_name in self.events:
            if hasattr(self, evt_name + "Event"):
                    logger.warning("Event Function Override -- %s --" % evt_name)
            else:
                evt = self.event_type()
                setattr(self, evt_name + "Event", evt)
                evt.name = evt_name

    def addObserver(self, obj, *args, **kw):
        """
        Add the right method observer to the contained event
        """
        for evt in self.events:
            try:
                getattr(self, evt + "Event").addObserver(getattr(obj, evt), *args, **kw)
            except AttributeError, err:
                if logger.isEnabledFor(logging.WARNING):
                    logger.warning("Object : %s do not have attribute -- %s --" % \
                               (repr(obj), evt))

    def removeObserver(self, obj):
        """
        Remove the right method observer to the contained event
        """
        for evt in self.events:
            try:
                getattr(self, evt).removeObserver(getattr(obj, evt), evt, *args, **kw)
            except AttributeError, err:
                if logger.isEnabledFor(logging.WARNING):
                    logger.warning("Object : %s do not have attribute -- %s --" % \
                               (repr(obj), evt))

    def clear(self):
        """
        Clear all events of this object
        """
        for evt in self.events:
            getattr(self, evt + "Event").clear()


class ThreadedEventDispatcher(EventDispatcherBase):
    event_type = ThreadedEvent


@@ -57,25 +57,8 @@
 opy%0A
-import traceback%0A
 impo
@@ -68,16 +68,16 @@
 logging%0A
+
 %0Aimport 
@@ -1294,32 +1294,37 @@
 %22%22%22%0A        for 
+id, (
 callback, cargs 
@@ -1318,24 +1318,25 @@
 lback, cargs
+)
  in self.obs
@@ -1342,29 +1342,28 @@
 servers.iter
-value
+item
 s():%0A       
@@ -1463,36 +1463,39 @@
         
-traceback.print_exc(
+logger.exception(str(e)
 )%0A%0A    d
@@ -1730,26 +1730,28 @@
 class Thread
+saf
 e
-d
 Event(Event)
@@ -1982,31 +1982,35 @@
     
-traceback.print_exc(
+logger.exception(str(e)
 )%0A%0A
+%0A
 clas
@@ -3886,26 +3886,28 @@
 class Thread
+saf
 e
-d
 EventDispatc
@@ -3955,17 +3955,19 @@
 = Thread
+saf
 e
-d
 Event%0A%0A

Change event