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