6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
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:
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.
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.
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.
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.
34 #ifndef __FUNCTION_OBJECT__
35 #define __FUNCTION_OBJECT__
39 #include <Messenger.h>
40 #include <MessageFilter.h>
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
50 // You will mostly want to use the NewFunctionObject... convenience
54 // add more function objects and specialized binders as needed
59 class ParameterBinder
{
60 // primitive default binder for scalars
75 class ParameterBinder
<const BEntry
*> {
78 ParameterBinder(const BEntry
* p
)
82 ParameterBinder
&operator=(const BEntry
* newp
)
83 { p
= *newp
; return *this; }
85 const BEntry
* Pass() const
93 class ParameterBinder
<const entry_ref
*> {
96 ParameterBinder(const entry_ref
* p
)
102 ParameterBinder
&operator=(const entry_ref
* newp
)
103 { p
= *newp
; return *this; }
105 const entry_ref
* Pass() const
113 class ParameterBinder
<const node_ref
*> {
116 ParameterBinder(const node_ref
* p
)
120 ParameterBinder
&operator=(const node_ref
* newp
)
121 { p
= *newp
; return *this; }
123 const node_ref
* Pass() const
131 class ParameterBinder
<const BMessage
*> {
134 ParameterBinder(const BMessage
* p
)
135 : p(p
? new BMessage(*p
) : NULL
)
143 ParameterBinder
&operator=(const BMessage
* newp
)
146 p
= (newp
? new BMessage(*newp
) : NULL
);
150 const BMessage
* Pass() const
158 class FunctionObject
{
160 virtual void operator()() = 0;
161 virtual ~FunctionObject() {}
166 class FunctionObjectWithResult
: public FunctionObject
{
168 const R
&Result() const { return result
; }
175 template <class Param1
>
176 class SingleParamFunctionObject
: public FunctionObject
{
178 SingleParamFunctionObject(void (*callThis
)(Param1
),
180 : function(callThis
),
185 virtual void operator()() { (function
)(p1
.Pass()); }
188 void (*function
)(Param1
);
189 ParameterBinder
<Param1
> p1
;
193 template <class Result
, class Param1
>
194 class SingleParamFunctionObjectWithResult
: public
195 FunctionObjectWithResult
<Result
> {
197 SingleParamFunctionObjectWithResult(Result (*function
)(Param1
), Param1 p1
)
198 : function(function
),
203 virtual void operator()()
204 { FunctionObjectWithResult
<Result
>::result
= (function
)(p1
.Pass()); }
207 Result (*function
)(Param1
);
208 ParameterBinder
<Param1
> p1
;
212 template <class Param1
, class Param2
>
213 class TwoParamFunctionObject
: public FunctionObject
{
215 TwoParamFunctionObject(void (*callThis
)(Param1
, Param2
),
216 Param1 p1
, Param2 p2
)
217 : function(callThis
),
223 virtual void operator()() { (function
)(p1
.Pass(), p2
.Pass()); }
226 void (*function
)(Param1
, Param2
);
227 ParameterBinder
<Param1
> p1
;
228 ParameterBinder
<Param2
> p2
;
232 template <class Param1
, class Param2
, class Param3
>
233 class ThreeParamFunctionObject
: public FunctionObject
{
235 ThreeParamFunctionObject(void (*callThis
)(Param1
, Param2
, Param3
),
236 Param1 p1
, Param2 p2
, Param3 p3
)
237 : function(callThis
),
244 virtual void operator()() { (function
)(p1
.Pass(), p2
.Pass(), p3
.Pass()); }
247 void (*function
)(Param1
, Param2
, Param3
);
248 ParameterBinder
<Param1
> p1
;
249 ParameterBinder
<Param2
> p2
;
250 ParameterBinder
<Param3
> p3
;
254 template <class Result
, class Param1
, class Param2
, class Param3
>
255 class ThreeParamFunctionObjectWithResult
: public
256 FunctionObjectWithResult
<Result
> {
258 ThreeParamFunctionObjectWithResult(
259 Result (*callThis
)(Param1
, Param2
, Param3
),
260 Param1 p1
, Param2 p2
, Param3 p3
)
261 : function(callThis
),
268 virtual void operator()()
269 { FunctionObjectWithResult
<Result
>::result
270 = (function
)(p1
.Pass(), p2
.Pass(), p3
.Pass()); }
273 Result (*function
)(Param1
, Param2
, Param3
);
274 ParameterBinder
<Param1
> p1
;
275 ParameterBinder
<Param2
> p2
;
276 ParameterBinder
<Param3
> p3
;
280 template <class Param1
, class Param2
, class Param3
, class Param4
>
281 class FourParamFunctionObject
: public FunctionObject
{
283 FourParamFunctionObject(void (*callThis
)(Param1
, Param2
, Param3
, Param4
),
284 Param1 p1
, Param2 p2
, Param3 p3
, Param4 p4
)
285 : function(callThis
),
293 virtual void operator()()
294 { (function
)(p1
.Pass(), p2
.Pass(), p3
.Pass(), p4
.Pass()); }
297 void (*function
)(Param1
, Param2
, Param3
, Param4
);
298 ParameterBinder
<Param1
> p1
;
299 ParameterBinder
<Param2
> p2
;
300 ParameterBinder
<Param3
> p3
;
301 ParameterBinder
<Param4
> p4
;
305 template <class Result
, class Param1
, class Param2
, class Param3
,
307 class FourParamFunctionObjectWithResult
: public
308 FunctionObjectWithResult
<Result
> {
310 FourParamFunctionObjectWithResult(
311 Result (*callThis
)(Param1
, Param2
, Param3
, Param4
),
312 Param1 p1
, Param2 p2
, Param3 p3
, Param4 p4
)
313 : function(callThis
),
321 virtual void operator()()
322 { FunctionObjectWithResult
<Result
>::result
323 = (function
)(p1
.Pass(), p2
.Pass(), p3
.Pass(), p4
.Pass()); }
326 Result (*function
)(Param1
, Param2
, Param3
, Param4
);
327 ParameterBinder
<Param1
> p1
;
328 ParameterBinder
<Param2
> p2
;
329 ParameterBinder
<Param3
> p3
;
330 ParameterBinder
<Param4
> p4
;
335 class PlainMemberFunctionObject
: public FunctionObject
{
337 PlainMemberFunctionObject(void (T::*function
)(), T
* onThis
)
338 : function(function
),
343 virtual void operator()()
344 { (target
->*function
)(); }
347 void (T::*function
)();
353 class PlainLockingMemberFunctionObject
: public FunctionObject
{
355 PlainLockingMemberFunctionObject(void (T::*function
)(), T
* target
)
356 : function(function
),
361 virtual void operator()()
363 T
* target
= dynamic_cast<T
*>(messenger
.Target(NULL
));
364 if (!target
|| !messenger
.LockTarget())
366 (target
->*function
)();
367 target
->Looper()->Unlock();
371 void (T::*function
)();
372 BMessenger messenger
;
376 template<class T
, class R
>
377 class PlainMemberFunctionObjectWithResult
: public
378 FunctionObjectWithResult
<R
> {
380 PlainMemberFunctionObjectWithResult(R (T::*function
)(), T
* onThis
)
381 : function(function
),
386 virtual void operator()()
387 { FunctionObjectWithResult
<R
>::result
= (target
->*function
)(); }
396 template<class T
, class Param1
>
397 class SingleParamMemberFunctionObject
: public FunctionObject
{
399 SingleParamMemberFunctionObject(void (T::*function
)(Param1
),
400 T
* onThis
, Param1 p1
)
401 : function(function
),
407 virtual void operator()()
408 { (target
->*function
)(p1
.Pass()); }
411 void (T::*function
)(Param1
);
413 ParameterBinder
<Param1
> p1
;
417 template<class T
, class Param1
, class Param2
>
418 class TwoParamMemberFunctionObject
: public FunctionObject
{
420 TwoParamMemberFunctionObject(void (T::*function
)(Param1
, Param2
),
421 T
* onThis
, Param1 p1
, Param2 p2
)
422 : function(function
),
429 virtual void operator()()
430 { (target
->*function
)(p1
.Pass(), p2
.Pass()); }
434 void (T::*function
)(Param1
, Param2
);
436 ParameterBinder
<Param1
> p1
;
437 ParameterBinder
<Param2
> p2
;
441 template<class T
, class R
, class Param1
>
442 class SingleParamMemberFunctionObjectWithResult
: public
443 FunctionObjectWithResult
<R
> {
445 SingleParamMemberFunctionObjectWithResult(R (T::*function
)(Param1
),
446 T
* onThis
, Param1 p1
)
447 : function(function
),
453 virtual void operator()()
454 { FunctionObjectWithResult
<R
>::result
455 = (target
->*function
)(p1
.Pass()); }
458 R (T::*function
)(Param1
);
460 ParameterBinder
<Param1
> p1
;
464 template<class T
, class R
, class Param1
, class Param2
>
465 class TwoParamMemberFunctionObjectWithResult
: public
466 FunctionObjectWithResult
<R
> {
468 TwoParamMemberFunctionObjectWithResult(R (T::*function
)(Param1
, Param2
),
469 T
* onThis
, Param1 p1
, Param2 p2
)
470 : function(function
),
477 virtual void operator()()
478 { FunctionObjectWithResult
<R
>::result
479 = (target
->*function
)(p1
.Pass(), p2
.Pass()); }
482 R (T::*function
)(Param1
, Param2
);
484 ParameterBinder
<Param1
> p1
;
485 ParameterBinder
<Param2
> p2
;
489 // convenience factory functions
491 // NewMemberFunctionObject
492 // NewMemberFunctionObjectWithResult
493 // NewLockingMemberFunctionObject
495 // ... add the missing ones as needed
497 template<class Param1
>
498 SingleParamFunctionObject
<Param1
>*
499 NewFunctionObject(void (*function
)(Param1
), Param1 p1
)
501 return new SingleParamFunctionObject
<Param1
>(function
, p1
);
505 template<class Param1
, class Param2
>
506 TwoParamFunctionObject
<Param1
, Param2
>*
507 NewFunctionObject(void (*function
)(Param1
, Param2
), Param1 p1
, Param2 p2
)
509 return new TwoParamFunctionObject
<Param1
, Param2
>(function
, p1
, p2
);
513 template<class Param1
, class Param2
, class Param3
>
514 ThreeParamFunctionObject
<Param1
, Param2
, Param3
>*
515 NewFunctionObject(void (*function
)(Param1
, Param2
, Param3
),
516 Param1 p1
, Param2 p2
, Param3 p3
)
518 return new ThreeParamFunctionObject
<Param1
, Param2
, Param3
>
519 (function
, p1
, p2
, p3
);
524 PlainMemberFunctionObject
<T
>*
525 NewMemberFunctionObject(void (T::*function
)(), T
* onThis
)
527 return new PlainMemberFunctionObject
<T
>(function
, onThis
);
531 template<class T
, class Param1
>
532 SingleParamMemberFunctionObject
<T
, Param1
>*
533 NewMemberFunctionObject(void (T::*function
)(Param1
), T
* onThis
, Param1 p1
)
535 return new SingleParamMemberFunctionObject
<T
, Param1
>
536 (function
, onThis
, p1
);
540 template<class T
, class Param1
, class Param2
>
541 TwoParamMemberFunctionObject
<T
, Param1
, Param2
>*
542 NewMemberFunctionObject(void (T::*function
)(Param1
, Param2
), T
* onThis
,
543 Param1 p1
, Param2 p2
)
545 return new TwoParamMemberFunctionObject
<T
, Param1
, Param2
>
546 (function
, onThis
, p1
, p2
);
550 template<class T
, class R
, class Param1
, class Param2
>
551 TwoParamMemberFunctionObjectWithResult
<T
, R
, Param1
, Param2
>*
552 NewMemberFunctionObjectWithResult(R (T::*function
)(Param1
, Param2
),
553 T
* onThis
, Param1 p1
, Param2 p2
)
555 return new TwoParamMemberFunctionObjectWithResult
<T
, R
, Param1
, Param2
>
556 (function
, onThis
, p1
, p2
);
560 template<class HandlerOrSubclass
>
561 PlainLockingMemberFunctionObject
<HandlerOrSubclass
>*
562 NewLockingMemberFunctionObject(void (HandlerOrSubclass::*function
)(),
563 HandlerOrSubclass
* onThis
)
565 return new PlainLockingMemberFunctionObject
<HandlerOrSubclass
>
569 } // namespace BPrivate
571 using namespace BPrivate
;
573 #endif // __FUNCTION_OBJECT__