X-Git-Url: https://scm.cri.ensmp.fr/git/minwii.git/blobdiff_plain/e7854ed82aa375273bfbf772493739f875817061..46f3ffd7fdde386f41020171b5733e55a8e64a85:/src/minwii/eventutils.py?ds=sidebyside diff --git a/src/minwii/eventutils.py b/src/minwii/eventutils.py new file mode 100755 index 0000000..11e0d5c --- /dev/null +++ b/src/minwii/eventutils.py @@ -0,0 +1,105 @@ +# -*- 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