Audio/AudioControl: Commit loads of long uncommited changes
[audiocontrol.git] / Events.py
index 4a51f79..8a64f47 100644 (file)
--- a/Events.py
+++ b/Events.py
@@ -5,19 +5,35 @@ EventSource instances. Each event source is associated with a file
 handle. This handle will be poll()'ed and the eventsource will be
 called, as sonn as input is available."""
 
-import select, Logger, Node
+import select, Logger, Node, Actions
 
-class _Event(tuple):
+class Event(object):
 
-    def __init__(self, elts):
-        tuple.__init__(self, elts)
+    def __init__(self, context, code):
+        self.context = context
+        self.code = code
 
-    context = property(lambda self: self[0], None, None)
-    code = property(lambda self: self[1], None, None)
+    def __getitem__(self, index):
+        rerturn (self.context, self.code)[index]
 
+    def __cmp__(self, other):
+        return cmp(self.context, other.context) or cmp(self.code, other.code)
 
-def Event(context, code):
-    return _Event((context,code))
+    def __hash__(self):
+        return hash(self.context) ^ hash(self.code)
+
+    def __str__(self):
+        return repr((self.context, self.code))
+
+
+class ControlEvent(Event):
+
+    def __init__(self, context, code, value):
+        Event.__init__(self, context, code)
+        self.value = value
+
+    def __str__(self):
+        return repr((self.context, self.code, self.value))
 
 
 class EventSource(Node.Node):
@@ -50,6 +66,9 @@ class Dispatcher(Node.Node):
         self._callbacks = []
         self._keylist = keylist
         self._poller = select.poll()
+        self._event = None
+        self._interval = None
+        self._idleCallback = None
 
     def registerSource(self, eventSource):
         self._sources[eventSource.fileno()] = eventSource
@@ -65,19 +84,46 @@ class Dispatcher(Node.Node):
     def unregisterCallback(self,cb):
         self._callbacks.remove(cb)
 
+    def currentEvent(self):
+        return self._event
+
+    def setIdleCallback(self, cb, interval):
+        self._interval = interval
+        self._idleCallback = cb
+
+    def unsetIdleCallback(self):
+        self._interval = None
+        self._idleCallback = None
+
+    def emit(self, event):
+        binding = self._keylist.lookup(event)
+        if binding is not None:
+            self._event = event
+            binding.execute()
+            self._event = None
+            
     def run(self):
         while 1:
             for cb in self._callbacks : cb()
             try:
-                pollEvents = self._poller.poll()
+                pollEvents = self._poller.poll(self._interval)
             except select.error, v:
                 if v[0]==4 : continue
                 else       : raise
-            if not pollEvents : return
+            if not pollEvents and self._idleCallback:
+                self._idleCallback()
             for fd, pollEvent in pollEvents:
                 if pollEvent != select.POLLIN : return
                 for event in  self._sources[fd].readEvents():
                     Logger.log('dispatcher', 'event: ' + str(event))
-                    binding = self._keylist.lookup(event)
-                    if binding is not None:
-                        binding.execute()
+                    self.emit(event)
+
+class EmitEvent(Actions.Action):
+
+    def __init__(self, name, dispatcher, event):
+        Actions.Action.__init__(self, name)
+        self._dispatcher = dispatcher
+        self._event = event
+
+    def __call__(self, binding):
+        self._dispatcher.emit(self._event)