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 le code d'événement pygame
+ 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.
$URL$
"""
import types
+import pygame
+from StringIO import StringIO
+from logging import getLogger, basicConfig, DEBUG
+import sys
+from events import TIMEOUT, COLOVER, eventNames
+basicConfig(level=DEBUG, stream = sys.stdout)
+console = getLogger('minwii')
+eventLog = getLogger('minwii.events')
+
+hiddenEvents = {pygame.MOUSEMOTION:True,
+ TIMEOUT:True,
+ COLOVER:True,}
+
+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.warn("no listener to remove")
+
+ def dispatchEvents(self) :
+ events = pygame.event.get()
+ for event in events :
+ listeners = self.registry.get(event.type, {})
+ if listeners and not hiddenEvents.has_key(event.type) :
+ eventLog.info((eventNames.get(event.type, event.type), event))
+ for listener in listeners.keys() :
+ listener(event)
-def event_handler(eventType) :
- def doRename(m) :
- m.__name__ = 'eventHandler%s' % eventType
+ 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 doRename
+ return markFunctionAsListener
-class MetaRenamer(type):
- def __new__(mcs, name, bases, dict) :
- for k, v in dict.items() :
- if isinstance(v, types.FunctionType) :
- if k != v.__name__ :
- print 'renommage de %s en %s' % (k, v.__name__)
- dict[v.__name__] = v
- del dict[k]
- return type.__new__(mcs, name, bases, dict)
+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__ = MetaRenamer
-
- def input(self, event) :
- handler = getattr(self, 'eventHandler%s' % event.type, lambda e:None)
- handler(event)
+ __metaclass__ = EventInitializer