--- /dev/null
+# -*- coding: utf-8 -*-
+"""
+Décorateur, métaclasse et classe mixin pour faciliter
+l'implémentation des gestionnaires d'événements pygame.
+
+Utilisation :
+- hériter de EventHandlerMixin
+- décorer les méthodes gestionnaires d'événements avec le décorateur 'event_handler'
+ en passant en paramètre un ou plusieurs codes d'événement pygame
+
+Il n'existe aucune contrainte sur le nommage de la méthode décorée.
+La méthode gestionnaire d'événement reçoit l'événement pygame comme unique paramètre.
+
+par exemple :
+
+import pygame
+class Machin(pygame.sprite.Sprite, EventHandlerMixin) :
+
+ # .../...
+
+ @event_handler(pygame.KEYDOWN)
+ def handleKeyDown(self, event) :
+ pass
+
+
+$Id$
+$URL$
+"""
+import types
+import pygame
+from StringIO import StringIO
+from log import console, eventLogger
+
+class _EventDispatcher :
+ def __init__(self) :
+ self.registry = {}
+
+ def addEventListener(self, eventType, listener) :
+ if self.registry.has_key(eventType) :
+ self.registry[eventType][listener] = True
+ else :
+ self.registry[eventType] = {listener:True}
+
+ def removeEventListener(self, eventType, listener) :
+ try :
+ del self.registry[eventType][listener]
+ except KeyError :
+ console.debug("no listener to remove")
+
+ def dispatchEvents(self) :
+ events = pygame.event.get()
+ for event in events :
+ eventLogger.info(event)
+ listeners = self.registry.get(event.type, {})
+ for listener in listeners.keys() :
+ listener(event)
+
+ def reset(self) :
+ self.registry = {}
+
+ def __repr__(self) :
+ out = StringIO()
+ keys = self.registry.keys()
+ keys.sort()
+ for k in keys :
+ print >> out, "event", k
+ for listener in self.registry[k].keys() :
+ print >> out, listener.__name__
+ out.seek(0)
+ return out.read()
+
+
+EventDispatcher = _EventDispatcher()
+
+def event_handler(*eventTypes) :
+ def markFunctionAsListener(m) :
+ m.__islistener__ = True
+ m.__eventtypes__ = eventTypes
+ return m
+ return markFunctionAsListener
+
+
+class EventInitializer(type):
+
+ def __init__(cls, name, bases, dict) :
+ def init_listeners(self) :
+ for k, v in dict.items() :
+ if isinstance(v, types.FunctionType) and hasattr(v, '__islistener__') :
+ listener = getattr(self, k)
+ for eventType in v.__eventtypes__ :
+ EventDispatcher.addEventListener(eventType, listener)
+
+ def ctor(self, *args, **kw) :
+ default_ctor = dict.get('__init__')
+ if not default_ctor :
+ super(cls, self).__init__(*args, **kw)
+ else :
+ default_ctor(self, *args, **kw)
+ init_listeners(self)
+
+ cls.__init__ = ctor
+
+
+class EventHandlerMixin(object) :
+ __metaclass__ = EventInitializer