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