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 | |
26 | namespace Poco { |
27 | |
28 | |
29 | template <class TArgs, bool hasSender = true, bool senderIsConst = true> |
30 | class FunctionDelegate: public AbstractDelegate<TArgs> |
31 | /// Wraps a freestanding function or static member function |
32 | /// for use as a Delegate. |
33 | { |
34 | public: |
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 | |
89 | protected: |
90 | NotifyFunction _function; |
91 | Mutex _mutex; |
92 | |
93 | private: |
94 | FunctionDelegate(); |
95 | }; |
96 | |
97 | |
98 | template <class TArgs> |
99 | class FunctionDelegate<TArgs, true, false>: public AbstractDelegate<TArgs> |
100 | { |
101 | public: |
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 | |
156 | protected: |
157 | NotifyFunction _function; |
158 | Mutex _mutex; |
159 | |
160 | private: |
161 | FunctionDelegate(); |
162 | }; |
163 | |
164 | |
165 | template <class TArgs, bool senderIsConst> |
166 | class FunctionDelegate<TArgs, false, senderIsConst>: public AbstractDelegate<TArgs> |
167 | { |
168 | public: |
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 | |
223 | protected: |
224 | NotifyFunction _function; |
225 | Mutex _mutex; |
226 | |
227 | private: |
228 | FunctionDelegate(); |
229 | }; |
230 | |
231 | |
232 | template <> |
233 | class FunctionDelegate<void, true, true>: public AbstractDelegate<void> |
234 | /// Wraps a freestanding function or static member function |
235 | /// for use as a Delegate. |
236 | { |
237 | public: |
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 | |
292 | protected: |
293 | NotifyFunction _function; |
294 | Mutex _mutex; |
295 | |
296 | private: |
297 | FunctionDelegate(); |
298 | }; |
299 | |
300 | |
301 | template <> |
302 | class FunctionDelegate<void, true, false>: public AbstractDelegate<void> |
303 | { |
304 | public: |
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 | |
359 | protected: |
360 | NotifyFunction _function; |
361 | Mutex _mutex; |
362 | |
363 | private: |
364 | FunctionDelegate(); |
365 | }; |
366 | |
367 | |
368 | template <bool senderIsConst> |
369 | class FunctionDelegate<void, false, senderIsConst>: public AbstractDelegate<void> |
370 | { |
371 | public: |
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 | |
426 | protected: |
427 | NotifyFunction _function; |
428 | Mutex _mutex; |
429 | |
430 | private: |
431 | FunctionDelegate(); |
432 | }; |
433 | |
434 | |
435 | } // namespace Poco |
436 | |
437 | |
438 | #endif // Foundation_FunctionDelegate_INCLUDED |
439 | |