1/* 2Open Tracker License 3 4Terms and Conditions 5 6Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7 8Permission is hereby granted, free of charge, to any person obtaining a copy of 9this software and associated documentation files (the "Software"), to deal in 10the Software without restriction, including without limitation the rights to 11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12of the Software, and to permit persons to whom the Software is furnished to do 13so, subject to the following conditions: 14 15The above copyright notice and this permission notice applies to all licensees 16and shall be included in all copies or substantial portions of the Software. 17 18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25Except as contained in this notice, the name of Be Incorporated shall not be 26used in advertising or otherwise to promote the sale, use or other dealings in 27this Software without prior written authorization from Be Incorporated. 28 29Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks 30of Be Incorporated in the United States and other countries. Other brand product 31names are registered trademarks or trademarks of their respective holders. 32All 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 56namespace BPrivate { 57 58template<class P> 59class ParameterBinder { 60// primitive default binder for scalars 61public: 62 ParameterBinder() {} 63 ParameterBinder(P p) 64 : p(p) 65 {} 66 67 P Pass() const 68 { return p; } 69private: 70 P p; 71}; 72 73 74template<> 75class ParameterBinder<const BEntry*> { 76public: 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; } 87private: 88 BEntry p; 89}; 90 91 92template<> 93class ParameterBinder<const entry_ref*> { 94public: 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; } 107private: 108 entry_ref p; 109}; 110 111 112template<> 113class ParameterBinder<const node_ref*> { 114public: 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; } 125private: 126 node_ref p; 127}; 128 129 130template<> 131class ParameterBinder<const BMessage*> { 132public: 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 153private: 154 BMessage* p; 155}; 156 157 158class FunctionObject { 159public: 160 virtual void operator()() = 0; 161 virtual ~FunctionObject() {} 162}; 163 164 165template<class R> 166class FunctionObjectWithResult : public FunctionObject { 167public: 168 const R &Result() const { return result; } 169 170protected: 171 R result; 172}; 173 174 175template <class Param1> 176class SingleParamFunctionObject : public FunctionObject { 177public: 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 187private: 188 void (*function)(Param1); 189 ParameterBinder<Param1> p1; 190}; 191 192 193template <class Result, class Param1> 194class SingleParamFunctionObjectWithResult : public 195 FunctionObjectWithResult<Result> { 196public: 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 206private: 207 Result (*function)(Param1); 208 ParameterBinder<Param1> p1; 209}; 210 211 212template <class Param1, class Param2> 213class TwoParamFunctionObject : public FunctionObject { 214public: 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 225private: 226 void (*function)(Param1, Param2); 227 ParameterBinder<Param1> p1; 228 ParameterBinder<Param2> p2; 229}; 230 231 232template <class Param1, class Param2, class Param3> 233class ThreeParamFunctionObject : public FunctionObject { 234public: 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 246private: 247 void (*function)(Param1, Param2, Param3); 248 ParameterBinder<Param1> p1; 249 ParameterBinder<Param2> p2; 250 ParameterBinder<Param3> p3; 251}; 252 253 254template <class Result, class Param1, class Param2, class Param3> 255class ThreeParamFunctionObjectWithResult : public 256 FunctionObjectWithResult<Result> { 257public: 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 272private: 273 Result (*function)(Param1, Param2, Param3); 274 ParameterBinder<Param1> p1; 275 ParameterBinder<Param2> p2; 276 ParameterBinder<Param3> p3; 277}; 278 279 280template <class Param1, class Param2, class Param3, class Param4> 281class FourParamFunctionObject : public FunctionObject { 282public: 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 296private: 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 305template <class Result, class Param1, class Param2, class Param3, 306 class Param4> 307class FourParamFunctionObjectWithResult : public 308 FunctionObjectWithResult<Result> { 309public: 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 325private: 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 334template<class T> 335class PlainMemberFunctionObject : public FunctionObject { 336public: 337 PlainMemberFunctionObject(void (T::*function)(), T* onThis) 338 : function(function), 339 target(onThis) 340 { 341 } 342 343 virtual void operator()() 344 { (target->*function)(); } 345 346private: 347 void (T::*function)(); 348 T* target; 349}; 350 351 352template<class T> 353class PlainLockingMemberFunctionObject : public FunctionObject { 354public: 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 370private: 371 void (T::*function)(); 372 BMessenger messenger; 373}; 374 375 376template<class T, class R> 377class PlainMemberFunctionObjectWithResult : public 378 FunctionObjectWithResult<R> { 379public: 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 390private: 391 R (T::*function)(); 392 T* target; 393}; 394 395 396template<class T, class Param1> 397class SingleParamMemberFunctionObject : public FunctionObject { 398public: 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 410private: 411 void (T::*function)(Param1); 412 T* target; 413 ParameterBinder<Param1> p1; 414}; 415 416 417template<class T, class Param1, class Param2> 418class TwoParamMemberFunctionObject : public FunctionObject { 419public: 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 433protected: 434 void (T::*function)(Param1, Param2); 435 T* target; 436 ParameterBinder<Param1> p1; 437 ParameterBinder<Param2> p2; 438}; 439 440 441template<class T, class R, class Param1> 442class SingleParamMemberFunctionObjectWithResult : public 443 FunctionObjectWithResult<R> { 444public: 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 457protected: 458 R (T::*function)(Param1); 459 T* target; 460 ParameterBinder<Param1> p1; 461}; 462 463 464template<class T, class R, class Param1, class Param2> 465class TwoParamMemberFunctionObjectWithResult : public 466 FunctionObjectWithResult<R> { 467public: 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 481protected: 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 497template<class Param1> 498SingleParamFunctionObject<Param1>* 499NewFunctionObject(void (*function)(Param1), Param1 p1) 500{ 501 return new SingleParamFunctionObject<Param1>(function, p1); 502} 503 504 505template<class Param1, class Param2> 506TwoParamFunctionObject<Param1, Param2>* 507NewFunctionObject(void (*function)(Param1, Param2), Param1 p1, Param2 p2) 508{ 509 return new TwoParamFunctionObject<Param1, Param2>(function, p1, p2); 510} 511 512 513template<class Param1, class Param2, class Param3> 514ThreeParamFunctionObject<Param1, Param2, Param3>* 515NewFunctionObject(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 523template<class T> 524PlainMemberFunctionObject<T>* 525NewMemberFunctionObject(void (T::*function)(), T* onThis) 526{ 527 return new PlainMemberFunctionObject<T>(function, onThis); 528} 529 530 531template<class T, class Param1> 532SingleParamMemberFunctionObject<T, Param1>* 533NewMemberFunctionObject(void (T::*function)(Param1), T* onThis, Param1 p1) 534{ 535 return new SingleParamMemberFunctionObject<T, Param1> 536 (function, onThis, p1); 537} 538 539 540template<class T, class Param1, class Param2> 541TwoParamMemberFunctionObject<T, Param1, Param2>* 542NewMemberFunctionObject(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 550template<class T, class R, class Param1, class Param2> 551TwoParamMemberFunctionObjectWithResult<T, R, Param1, Param2>* 552NewMemberFunctionObjectWithResult(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 560template<class HandlerOrSubclass> 561PlainLockingMemberFunctionObject<HandlerOrSubclass>* 562NewLockingMemberFunctionObject(void (HandlerOrSubclass::*function)(), 563 HandlerOrSubclass* onThis) 564{ 565 return new PlainLockingMemberFunctionObject<HandlerOrSubclass> 566 (function, onThis); 567} 568 569} // namespace BPrivate 570 571using namespace BPrivate; 572 573#endif // __FUNCTION_OBJECT__ 574