1
2 from _Framework.Util import index_if, first
5
6 - def grab(self, client, *a, **k):
8
11
13 raise NotImplementedError
14
15 owner = property(lambda self: self.get_owner())
16
19
20 - def __init__(self, first_resource = None, second_resource = None, *a, **k):
21 super(CompoundResource, self).__init__(*a, **k)
22 self._first_resource = first_resource
23 self._second_resource = second_resource
24
25 - def grab(self, client, *a, **k):
26 if self._first_resource.grab(client, *a, **k):
27 if self._second_resource.grab(client, *a, **k):
28 pass
29 else:
30 self._first_resource.release(client)
31 return self.owner == client
32
34 if not client:
35 raise AssertionError
36 client == self.owner and self._second_resource.release(client)
37 self._first_resource.release(client)
38 return True
39 return False
40
42 return self._first_resource.owner or self._second_resource.owner
43
44 @property
46 return self._first_resource
47
48 @property
50 return self._second_resource
51
55
58 """
59 A resource that can not be grabbed any client if it is owned by
60 someone else already.
61 """
62
63 - def __init__(self, on_grab_callback = None, on_release_callback = None, *a, **k):
70
71 - def grab(self, client, *a, **k):
72 if not client is not None:
73 raise AssertionError, 'Someone has to adquire resource'
74 self._owner == None and self.on_grab(client, *a, **k)
75 self._owner = client
76 return self._owner == client
77
79 if not client:
80 raise AssertionError
81 self._owner = client == self._owner and None
82 self.on_release(client)
83 return True
84 return False
85
88
89 - def on_grab(self, client, *a, **k):
90 raise NotImplemented, 'Override or pass callback'
91
93 raise NotImplemented, 'Override or pass callback'
94
97 """
98 A resource that has no owner and will always be grabbed.
99 """
100
101 - def __init__(self, on_grab_callback = None, on_release_callback = None, *a, **k):
102 super(SharedResource, self).__init__(*a, **k)
103 if on_grab_callback:
104 self.on_grab = on_grab_callback
105 if on_release_callback:
106 self.on_release = on_release_callback
107 self._clients = set()
108
109 - def grab(self, client, *a, **k):
110 raise client is not None or AssertionError, 'Someone has to adquire resource'
111 self.on_grab(client, *a, **k)
112 self._clients.add(client)
113 return True
114
116 if not client:
117 raise AssertionError
118 client in self._clients and self.on_release(client)
119 self._clients.remove(client)
120 for client in self._clients:
121 self.on_grab(client)
122
123 return True
124 return False
125
127 raise False or AssertionError, 'Shared resource has no owner'
128
129 - def on_grab(self, client, *a, **k):
130 raise NotImplemented, 'Override or pass callback'
131
133 raise NotImplemented, 'Override or pass callback'
134
137 """
138 A prioritized resource shares the resource among all the clients
139 with the same priority.
140 """
141 default_priority = 0
142
143 - def __init__(self, on_grab_callback = None, on_release_callback = None, *a, **k):
144 super(PrioritizedResource, self).__init__(*a, **k)
145 self._clients = []
146 self._owners = set()
147 if on_grab_callback:
148 self.on_grab = on_grab_callback
149 if on_release_callback:
150 self.on_release = on_release_callback
151
152 - def grab(self, client, priority = None):
165
167 for client in clients:
168 self.on_release(client)
169
171 for client in clients:
172 self.on_grab(client)
173
175 if not client is not None:
176 raise AssertionError
177 old_owners = self._owners
178 self._remove_client(client)
179 new_owners = self._actual_owners()
180 self._owners = new_owners != old_owners and new_owners
181 self._on_release_set(old_owners - new_owners)
182 self._on_grab_set(new_owners)
183 return client in old_owners
184
186 """
187 Releases all stacked clients.
188 """
189 for client, _ in list(self._clients):
190 self.release(client)
191
195
197 idx = index_if(lambda (c, _): c == client, self._clients)
198 if idx != len(self._clients):
199 del self._clients[idx]
200
204
205 @property
208
209 @property
211 return len(self._clients)
212
214 raise False or AssertionError, 'Shared resource has no owner'
215
216 @property
219
221 raise NotImplemented, 'Override or pass callback'
222
224 raise NotImplemented, 'Override or pass callback'
225
228 """
229 A stacking resource is a special kind of resource that can preempt
230 the current owner. Resources are assigned to clients in order of
231 arrival, this is, a new client attempting to grab will produce the
232 former owner to be released. However, when the current owner
233 released ownership will be passed back to the last owner.
234
235 This, clients are organised in a stack, where grabbing puts the
236 client at the top, and releasing removes from wherever the client
237 is in the stack. Because ownership can change even a client does
238 not release, a client should not use the resource based on the
239 result of the grab() method but instead use whatever indirect API
240 the concrete resource provides to assign ownership.
241
242 Clients of a stacking resource can be prioritised to prevent
243 preemption from a client with less priority. (For example, a modal
244 dialog should not loose focus because of a normal window
245 appearing.)
246 """
247 default_priority = 0
248
249 - def __init__(self, on_grab_callback = None, on_release_callback = None, *a, **k):
250 super(StackingResource, self).__init__(*a, **k)
251 self._clients = []
252 self._owner = None
253 if on_grab_callback:
254 self.on_grab = on_grab_callback
255 if on_release_callback:
256 self.on_release = on_release_callback
257
258 - def grab(self, client, priority = None):
272
274 if not client is not None:
275 raise AssertionError
276 old_owner = self._owner
277 self._remove_client(client)
278 new_owner = self._actual_owner()
279 if new_owner != old_owner:
280 self._owner = new_owner
281 self.on_release(old_owner)
282 new_owner is not None and self.on_grab(new_owner)
283 return old_owner == client
284
286 """
287 Releases all objects that are stacked but do not own the
288 resource.
289 """
290 self.release_if(lambda client: client != self.owner)
291
293 """
294 Releases all objects that satisfy a predicate.
295 """
296 for client, _ in list(self._clients):
297 if predicate(client):
298 self.release(client)
299
301 """
302 Releases all stacked clients.
303 """
304 for client, _ in list(self._clients):
305 self.release(client)
306
310
312 idx = index_if(lambda (c, _): c == client, self._clients)
313 if idx != len(self._clients):
314 del self._clients[idx]
315
317 return self._clients[-1][0] if self._clients else None
318
319 @property
321 return map(first, self._clients)
322
323 @property
326
327 @property
329 return len(self._clients)
330
333
335 raise NotImplemented, 'Override or pass callback'
336
338 raise NotImplemented, 'Override or pass callback'
339