nommage des événements.
[minwii.git] / src / app / eventutils.py
index 10ddbad..e45d5a3 100755 (executable)
@@ -6,7 +6,7 @@ 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'
 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.
 
 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.
@@ -27,28 +27,89 @@ $Id$
 $URL$
 """
 import types
 $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 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) :
 
 
 class EventHandlerMixin(object) :
-    __metaclass__ = MetaRenamer
-    
-    def input(self, event) :
-        handler = getattr(self, 'eventHandler%s' % event.type, lambda e:None)
-        handler(event)
+    __metaclass__ = EventInitializer