1 | // |
2 | // PriorityDelegate.h |
3 | // |
4 | // Library: Foundation |
5 | // Package: Events |
6 | // Module: PriorityDelegate |
7 | // |
8 | // Implementation of the PriorityDelegate template. |
9 | // |
10 | // Copyright (c) 2006-2011, Applied Informatics Software Engineering GmbH. |
11 | // and Contributors. |
12 | // |
13 | // SPDX-License-Identifier: BSL-1.0 |
14 | // |
15 | |
16 | |
17 | #ifndef Foundation_PriorityDelegate_INCLUDED |
18 | #define Foundation_PriorityDelegate_INCLUDED |
19 | |
20 | |
21 | #include "Poco/Foundation.h" |
22 | #include "Poco/AbstractPriorityDelegate.h" |
23 | #include "Poco/PriorityExpire.h" |
24 | #include "Poco/FunctionPriorityDelegate.h" |
25 | #include "Poco/Mutex.h" |
26 | |
27 | |
28 | namespace Poco { |
29 | |
30 | |
31 | template <class TObj, class TArgs, bool useSender = true> |
32 | class PriorityDelegate: public AbstractPriorityDelegate<TArgs> |
33 | { |
34 | public: |
35 | typedef void (TObj::*NotifyMethod)(const void*, TArgs&); |
36 | |
37 | PriorityDelegate(TObj* obj, NotifyMethod method, int prio): |
38 | AbstractPriorityDelegate<TArgs>(prio), |
39 | _receiverObject(obj), |
40 | _receiverMethod(method) |
41 | { |
42 | } |
43 | |
44 | PriorityDelegate(const PriorityDelegate& delegate): |
45 | AbstractPriorityDelegate<TArgs>(delegate), |
46 | _receiverObject(delegate._receiverObject), |
47 | _receiverMethod(delegate._receiverMethod) |
48 | { |
49 | } |
50 | |
51 | PriorityDelegate& operator = (const PriorityDelegate& delegate) |
52 | { |
53 | if (&delegate != this) |
54 | { |
55 | this->_pTarget = delegate._pTarget; |
56 | this->_receiverObject = delegate._receiverObject; |
57 | this->_receiverMethod = delegate._receiverMethod; |
58 | this->_priority = delegate._priority; |
59 | } |
60 | return *this; |
61 | } |
62 | |
63 | ~PriorityDelegate() |
64 | { |
65 | } |
66 | |
67 | bool notify(const void* sender, TArgs& arguments) |
68 | { |
69 | Mutex::ScopedLock lock(_mutex); |
70 | if (_receiverObject) |
71 | { |
72 | (_receiverObject->*_receiverMethod)(sender, arguments); |
73 | return true; |
74 | } |
75 | else return false; |
76 | } |
77 | |
78 | bool equals(const AbstractDelegate<TArgs>& other) const |
79 | { |
80 | const PriorityDelegate* pOtherDelegate = dynamic_cast<const PriorityDelegate*>(other.unwrap()); |
81 | return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod; |
82 | } |
83 | |
84 | AbstractDelegate<TArgs>* clone() const |
85 | { |
86 | return new PriorityDelegate(*this); |
87 | } |
88 | |
89 | void disable() |
90 | { |
91 | Mutex::ScopedLock lock(_mutex); |
92 | _receiverObject = 0; |
93 | } |
94 | |
95 | protected: |
96 | TObj* _receiverObject; |
97 | NotifyMethod _receiverMethod; |
98 | Mutex _mutex; |
99 | |
100 | private: |
101 | PriorityDelegate(); |
102 | }; |
103 | |
104 | |
105 | template <class TObj, class TArgs> |
106 | class PriorityDelegate<TObj, TArgs, false>: public AbstractPriorityDelegate<TArgs> |
107 | { |
108 | public: |
109 | typedef void (TObj::*NotifyMethod)(TArgs&); |
110 | |
111 | PriorityDelegate(TObj* obj, NotifyMethod method, int prio): |
112 | AbstractPriorityDelegate<TArgs>(prio), |
113 | _receiverObject(obj), |
114 | _receiverMethod(method) |
115 | { |
116 | } |
117 | |
118 | PriorityDelegate(const PriorityDelegate& delegate): |
119 | AbstractPriorityDelegate<TArgs>(delegate), |
120 | _receiverObject(delegate._receiverObject), |
121 | _receiverMethod(delegate._receiverMethod) |
122 | { |
123 | } |
124 | |
125 | PriorityDelegate& operator = (const PriorityDelegate& delegate) |
126 | { |
127 | if (&delegate != this) |
128 | { |
129 | this->_pTarget = delegate._pTarget; |
130 | this->_receiverObject = delegate._receiverObject; |
131 | this->_receiverMethod = delegate._receiverMethod; |
132 | this->_priority = delegate._priority; |
133 | } |
134 | return *this; |
135 | } |
136 | |
137 | ~PriorityDelegate() |
138 | { |
139 | } |
140 | |
141 | bool notify(const void* sender, TArgs& arguments) |
142 | { |
143 | Mutex::ScopedLock lock(_mutex); |
144 | if (_receiverObject) |
145 | { |
146 | (_receiverObject->*_receiverMethod)(arguments); |
147 | return true; |
148 | } |
149 | return false; |
150 | } |
151 | |
152 | bool equals(const AbstractDelegate<TArgs>& other) const |
153 | { |
154 | const PriorityDelegate* pOtherDelegate = dynamic_cast<const PriorityDelegate*>(other.unwrap()); |
155 | return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod; |
156 | } |
157 | |
158 | AbstractDelegate<TArgs>* clone() const |
159 | { |
160 | return new PriorityDelegate(*this); |
161 | } |
162 | |
163 | void disable() |
164 | { |
165 | Mutex::ScopedLock lock(_mutex); |
166 | _receiverObject = 0; |
167 | } |
168 | |
169 | protected: |
170 | TObj* _receiverObject; |
171 | NotifyMethod _receiverMethod; |
172 | Mutex _mutex; |
173 | |
174 | private: |
175 | PriorityDelegate(); |
176 | }; |
177 | |
178 | |
179 | template <class TObj> |
180 | class PriorityDelegate<TObj, void, true>: public AbstractPriorityDelegate<void> |
181 | { |
182 | public: |
183 | typedef void (TObj::*NotifyMethod)(const void*); |
184 | |
185 | PriorityDelegate(TObj* obj, NotifyMethod method, int prio): |
186 | AbstractPriorityDelegate<void>(prio), |
187 | _receiverObject(obj), |
188 | _receiverMethod(method) |
189 | { |
190 | } |
191 | |
192 | PriorityDelegate(const PriorityDelegate& delegate): |
193 | AbstractPriorityDelegate<void>(delegate), |
194 | _receiverObject(delegate._receiverObject), |
195 | _receiverMethod(delegate._receiverMethod) |
196 | { |
197 | } |
198 | |
199 | PriorityDelegate& operator = (const PriorityDelegate& delegate) |
200 | { |
201 | if (&delegate != this) |
202 | { |
203 | this->_pTarget = delegate._pTarget; |
204 | this->_receiverObject = delegate._receiverObject; |
205 | this->_receiverMethod = delegate._receiverMethod; |
206 | this->_priority = delegate._priority; |
207 | } |
208 | return *this; |
209 | } |
210 | |
211 | ~PriorityDelegate() |
212 | { |
213 | } |
214 | |
215 | bool notify(const void* sender) |
216 | { |
217 | Mutex::ScopedLock lock(_mutex); |
218 | if (_receiverObject) |
219 | { |
220 | (_receiverObject->*_receiverMethod)(sender); |
221 | return true; |
222 | } |
223 | else return false; |
224 | } |
225 | |
226 | bool equals(const AbstractDelegate<void>& other) const |
227 | { |
228 | const PriorityDelegate* pOtherDelegate = dynamic_cast<const PriorityDelegate*>(other.unwrap()); |
229 | return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod; |
230 | } |
231 | |
232 | AbstractDelegate<void>* clone() const |
233 | { |
234 | return new PriorityDelegate(*this); |
235 | } |
236 | |
237 | void disable() |
238 | { |
239 | Mutex::ScopedLock lock(_mutex); |
240 | _receiverObject = 0; |
241 | } |
242 | |
243 | protected: |
244 | TObj* _receiverObject; |
245 | NotifyMethod _receiverMethod; |
246 | Mutex _mutex; |
247 | |
248 | private: |
249 | PriorityDelegate(); |
250 | }; |
251 | |
252 | |
253 | template <class TObj> |
254 | class PriorityDelegate<TObj, void, false>: public AbstractPriorityDelegate<void> |
255 | { |
256 | public: |
257 | typedef void (TObj::*NotifyMethod)(); |
258 | |
259 | PriorityDelegate(TObj* obj, NotifyMethod method, int prio): |
260 | AbstractPriorityDelegate<void>(prio), |
261 | _receiverObject(obj), |
262 | _receiverMethod(method) |
263 | { |
264 | } |
265 | |
266 | PriorityDelegate(const PriorityDelegate& delegate): |
267 | AbstractPriorityDelegate<void>(delegate), |
268 | _receiverObject(delegate._receiverObject), |
269 | _receiverMethod(delegate._receiverMethod) |
270 | { |
271 | } |
272 | |
273 | PriorityDelegate& operator = (const PriorityDelegate& delegate) |
274 | { |
275 | if (&delegate != this) |
276 | { |
277 | this->_pTarget = delegate._pTarget; |
278 | this->_receiverObject = delegate._receiverObject; |
279 | this->_receiverMethod = delegate._receiverMethod; |
280 | this->_priority = delegate._priority; |
281 | } |
282 | return *this; |
283 | } |
284 | |
285 | ~PriorityDelegate() |
286 | { |
287 | } |
288 | |
289 | bool notify(const void* sender) |
290 | { |
291 | Mutex::ScopedLock lock(_mutex); |
292 | if (_receiverObject) |
293 | { |
294 | (_receiverObject->*_receiverMethod)(); |
295 | return true; |
296 | } |
297 | return false; |
298 | } |
299 | |
300 | bool equals(const AbstractDelegate<void>& other) const |
301 | { |
302 | const PriorityDelegate* pOtherDelegate = dynamic_cast<const PriorityDelegate*>(other.unwrap()); |
303 | return pOtherDelegate && this->priority() == pOtherDelegate->priority() && _receiverObject == pOtherDelegate->_receiverObject && _receiverMethod == pOtherDelegate->_receiverMethod; |
304 | } |
305 | |
306 | AbstractDelegate<void>* clone() const |
307 | { |
308 | return new PriorityDelegate(*this); |
309 | } |
310 | |
311 | void disable() |
312 | { |
313 | Mutex::ScopedLock lock(_mutex); |
314 | _receiverObject = 0; |
315 | } |
316 | |
317 | protected: |
318 | TObj* _receiverObject; |
319 | NotifyMethod _receiverMethod; |
320 | Mutex _mutex; |
321 | |
322 | private: |
323 | PriorityDelegate(); |
324 | }; |
325 | |
326 | |
327 | template <class TObj, class TArgs> |
328 | static PriorityDelegate<TObj, TArgs, true> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), int prio) |
329 | { |
330 | return PriorityDelegate<TObj, TArgs, true>(pObj, NotifyMethod, prio); |
331 | } |
332 | |
333 | |
334 | template <class TObj, class TArgs> |
335 | static PriorityDelegate<TObj, TArgs, false> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&), int prio) |
336 | { |
337 | return PriorityDelegate<TObj, TArgs, false>(pObj, NotifyMethod, prio); |
338 | } |
339 | |
340 | |
341 | template <class TObj, class TArgs> |
342 | static PriorityExpire<TArgs> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*, TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) |
343 | { |
344 | return PriorityExpire<TArgs>(PriorityDelegate<TObj, TArgs, true>(pObj, NotifyMethod, prio), expireMilliSec); |
345 | } |
346 | |
347 | |
348 | template <class TObj, class TArgs> |
349 | static PriorityExpire<TArgs> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) |
350 | { |
351 | return PriorityExpire<TArgs>(PriorityDelegate<TObj, TArgs, false>(pObj, NotifyMethod, prio), expireMilliSec); |
352 | } |
353 | |
354 | |
355 | template <class TArgs> |
356 | static PriorityExpire<TArgs> priorityDelegate(void (*NotifyMethod)(const void*, TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) |
357 | { |
358 | return PriorityExpire<TArgs>(FunctionPriorityDelegate<TArgs, true, true>(NotifyMethod, prio), expireMilliSec); |
359 | } |
360 | |
361 | |
362 | template <class TArgs> |
363 | static PriorityExpire<TArgs> priorityDelegate(void (*NotifyMethod)(void*, TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) |
364 | { |
365 | return PriorityExpire<TArgs>(FunctionPriorityDelegate<TArgs, true, false>(NotifyMethod, prio), expireMilliSec); |
366 | } |
367 | |
368 | |
369 | template <class TArgs> |
370 | static PriorityExpire<TArgs> priorityDelegate(void (*NotifyMethod)(TArgs&), int prio, Timestamp::TimeDiff expireMilliSec) |
371 | { |
372 | return PriorityExpire<TArgs>(FunctionPriorityDelegate<TArgs, false>(NotifyMethod, prio), expireMilliSec); |
373 | } |
374 | |
375 | |
376 | template <class TArgs> |
377 | static FunctionPriorityDelegate<TArgs, true, true> priorityDelegate(void (*NotifyMethod)(const void*, TArgs&), int prio) |
378 | { |
379 | return FunctionPriorityDelegate<TArgs, true, true>(NotifyMethod, prio); |
380 | } |
381 | |
382 | |
383 | template <class TArgs> |
384 | static FunctionPriorityDelegate<TArgs, true, false> priorityDelegate(void (*NotifyMethod)(void*, TArgs&), int prio) |
385 | { |
386 | return FunctionPriorityDelegate<TArgs, true, false>(NotifyMethod, prio); |
387 | } |
388 | |
389 | |
390 | template <class TArgs> |
391 | static FunctionPriorityDelegate<TArgs, false> priorityDelegate(void (*NotifyMethod)(TArgs&), int prio) |
392 | { |
393 | return FunctionPriorityDelegate<TArgs, false>(NotifyMethod, prio); |
394 | } |
395 | |
396 | |
397 | template <class TObj> |
398 | static PriorityDelegate<TObj, void, true> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*), int prio) |
399 | { |
400 | return PriorityDelegate<TObj, void, true>(pObj, NotifyMethod, prio); |
401 | } |
402 | |
403 | |
404 | template <class TObj> |
405 | static PriorityDelegate<TObj, void, false> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(), int prio) |
406 | { |
407 | return PriorityDelegate<TObj, void, false>(pObj, NotifyMethod, prio); |
408 | } |
409 | |
410 | |
411 | template <class TObj> |
412 | static PriorityExpire<void> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(const void*), int prio, Timestamp::TimeDiff expireMilliSec) |
413 | { |
414 | return PriorityExpire<void>(PriorityDelegate<TObj, void, true>(pObj, NotifyMethod, prio), expireMilliSec); |
415 | } |
416 | |
417 | |
418 | template <class TObj> |
419 | static PriorityExpire<void> priorityDelegate(TObj* pObj, void (TObj::*NotifyMethod)(), int prio, Timestamp::TimeDiff expireMilliSec) |
420 | { |
421 | return PriorityExpire<void>(PriorityDelegate<TObj, void, false>(pObj, NotifyMethod, prio), expireMilliSec); |
422 | } |
423 | |
424 | |
425 | inline PriorityExpire<void> priorityDelegate(void (*NotifyMethod)(const void*), int prio, Timestamp::TimeDiff expireMilliSec) |
426 | { |
427 | return PriorityExpire<void>(FunctionPriorityDelegate<void, true, true>(NotifyMethod, prio), expireMilliSec); |
428 | } |
429 | |
430 | |
431 | inline PriorityExpire<void> priorityDelegate(void (*NotifyMethod)(void*), int prio, Timestamp::TimeDiff expireMilliSec) |
432 | { |
433 | return PriorityExpire<void>(FunctionPriorityDelegate<void, true, false>(NotifyMethod, prio), expireMilliSec); |
434 | } |
435 | |
436 | |
437 | inline PriorityExpire<void> priorityDelegate(void (*NotifyMethod)(), int prio, Timestamp::TimeDiff expireMilliSec) |
438 | { |
439 | return PriorityExpire<void>(FunctionPriorityDelegate<void, false>(NotifyMethod, prio), expireMilliSec); |
440 | } |
441 | |
442 | |
443 | inline FunctionPriorityDelegate<void, true, true> priorityDelegate(void (*NotifyMethod)(const void*), int prio) |
444 | { |
445 | return FunctionPriorityDelegate<void, true, true>(NotifyMethod, prio); |
446 | } |
447 | |
448 | |
449 | inline FunctionPriorityDelegate<void, true, false> priorityDelegate(void (*NotifyMethod)(void*), int prio) |
450 | { |
451 | return FunctionPriorityDelegate<void, true, false>(NotifyMethod, prio); |
452 | } |
453 | |
454 | |
455 | inline FunctionPriorityDelegate<void, false> priorityDelegate(void (*NotifyMethod)(), int prio) |
456 | { |
457 | return FunctionPriorityDelegate<void, false>(NotifyMethod, prio); |
458 | } |
459 | |
460 | |
461 | } // namespace Poco |
462 | |
463 | |
464 | #endif // Foundation_PriorityDelegate_INCLUDED |
465 | |