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
28namespace Poco {
29
30
31template <class TObj, class TArgs, bool useSender = true>
32class PriorityDelegate: public AbstractPriorityDelegate<TArgs>
33{
34public:
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
95protected:
96 TObj* _receiverObject;
97 NotifyMethod _receiverMethod;
98 Mutex _mutex;
99
100private:
101 PriorityDelegate();
102};
103
104
105template <class TObj, class TArgs>
106class PriorityDelegate<TObj, TArgs, false>: public AbstractPriorityDelegate<TArgs>
107{
108public:
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
169protected:
170 TObj* _receiverObject;
171 NotifyMethod _receiverMethod;
172 Mutex _mutex;
173
174private:
175 PriorityDelegate();
176};
177
178
179template <class TObj>
180class PriorityDelegate<TObj, void, true>: public AbstractPriorityDelegate<void>
181{
182public:
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
243protected:
244 TObj* _receiverObject;
245 NotifyMethod _receiverMethod;
246 Mutex _mutex;
247
248private:
249 PriorityDelegate();
250};
251
252
253template <class TObj>
254class PriorityDelegate<TObj, void, false>: public AbstractPriorityDelegate<void>
255{
256public:
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
317protected:
318 TObj* _receiverObject;
319 NotifyMethod _receiverMethod;
320 Mutex _mutex;
321
322private:
323 PriorityDelegate();
324};
325
326
327template <class TObj, class TArgs>
328static 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
334template <class TObj, class TArgs>
335static 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
341template <class TObj, class TArgs>
342static 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
348template <class TObj, class TArgs>
349static 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
355template <class TArgs>
356static 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
362template <class TArgs>
363static 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
369template <class TArgs>
370static 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
376template <class TArgs>
377static FunctionPriorityDelegate<TArgs, true, true> priorityDelegate(void (*NotifyMethod)(const void*, TArgs&), int prio)
378{
379 return FunctionPriorityDelegate<TArgs, true, true>(NotifyMethod, prio);
380}
381
382
383template <class TArgs>
384static FunctionPriorityDelegate<TArgs, true, false> priorityDelegate(void (*NotifyMethod)(void*, TArgs&), int prio)
385{
386 return FunctionPriorityDelegate<TArgs, true, false>(NotifyMethod, prio);
387}
388
389
390template <class TArgs>
391static FunctionPriorityDelegate<TArgs, false> priorityDelegate(void (*NotifyMethod)(TArgs&), int prio)
392{
393 return FunctionPriorityDelegate<TArgs, false>(NotifyMethod, prio);
394}
395
396
397template <class TObj>
398static 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
404template <class TObj>
405static 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
411template <class TObj>
412static 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
418template <class TObj>
419static 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
425inline 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
431inline 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
437inline PriorityExpire<void> priorityDelegate(void (*NotifyMethod)(), int prio, Timestamp::TimeDiff expireMilliSec)
438{
439 return PriorityExpire<void>(FunctionPriorityDelegate<void, false>(NotifyMethod, prio), expireMilliSec);
440}
441
442
443inline FunctionPriorityDelegate<void, true, true> priorityDelegate(void (*NotifyMethod)(const void*), int prio)
444{
445 return FunctionPriorityDelegate<void, true, true>(NotifyMethod, prio);
446}
447
448
449inline FunctionPriorityDelegate<void, true, false> priorityDelegate(void (*NotifyMethod)(void*), int prio)
450{
451 return FunctionPriorityDelegate<void, true, false>(NotifyMethod, prio);
452}
453
454
455inline 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