4a51f79741de315073265c50da25673aec77639a
[audiocontrol.git] / Events.py
1 """Event handling and generation.
2
3 The Event module manages event generation. Events are created by
4 EventSource instances. Each event source is associated with a file
5 handle. This handle will be poll()'ed and the eventsource will be
6 called, as sonn as input is available."""
7
8 import select, Logger, Node
9
10 class _Event(tuple):
11
12     def __init__(self, elts):
13         tuple.__init__(self, elts)
14
15     context = property(lambda self: self[0], None, None)
16     code = property(lambda self: self[1], None, None)
17
18
19 def Event(context, code):
20     return _Event((context,code))
21
22
23 class EventSource(Node.Node):
24
25     def __init__(self, fd, context):
26         Node.Node.__init__(self)
27         self._fd = fd
28         self._context = context
29
30     def fd(self):
31         return self._fd
32
33     def context(self):
34         return self._context
35
36     def fileno(self):
37         return self._fd.fileno()
38
39     def readEvents(self):
40         raise NotImplementedError
41
42
43 class Dispatcher(Node.Node):
44
45     _sources = Node.NodeMap()
46
47     def __init__(self, keylist):
48         Node.Node.__init__(self)
49         self._sources = {}
50         self._callbacks = []
51         self._keylist = keylist
52         self._poller = select.poll()
53
54     def registerSource(self, eventSource):
55         self._sources[eventSource.fileno()] = eventSource
56         self._poller.register(eventSource.fileno(),select.POLLIN)
57
58     def unregisterSource(self, eventSource):
59         del self._sources[eventSource.fileno()]
60         self._poller.unregister(eventSource.fileno())
61
62     def registerCallback(self,cb):
63         self._callbacks.append(cb)
64
65     def unregisterCallback(self,cb):
66         self._callbacks.remove(cb)
67
68     def run(self):
69         while 1:
70             for cb in self._callbacks : cb()
71             try:
72                 pollEvents = self._poller.poll()
73             except select.error, v:
74                 if v[0]==4 : continue
75                 else       : raise
76             if not pollEvents : return
77             for fd, pollEvent in pollEvents:
78                 if pollEvent != select.POLLIN : return
79                 for event in  self._sources[fd].readEvents():
80                     Logger.log('dispatcher', 'event: ' + str(event))
81                     binding = self._keylist.lookup(event)
82                     if binding is not None:
83                         binding.execute()