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