1 /*
2 Open Tracker License
3
4 Terms and Conditions
5
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
33 */
34 #ifndef __FUNCTION_OBJECT__
35 #define __FUNCTION_OBJECT__
36
37
38 #include <Message.h>
39 #include <Messenger.h>
40 #include <MessageFilter.h>
41
42 #include <Entry.h>
43 #include <Node.h>
44
45
46 // parameter binders serve to store a copy of a struct and
47 // pass it in and out by pointers, allowing struct parameters to share
48 // the same syntax as scalar ones
49
50 // You will mostly want to use the NewFunctionObject... convenience
51 // factories
52 //
53
54 // add more function objects and specialized binders as needed
55
56 namespace BPrivate {
57
58 template<class P>
59 class ParameterBinder {
60 // primitive default binder for scalars
61 public:
ParameterBinder()62 ParameterBinder() {}
ParameterBinder(P p)63 ParameterBinder(P p)
64 : p(p)
65 {}
66
Pass()67 P Pass() const
68 { return p; }
69 private:
70 P p;
71 };
72
73
74 template<>
75 class ParameterBinder<const BEntry*> {
76 public:
ParameterBinder()77 ParameterBinder() {}
ParameterBinder(const BEntry * p)78 ParameterBinder(const BEntry* p)
79 : p(*p)
80 {}
81
82 ParameterBinder &operator=(const BEntry* newp)
83 { p = *newp; return *this; }
84
Pass()85 const BEntry* Pass() const
86 { return &p; }
87 private:
88 BEntry p;
89 };
90
91
92 template<>
93 class ParameterBinder<const entry_ref*> {
94 public:
ParameterBinder()95 ParameterBinder() {}
ParameterBinder(const entry_ref * p)96 ParameterBinder(const entry_ref* p)
97 {
98 if (p)
99 this->p = *p;
100 }
101
102 ParameterBinder &operator=(const entry_ref* newp)
103 { p = *newp; return *this; }
104
Pass()105 const entry_ref* Pass() const
106 { return &p; }
107 private:
108 entry_ref p;
109 };
110
111
112 template<>
113 class ParameterBinder<const node_ref*> {
114 public:
ParameterBinder()115 ParameterBinder() {}
ParameterBinder(const node_ref * p)116 ParameterBinder(const node_ref* p)
117 : p(*p)
118 {}
119
120 ParameterBinder &operator=(const node_ref* newp)
121 { p = *newp; return *this; }
122
Pass()123 const node_ref* Pass() const
124 { return &p; }
125 private:
126 node_ref p;
127 };
128
129
130 template<>
131 class ParameterBinder<const BMessage*> {
132 public:
ParameterBinder()133 ParameterBinder() {}
ParameterBinder(const BMessage * p)134 ParameterBinder(const BMessage* p)
135 : p(p ? new BMessage(*p) : NULL)
136 {}
137
~ParameterBinder()138 ~ParameterBinder()
139 {
140 delete p;
141 }
142
143 ParameterBinder &operator=(const BMessage* newp)
144 {
145 delete p;
146 p = (newp ? new BMessage(*newp) : NULL);
147 return *this;
148 }
149
Pass()150 const BMessage* Pass() const
151 { return p; }
152
153 private:
154 BMessage* p;
155 };
156
157
158 class FunctionObject {
159 public:
160 virtual void operator()() = 0;
~FunctionObject()161 virtual ~FunctionObject() {}
162 };
163
164
165 template<class R>
166 class FunctionObjectWithResult : public FunctionObject {
167 public:
Result()168 const R &Result() const { return result; }
169
170 protected:
171 R result;
172 };
173
174
175 template <class Param1>
176 class SingleParamFunctionObject : public FunctionObject {
177 public:
SingleParamFunctionObject(void (* callThis)(Param1),Param1 p1)178 SingleParamFunctionObject(void (*callThis)(Param1),
179 Param1 p1)
180 : function(callThis),
181 p1(p1)
182 {
183 }
184
operator()185 virtual void operator()() { (function)(p1.Pass()); }
186
187 private:
188 void (*function)(Param1);
189 ParameterBinder<Param1> p1;
190 };
191
192
193 template <class Result, class Param1>
194 class SingleParamFunctionObjectWithResult : public
195 FunctionObjectWithResult<Result> {
196 public:
SingleParamFunctionObjectWithResult(Result (* function)(Param1),Param1 p1)197 SingleParamFunctionObjectWithResult(Result (*function)(Param1), Param1 p1)
198 : function(function),
199 p1(p1)
200 {
201 }
202
operator()203 virtual void operator()()
204 { FunctionObjectWithResult<Result>::result = (function)(p1.Pass()); }
205
206 private:
207 Result (*function)(Param1);
208 ParameterBinder<Param1> p1;
209 };
210
211
212 template <class Param1, class Param2>
213 class TwoParamFunctionObject : public FunctionObject {
214 public:
TwoParamFunctionObject(void (* callThis)(Param1,Param2),Param1 p1,Param2 p2)215 TwoParamFunctionObject(void (*callThis)(Param1, Param2),
216 Param1 p1, Param2 p2)
217 : function(callThis),
218 p1(p1),
219 p2(p2)
220 {
221 }
222
operator()223 virtual void operator()() { (function)(p1.Pass(), p2.Pass()); }
224
225 private:
226 void (*function)(Param1, Param2);
227 ParameterBinder<Param1> p1;
228 ParameterBinder<Param2> p2;
229 };
230
231
232 template <class Param1, class Param2, class Param3>
233 class ThreeParamFunctionObject : public FunctionObject {
234 public:
ThreeParamFunctionObject(void (* callThis)(Param1,Param2,Param3),Param1 p1,Param2 p2,Param3 p3)235 ThreeParamFunctionObject(void (*callThis)(Param1, Param2, Param3),
236 Param1 p1, Param2 p2, Param3 p3)
237 : function(callThis),
238 p1(p1),
239 p2(p2),
240 p3(p3)
241 {
242 }
243
operator()244 virtual void operator()() { (function)(p1.Pass(), p2.Pass(), p3.Pass()); }
245
246 private:
247 void (*function)(Param1, Param2, Param3);
248 ParameterBinder<Param1> p1;
249 ParameterBinder<Param2> p2;
250 ParameterBinder<Param3> p3;
251 };
252
253
254 template <class Result, class Param1, class Param2, class Param3>
255 class ThreeParamFunctionObjectWithResult : public
256 FunctionObjectWithResult<Result> {
257 public:
ThreeParamFunctionObjectWithResult(Result (* callThis)(Param1,Param2,Param3),Param1 p1,Param2 p2,Param3 p3)258 ThreeParamFunctionObjectWithResult(
259 Result (*callThis)(Param1, Param2, Param3),
260 Param1 p1, Param2 p2, Param3 p3)
261 : function(callThis),
262 p1(p1),
263 p2(p2),
264 p3(p3)
265 {
266 }
267
operator()268 virtual void operator()()
269 { FunctionObjectWithResult<Result>::result
270 = (function)(p1.Pass(), p2.Pass(), p3.Pass()); }
271
272 private:
273 Result (*function)(Param1, Param2, Param3);
274 ParameterBinder<Param1> p1;
275 ParameterBinder<Param2> p2;
276 ParameterBinder<Param3> p3;
277 };
278
279
280 template <class Param1, class Param2, class Param3, class Param4>
281 class FourParamFunctionObject : public FunctionObject {
282 public:
FourParamFunctionObject(void (* callThis)(Param1,Param2,Param3,Param4),Param1 p1,Param2 p2,Param3 p3,Param4 p4)283 FourParamFunctionObject(void (*callThis)(Param1, Param2, Param3, Param4),
284 Param1 p1, Param2 p2, Param3 p3, Param4 p4)
285 : function(callThis),
286 p1(p1),
287 p2(p2),
288 p3(p3),
289 p4(p4)
290 {
291 }
292
operator()293 virtual void operator()()
294 { (function)(p1.Pass(), p2.Pass(), p3.Pass(), p4.Pass()); }
295
296 private:
297 void (*function)(Param1, Param2, Param3, Param4);
298 ParameterBinder<Param1> p1;
299 ParameterBinder<Param2> p2;
300 ParameterBinder<Param3> p3;
301 ParameterBinder<Param4> p4;
302 };
303
304
305 template <class Result, class Param1, class Param2, class Param3,
306 class Param4>
307 class FourParamFunctionObjectWithResult : public
308 FunctionObjectWithResult<Result> {
309 public:
FourParamFunctionObjectWithResult(Result (* callThis)(Param1,Param2,Param3,Param4),Param1 p1,Param2 p2,Param3 p3,Param4 p4)310 FourParamFunctionObjectWithResult(
311 Result (*callThis)(Param1, Param2, Param3, Param4),
312 Param1 p1, Param2 p2, Param3 p3, Param4 p4)
313 : function(callThis),
314 p1(p1),
315 p2(p2),
316 p3(p3),
317 p4(p4)
318 {
319 }
320
operator()321 virtual void operator()()
322 { FunctionObjectWithResult<Result>::result
323 = (function)(p1.Pass(), p2.Pass(), p3.Pass(), p4.Pass()); }
324
325 private:
326 Result (*function)(Param1, Param2, Param3, Param4);
327 ParameterBinder<Param1> p1;
328 ParameterBinder<Param2> p2;
329 ParameterBinder<Param3> p3;
330 ParameterBinder<Param4> p4;
331 };
332
333
334 template<class T>
335 class PlainMemberFunctionObject : public FunctionObject {
336 public:
PlainMemberFunctionObject(void (T::* function)(),T * onThis)337 PlainMemberFunctionObject(void (T::*function)(), T* onThis)
338 : function(function),
339 target(onThis)
340 {
341 }
342
operator()343 virtual void operator()()
344 { (target->*function)(); }
345
346 private:
347 void (T::*function)();
348 T* target;
349 };
350
351
352 template<class T>
353 class PlainLockingMemberFunctionObject : public FunctionObject {
354 public:
PlainLockingMemberFunctionObject(void (T::* function)(),T * target)355 PlainLockingMemberFunctionObject(void (T::*function)(), T* target)
356 : function(function),
357 messenger(target)
358 {
359 }
360
operator()361 virtual void operator()()
362 {
363 T* target = dynamic_cast<T*>(messenger.Target(NULL));
364 if (!target || !messenger.LockTarget())
365 return;
366 (target->*function)();
367 target->Looper()->Unlock();
368 }
369
370 private:
371 void (T::*function)();
372 BMessenger messenger;
373 };
374
375
376 template<class T, class R>
377 class PlainMemberFunctionObjectWithResult : public
378 FunctionObjectWithResult<R> {
379 public:
PlainMemberFunctionObjectWithResult(R (T::* function)(),T * onThis)380 PlainMemberFunctionObjectWithResult(R (T::*function)(), T* onThis)
381 : function(function),
382 target(onThis)
383 {
384 }
385
operator()386 virtual void operator()()
387 { FunctionObjectWithResult<R>::result = (target->*function)(); }
388
389
390 private:
391 R (T::*function)();
392 T* target;
393 };
394
395
396 template<class T, class Param1>
397 class SingleParamMemberFunctionObject : public FunctionObject {
398 public:
SingleParamMemberFunctionObject(void (T::* function)(Param1),T * onThis,Param1 p1)399 SingleParamMemberFunctionObject(void (T::*function)(Param1),
400 T* onThis, Param1 p1)
401 : function(function),
402 target(onThis),
403 p1(p1)
404 {
405 }
406
operator()407 virtual void operator()()
408 { (target->*function)(p1.Pass()); }
409
410 private:
411 void (T::*function)(Param1);
412 T* target;
413 ParameterBinder<Param1> p1;
414 };
415
416
417 template<class T, class Param1, class Param2>
418 class TwoParamMemberFunctionObject : public FunctionObject {
419 public:
TwoParamMemberFunctionObject(void (T::* function)(Param1,Param2),T * onThis,Param1 p1,Param2 p2)420 TwoParamMemberFunctionObject(void (T::*function)(Param1, Param2),
421 T* onThis, Param1 p1, Param2 p2)
422 : function(function),
423 target(onThis),
424 p1(p1),
425 p2(p2)
426 {
427 }
428
operator()429 virtual void operator()()
430 { (target->*function)(p1.Pass(), p2.Pass()); }
431
432
433 protected:
434 void (T::*function)(Param1, Param2);
435 T* target;
436 ParameterBinder<Param1> p1;
437 ParameterBinder<Param2> p2;
438 };
439
440
441 template<class T, class R, class Param1>
442 class SingleParamMemberFunctionObjectWithResult : public
443 FunctionObjectWithResult<R> {
444 public:
SingleParamMemberFunctionObjectWithResult(R (T::* function)(Param1),T * onThis,Param1 p1)445 SingleParamMemberFunctionObjectWithResult(R (T::*function)(Param1),
446 T* onThis, Param1 p1)
447 : function(function),
448 target(onThis),
449 p1(p1)
450 {
451 }
452
operator()453 virtual void operator()()
454 { FunctionObjectWithResult<R>::result
455 = (target->*function)(p1.Pass()); }
456
457 protected:
458 R (T::*function)(Param1);
459 T* target;
460 ParameterBinder<Param1> p1;
461 };
462
463
464 template<class T, class R, class Param1, class Param2>
465 class TwoParamMemberFunctionObjectWithResult : public
466 FunctionObjectWithResult<R> {
467 public:
TwoParamMemberFunctionObjectWithResult(R (T::* function)(Param1,Param2),T * onThis,Param1 p1,Param2 p2)468 TwoParamMemberFunctionObjectWithResult(R (T::*function)(Param1, Param2),
469 T* onThis, Param1 p1, Param2 p2)
470 : function(function),
471 target(onThis),
472 p1(p1),
473 p2(p2)
474 {
475 }
476
operator()477 virtual void operator()()
478 { FunctionObjectWithResult<R>::result
479 = (target->*function)(p1.Pass(), p2.Pass()); }
480
481 protected:
482 R (T::*function)(Param1, Param2);
483 T* target;
484 ParameterBinder<Param1> p1;
485 ParameterBinder<Param2> p2;
486 };
487
488
489 // convenience factory functions
490 // NewFunctionObject
491 // NewMemberFunctionObject
492 // NewMemberFunctionObjectWithResult
493 // NewLockingMemberFunctionObject
494 //
495 // ... add the missing ones as needed
496
497 template<class Param1>
498 SingleParamFunctionObject<Param1>*
NewFunctionObject(void (* function)(Param1),Param1 p1)499 NewFunctionObject(void (*function)(Param1), Param1 p1)
500 {
501 return new SingleParamFunctionObject<Param1>(function, p1);
502 }
503
504
505 template<class Param1, class Param2>
506 TwoParamFunctionObject<Param1, Param2>*
NewFunctionObject(void (* function)(Param1,Param2),Param1 p1,Param2 p2)507 NewFunctionObject(void (*function)(Param1, Param2), Param1 p1, Param2 p2)
508 {
509 return new TwoParamFunctionObject<Param1, Param2>(function, p1, p2);
510 }
511
512
513 template<class Param1, class Param2, class Param3>
514 ThreeParamFunctionObject<Param1, Param2, Param3>*
NewFunctionObject(void (* function)(Param1,Param2,Param3),Param1 p1,Param2 p2,Param3 p3)515 NewFunctionObject(void (*function)(Param1, Param2, Param3),
516 Param1 p1, Param2 p2, Param3 p3)
517 {
518 return new ThreeParamFunctionObject<Param1, Param2, Param3>
519 (function, p1, p2, p3);
520 }
521
522
523 template<class T>
524 PlainMemberFunctionObject<T>*
NewMemberFunctionObject(void (T::* function)(),T * onThis)525 NewMemberFunctionObject(void (T::*function)(), T* onThis)
526 {
527 return new PlainMemberFunctionObject<T>(function, onThis);
528 }
529
530
531 template<class T, class Param1>
532 SingleParamMemberFunctionObject<T, Param1>*
NewMemberFunctionObject(void (T::* function)(Param1),T * onThis,Param1 p1)533 NewMemberFunctionObject(void (T::*function)(Param1), T* onThis, Param1 p1)
534 {
535 return new SingleParamMemberFunctionObject<T, Param1>
536 (function, onThis, p1);
537 }
538
539
540 template<class T, class Param1, class Param2>
541 TwoParamMemberFunctionObject<T, Param1, Param2>*
NewMemberFunctionObject(void (T::* function)(Param1,Param2),T * onThis,Param1 p1,Param2 p2)542 NewMemberFunctionObject(void (T::*function)(Param1, Param2), T* onThis,
543 Param1 p1, Param2 p2)
544 {
545 return new TwoParamMemberFunctionObject<T, Param1, Param2>
546 (function, onThis, p1, p2);
547 }
548
549
550 template<class T, class R, class Param1, class Param2>
551 TwoParamMemberFunctionObjectWithResult<T, R, Param1, Param2>*
NewMemberFunctionObjectWithResult(R (T::* function)(Param1,Param2),T * onThis,Param1 p1,Param2 p2)552 NewMemberFunctionObjectWithResult(R (T::*function)(Param1, Param2),
553 T* onThis, Param1 p1, Param2 p2)
554 {
555 return new TwoParamMemberFunctionObjectWithResult<T, R, Param1, Param2>
556 (function, onThis, p1, p2);
557 }
558
559
560 template<class HandlerOrSubclass>
561 PlainLockingMemberFunctionObject<HandlerOrSubclass>*
NewLockingMemberFunctionObject(void (HandlerOrSubclass::* function)(),HandlerOrSubclass * onThis)562 NewLockingMemberFunctionObject(void (HandlerOrSubclass::*function)(),
563 HandlerOrSubclass* onThis)
564 {
565 return new PlainLockingMemberFunctionObject<HandlerOrSubclass>
566 (function, onThis);
567 }
568
569 } // namespace BPrivate
570
571 using namespace BPrivate;
572
573 #endif // __FUNCTION_OBJECT__
574