1 '''
2 Defines the L{AccessEngine} class which runs the main program loop.
3
4 @author: Peter Parente
5 @organization: IBM Corporation
6 @copyright: Copyright (c) 2005, 2007 IBM Corporation
7 @license: The BSD License
8
9 All rights reserved. This program and the accompanying materials are made
10 available under the terms of the BSD license which accompanies
11 this distribution, and is available at
12 U{http://www.opensource.org/licenses/bsd-license.php}
13 '''
14 import gobject, bonobo
15 import EventManager, ViewManager, TierManager, DeviceManager, SettingsManager
16 import time, signal, logging
17 from i18n import _
18
19 log = logging.getLogger('AccessEngine')
20
22 '''
23 Runs the main bonobo loop so that AT-SPI events are received and GUI monitors
24 function properly. Allows clients to register for callbacks from the main loop
25 on a set interval. Maintains a dictionary of managers that can be loaned out
26 to L{Task.Tools} objects
27
28 @ivar callbacks: Callback IDs for functions to invoke on timers or idle using
29 gobject
30 @type callbacks: dictionary
31 @ivar vm: Reference to the L{ViewManager}
32 @type vm: L{ViewManager}
33 @ivar tm: Reference to the L{TierManager}
34 @type tm: L{TierManager}
35 @ivar em: Reference to the L{EventManager}
36 @type em: L{EventManager}
37 @ivar dm: Reference to the L{DeviceManager}
38 @type dm: L{DeviceManager}
39 @ivar sm: Reference to the L{SettingsManager}
40 @type sm: L{SettingsManager}
41 @ivar manager_dict: Dictionary of managers keyed by manager names (device_man,
42 event_man, tier_man, and view_man)
43 @type manager_dict: dictionary
44 @ivar none_dict: Dictionary of None values with the same keys as
45 L{manager_dict}
46 @type none_dict: dictionary
47 @ivar profile: Name of the profile this instance of L{AccessEngine} was
48 started under
49 @type profile: string
50 @ivar welcome: Output an introductory message when the engine starts?
51 @type welcome: boolean
52 '''
54 '''
55 Creates the L{ViewManager}, L{TierManager}, and L{EventManager} objects.
56 Calls the init method here to intialize the managers with references to
57 other managers.
58
59 @param profile: Name of the profile LSR was executed under
60 @type profile: string
61 @param welcome: Output an introductory message?
62 @type welcome: boolean
63 '''
64 self.profile = profile
65 self.callbacks = {}
66 self.alive = False
67 self.manager_dict = None
68 self.none_dict = None
69 self.welcome = welcome
70
71
72 self.sm = SettingsManager.SettingsManager(self.profile)
73 self.em = EventManager.EventManager(self)
74 self.vm = ViewManager.ViewManager(self)
75 self.tm = TierManager.TierManager(self)
76 self.dm = DeviceManager.DeviceManager(self)
77
78 - def _init(self, **managers):
79 '''
80 Calls init on each manager providing it with references to the other
81 managers in case it wants to hold one or more references. Called implicitly
82 by L{run}.
83
84 @keyword event_man: Reference to the L{EventManager}
85 @type event_man: L{EventManager}
86 @keyword view_man: Reference to the L{ViewManager}
87 @type view_man: L{ViewManager}
88 @keyword tier_man: Reference to the L{TierManager}
89 @type tier_man: L{TierManager}
90 @keyword device_man: Reference to the L{DeviceManager}
91 @type device_man: L{DeviceManager}
92 @keyword sett_man: Reference to the L{SettingsManager}
93 @type sett_man: L{SettingsManager}
94 '''
95
96
97 self.manager_dict = managers
98
99
100 self.none_dict = dict([(name, None) for name in managers.keys()])
101
102 self.sm.init(**managers)
103 self.em.init(**managers)
104 self.vm.init(**managers)
105 self.tm.init(**managers)
106 self.dm.init(**managers)
107
108
109 if self.welcome:
110 self.dm.sendWelcome()
111
112 self.em.flushEvents()
113
114
115 self.vm.initViews()
116
118 '''
119 Shutsdown all managers. Called implicitly by L{run} when the main loop
120 ends. Sends an exiting message to the default device.
121 '''
122 if self.welcome:
123 self.dm.sendGoodbye()
124 self.tm.close()
125 self.vm.close()
126 self.em.close()
127 self.sm.close()
128 self.dm.close()
129
130 - def quit(self, *args):
131 '''
132 Quits the gtk main loop. Extra parameters are ignored but captured by args
133 so that this method may be reigstered as a signal handler callback.
134 '''
135 try:
136 bonobo.main_quit()
137 except RuntimeError:
138
139 return
140
142 '''
143 Updates the namespace dictionary of the given object with the names and
144 values of the managers stored in L{manager_dict}. These references can be
145 wiped out by a later call to L{unloanManagers}.
146
147 @param obj: An object with a __dict__ attribute
148 @type obj: object
149 '''
150 obj.__dict__.update(self.manager_dict)
151
153 '''
154 Updates the namespace dictionary of the given object with the names and
155 None values of stored in L{none_dict}. This effectively wipes out references
156 to managers previously loaned out by L{loanManagers}.
157
158 @param obj: An object with a __dict__ attribute
159 @type obj: object
160 '''
161 obj.__dict__.update(self.none_dict)
162
163 - def addTimer(self, callback, ms=None, *args):
164 '''
165 Creates a timer that calls the given callback on the interval specified by
166 the given milliseconds. If ms is None, registers for callbacks on idle.
167
168 @param callback: Function to call
169 @type callback: callable
170 @param args: Additional arguments to be given to the callback
171 @type args: list
172 '''
173 if ms is not None:
174 cid = gobject.timeout_add(ms, callback, *args)
175 else:
176 cid = gobject.idle_add(ms, callback, *args)
177 self.callbacks[callback] = cid
178
180 '''
181 Ceases calls to the given registered callback.
182
183 @param callback: Function to stop calling
184 @type callback: callable
185 @raise KeyError: When the callback is not already registered
186 '''
187 cid = self.callbacks[callback]
188 gobject.source_remove(cid)
189
191 '''
192 Runs an event loop by creating a gobject.MainLoop object and calling the
193 iteration method of its gobject.MainContext. Makes the timer callbacks
194 registered via L{AccessEngine.addTimer} on each iteration of the loop.
195 '''
196
197 self.alive = True
198
199
200 signal.signal(signal.SIGINT, self.quit)
201 signal.signal(signal.SIGTERM, self.quit)
202
203
204 self._init(event_man=self.em, view_man=self.vm, tier_man=self.tm,
205 device_man=self.dm, sett_man=self.sm)
206
207
208
209 def releaseGIL():
210 time.sleep(1e-5)
211 return True
212
213 i = gobject.idle_add(releaseGIL)
214 bonobo.main()
215 gobject.source_remove(i)
216
217
218 for c in self.callbacks:
219 self.removeTimer(c)
220
221
222 self._close()
223
224
225 log.info('exiting...')
226
227 time.sleep(1)
228
230 '''
231 Gets the name of the profile this L{AccessEngine} instance is running
232 under.
233
234 @return: Name of the profile
235 @rtype: string
236 '''
237 return self.profile
238