création d'un dispatcher d'événement central.
[minwii.git] / src / app / eventutils.py
1 # -*- coding: utf-8 -*-
2 """
3 Décorateur, métaclasse et classe mixin pour faciliter
4 l'implémentation des gestionnaires d'événements pygame.
5
6 Utilisation :
7 - hériter de EventHandlerMixin
8 - décorer les méthodes gestionnaires d'événements avec le décorateur 'event_handler'
9 en passant en paramètre le code d'événement pygame
10
11 Il n'existe aucune contrainte sur le nommage de la méthode décorée.
12 La méthode gestionnaire d'événement reçoit l'événement pygame comme unique paramètre.
13
14 par exemple :
15
16 import pygame
17 class Machin(pygame.sprite.Sprite, EventHandlerMixin) :
18
19 # .../...
20
21 @event_handler(pygame.KEYDOWN)
22 def handleKeyDown(self, event) :
23 pass
24
25
26 $Id$
27 $URL$
28 """
29 import types
30 import pygame
31
32 class _EventDispatcher :
33 def __init__(self) :
34 self.registry = {}
35
36 def addEventListener(self, eventType, listener) :
37 if self.registry.has_key(eventType) :
38 self.registry[eventType].append(listener)
39 else :
40 self.registry[eventType] = [listener]
41
42 def dispatchEvents(self) :
43 events = pygame.event.get()
44 for event in events :
45 listeners = self.registry.get(event.type, [])
46 for listener in listeners :
47 listener(event)
48
49 EventDispatcher = _EventDispatcher()
50
51 def event_handler(eventType) :
52 def markFunctionAsListener(m) :
53 m.__islistener__ = True
54 m.__eventtype__ = eventType
55 return m
56 return markFunctionAsListener
57
58
59 class EventInitializer(type):
60
61 def __init__(cls, name, bases, dict) :
62 def init_listeners(self) :
63 for k, v in dict.items() :
64 if isinstance(v, types.FunctionType) and hasattr(v, '__islistener__') :
65 listener = getattr(self, k)
66 EventDispatcher.addEventListener(v.__eventtype__, listener)
67 del v.__islistener__
68 del v.__eventtype__
69
70 def ctor(self, *args, **kw) :
71 init_listeners(self)
72 default_ctor = dict.get('__init__')
73 if not default_ctor :
74 super(cls, self).__init__(*args, **kw)
75 else :
76 default_ctor(self, *args, **kw)
77
78 cls.__init__ = ctor
79
80
81 class EventHandlerMixin(object) :
82 __metaclass__ = EventInitializer
83
84 #def input(self) :
85 # event = pygame.event.wait()
86 # handler = getattr(self, 'eventHandler%s' % event.type, lambda e:None)
87 # handler(event)