xref: /haiku/headers/private/shared/FunctionObject.h (revision a3e794ae459fec76826407f8ba8c94cd3535f128)
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:
62 	ParameterBinder() {}
63 	ParameterBinder(P p)
64 		:	p(p)
65 		{}
66 
67 	P Pass() const
68 		{ return p; }
69 private:
70 	P p;
71 };
72 
73 
74 template<>
75 class ParameterBinder<const BEntry*> {
76 public:
77 	ParameterBinder() {}
78 	ParameterBinder(const BEntry* p)
79 		:	p(*p)
80 		{}
81 
82 	ParameterBinder &operator=(const BEntry* newp)
83 		{ p = *newp; return *this; }
84 
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:
95 	ParameterBinder() {}
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 
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:
115 	ParameterBinder() {}
116 	ParameterBinder(const node_ref* p)
117 		:	p(*p)
118 		{}
119 
120 	ParameterBinder &operator=(const node_ref* newp)
121 		{ p = *newp; return *this; }
122 
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:
133 	ParameterBinder() {}
134 	ParameterBinder(const BMessage* p)
135 		:	p(p ? new BMessage(*p) : NULL)
136 		{}
137 
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 
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;
161 	virtual ~FunctionObject() {}
162 };
163 
164 
165 template<class R>
166 class FunctionObjectWithResult : public FunctionObject {
167 public:
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:
178 	SingleParamFunctionObject(void (*callThis)(Param1),
179 		Param1 p1)
180 		:	function(callThis),
181 			p1(p1)
182 		{
183 		}
184 
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:
197 	SingleParamFunctionObjectWithResult(Result (*function)(Param1), Param1 p1)
198 		:	function(function),
199 			p1(p1)
200 		{
201 		}
202 
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:
215 	TwoParamFunctionObject(void (*callThis)(Param1, Param2),
216 		Param1 p1, Param2 p2)
217 		:	function(callThis),
218 			p1(p1),
219 			p2(p2)
220 		{
221 		}
222 
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:
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 
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:
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 
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:
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 
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:
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 
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:
337 	PlainMemberFunctionObject(void (T::*function)(), T* onThis)
338 		:	function(function),
339 			target(onThis)
340 		{
341 		}
342 
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:
355 	PlainLockingMemberFunctionObject(void (T::*function)(), T* target)
356 		:	function(function),
357 			messenger(target)
358 		{
359 		}
360 
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:
380 	PlainMemberFunctionObjectWithResult(R (T::*function)(), T* onThis)
381 		:	function(function),
382 			target(onThis)
383 		{
384 		}
385 
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:
399 	SingleParamMemberFunctionObject(void (T::*function)(Param1),
400 		T* onThis, Param1 p1)
401 		:	function(function),
402 			target(onThis),
403 			p1(p1)
404 		{
405 		}
406 
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:
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 
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:
445 	SingleParamMemberFunctionObjectWithResult(R (T::*function)(Param1),
446 		T* onThis, Param1 p1)
447 		:	function(function),
448 			target(onThis),
449 			p1(p1)
450 		{
451 		}
452 
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:
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 
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>*
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>*
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>*
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>*
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>*
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>*
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>*
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>*
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