1 /** 2 * @file scim_signals.h 3 * @brief C++ signal interface. 4 * 5 * Provides a set of signal class templates you can use to create signals 6 * that can pass up to 6 arguments to signal handlers connected via the 7 * slot interface (see scim_slot.h). The signal classes are named Signal0 8 * to Signal6, where 0 to 6 specifies the number of arguments that can be 9 * passed to a slot. 10 * 11 * Most code of this file are came from Inti project. 12 */ 13 14 /* 15 * Smart Common Input Method 16 * 17 * Copyright (c) 2002-2005 James Su <suzhe@tsinghua.org.cn> 18 * Copyright (c) 2002 The Inti Development Team. 19 * Copyright (c) 2000 Red Hat, Inc. 20 * Copyright 1999, Karl Einar Nelson 21 * 22 * 23 * This library is free software; you can redistribute it and/or 24 * modify it under the terms of the GNU Lesser General Public 25 * License as published by the Free Software Foundation; either 26 * version 2 of the License, or (at your option) any later version. 27 * 28 * This library is distributed in the hope that it will be useful, 29 * but WITHOUT ANY WARRANTY; without even the implied warranty of 30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31 * GNU Lesser General Public License for more details. 32 * 33 * You should have received a copy of the GNU Lesser General Public 34 * License along with this program; if not, write to the 35 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 36 * Boston, MA 02111-1307 USA 37 * 38 * $Id: scim_signals.h,v 1.12 2005/01/30 13:24:13 suzhe Exp $ 39 */ 40 41 #ifndef __SCIM_SIGNALS_H 42 #define __SCIM_SIGNALS_H 43 44 namespace scim { 45 46 /** 47 * @addtogroup SignalSlot 48 * @{ 49 */ 50 51 class Signal; 52 53 //! @class SlotNode 54 //! @brief A node class for managing slots connected to scim::Signal's. 55 56 class SlotNode : public Node 57 { 58 friend class Signal; 59 60 SlotNode(Slot *slot); 61 ~SlotNode(); 62 63 bool is_blocked; 64 65 public: blocked()66 bool blocked() const { return is_blocked; } 67 //!< Returns true if the slot is blocked. 68 69 virtual void block(); 70 //!< Block signal emission to the slot until unblock is called. 71 72 virtual void unblock(); 73 //!< Unblock the slot so signal emmissions can be received. 74 75 virtual void disconnect(); 76 //!< Disconnect the slot. The slot will no longer recieve signal emissions. 77 }; 78 79 // DefaultMarshal class (from marshal.h, libsigc++) 80 81 template <typename R> 82 class DefaultMarshal 83 { 84 public: 85 typedef R OutType; 86 typedef R InType; 87 88 private: 89 OutType value_; 90 91 public: DefaultMarshal()92 DefaultMarshal() :value_() {} 93 value()94 OutType& value() { return value_; } 95 96 // Return true to stop emission. marshal(const InType & newval)97 bool marshal(const InType & newval) 98 { 99 value_ = newval; 100 return false; 101 } 102 }; 103 104 // Marshal specialization 105 template <> 106 class DefaultMarshal <bool> 107 { 108 public: 109 typedef bool OutType; 110 typedef bool InType; 111 112 private: 113 OutType value_; 114 115 public: DefaultMarshal()116 DefaultMarshal() :value_(false) {} 117 value()118 OutType& value() { return value_; } 119 120 // Return true to stop emission. marshal(const InType & newval)121 bool marshal(const InType & newval) 122 { 123 value_ = newval; 124 return false; 125 } 126 }; 127 128 //! @class Signal 129 //! @brief Base class for the C++ signal interface. 130 131 class Signal 132 { 133 Signal(const Signal&); 134 Signal& operator=(const Signal&); 135 136 protected: 137 typedef std::vector< Pointer<SlotNode> > ConnectionList; 138 //!< ConnectionList type. 139 140 ConnectionList connection_list; 141 //!< A list of all the slots connected to the signal. 142 143 public: 144 Signal(); 145 //!< Constructor. 146 147 virtual ~Signal(); 148 //!< Destructor. 149 150 SlotNode* connect(Slot *slot); 151 //!< Creates a new SlotNode for slot and adds it to the <EM>connection_list</EM>. 152 }; 153 154 //! @class Signal0 155 //! @brief A template for a signal passing no arguments and returning a value of type R. 156 157 template<typename R, typename Marshal = class DefaultMarshal<R> > 158 class Signal0 : public Signal 159 { 160 typedef Signal0<R> Self; 161 callback(void * data)162 static R callback(void *data) 163 { 164 Self *s = static_cast<Self*>(data); 165 return s->emit(); 166 } 167 168 public: 169 typedef Slot0<R> SlotType; 170 //!< Function signature for handlers connecting the signal. 171 connect(SlotType * slot)172 Connection connect(SlotType *slot) 173 { 174 return Signal::connect(slot); 175 } 176 //!< Connect a slot to the signal. 177 //!< @param slot - a slot of type Slot0<R>. 178 //!< @return a connection object. 179 //!< 180 //!< <BR>The returned connection object can be used alter or change the connection. 181 slot()182 SlotType* slot() 183 { 184 return new SignalSlot0<Self, R>(this, &callback); 185 } 186 //!< Returns a slot for this signal. 187 //!< @return a new slot of type Slot0<R>. 188 //!< 189 //!< <BR>The returned slot can be passed to another signal allowing the 190 //!< other signal to call this signal when it gets emitted. 191 emit()192 R emit() 193 { 194 Marshal m; 195 ConnectionList::iterator i = connection_list.begin(); 196 while (i != connection_list.end()) 197 { 198 if (!(*i)->blocked()) 199 { 200 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 201 if (slot && m.marshal(slot->call())) 202 break; 203 } 204 ++i; 205 } 206 return m.value(); 207 } 208 //!< Emit the signal. 209 //!< @return the value returned by the signal handler. 210 //!< 211 //!< <BR>Calls every slot connected to this signal, in order of connection. 212 operator()213 R operator()() 214 { 215 return emit(); 216 } 217 //!< Function operator; calls emit(). 218 }; 219 220 // Signal0 partially specialized for void return 221 222 template<typename IgnoreMarshal> 223 class Signal0<void, IgnoreMarshal> : public Signal 224 { 225 typedef Signal0<void, IgnoreMarshal> Self; 226 callback(void * data)227 static void callback(void *data) 228 { 229 Self *s = static_cast<Self*>(data); 230 s->emit(); 231 } 232 233 public: 234 typedef Slot0<void> SlotType; 235 connect(SlotType * slot)236 Connection connect(SlotType *slot) 237 { 238 return Signal::connect(slot); 239 } 240 slot()241 SlotType* slot() 242 { 243 return new SignalSlot0<Self, void>(this, &callback); 244 } 245 emit()246 void emit() 247 { 248 ConnectionList::iterator i = connection_list.begin(); 249 while (i != connection_list.end()) 250 { 251 if (!(*i)->blocked()) 252 { 253 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 254 if (slot) slot->call(); 255 } 256 ++i; 257 } 258 } 259 operator()260 void operator()() 261 { 262 emit(); 263 } 264 }; 265 266 //! @class Signal1 267 //! @brief A template for a signal passing one argument of type P1 and returning a value of type R. 268 269 template<typename R, typename P1, typename Marshal = class DefaultMarshal<R> > 270 class Signal1 : public Signal 271 { 272 typedef Signal1<R, P1> Self; 273 callback(void * data,P1 p1)274 static R callback(void *data, P1 p1) 275 { 276 Self *s = static_cast<Self*>(data); 277 return s->emit(p1); 278 } 279 280 public: 281 typedef Slot1<R, P1> SlotType; 282 //!< Function signature for handlers connecting to the signal. 283 connect(SlotType * slot)284 Connection connect(SlotType *slot) 285 { 286 return Signal::connect(slot); 287 } 288 //!< Connect a slot to the signal. 289 //!< @param slot - a slot of type Slot1<R, P1>. 290 //!< @return a connection object. 291 //!< 292 //!< <BR>The returned connection object can be used alter or change the connection. 293 slot()294 SlotType* slot() 295 { 296 return new SignalSlot1<Self, R, P1>(this, &callback); 297 } 298 //!< Returns a slot for this signal. 299 //!< @return a new slot of type Slot1<R, P1>. 300 //!< 301 //!< <BR>The returned slot can be passed to another signal allowing the 302 //!< other signal to call this signal when it gets emitted. 303 emit(P1 p1)304 R emit(P1 p1) 305 { 306 Marshal m; 307 ConnectionList::iterator i = connection_list.begin(); 308 while (i != connection_list.end()) 309 { 310 if (!(*i)->blocked()) 311 { 312 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 313 if (slot && m.marshal(slot->call(p1))) 314 break; 315 } 316 ++i; 317 } 318 return m.value(); 319 } 320 //!< Emit the signal. 321 //!< @param p1 - passes p1 to the signal handler. 322 //!< @return the value returned by the signal handler. 323 //!< 324 //!< <BR>Calls every slot connected to this signal, in order of connection. 325 operator()326 R operator()(P1 p1) 327 { 328 return emit(p1); 329 } 330 //!< Function operator; calls emit(). 331 }; 332 333 // Signal1 partially specialized for void return 334 335 template<typename P1, typename IgnoreMarshal> 336 class Signal1<void, P1, IgnoreMarshal> : public Signal 337 { 338 typedef Signal1<void, P1, IgnoreMarshal> Self; 339 callback(void * data,P1 p1)340 static void callback(void *data, P1 p1) 341 { 342 Self *s = static_cast<Self*>(data); 343 s->emit(p1); 344 } 345 346 public: 347 typedef Slot1<void, P1> SlotType; 348 connect(SlotType * slot)349 Connection connect(SlotType *slot) 350 { 351 return Signal::connect(slot); 352 } 353 slot()354 SlotType* slot() 355 { 356 return new SignalSlot1<Self, void, P1>(this, &callback); 357 } 358 emit(P1 p1)359 void emit(P1 p1) 360 { 361 ConnectionList::iterator i = connection_list.begin(); 362 while (i != connection_list.end()) 363 { 364 if (!(*i)->blocked()) 365 { 366 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 367 if (slot) slot->call(p1); 368 } 369 ++i; 370 } 371 } 372 operator()373 void operator()(P1 p1) 374 { 375 emit(p1); 376 } 377 }; 378 379 //! @class Signal2 380 //! @brief A template for a signal passing two arguments of type P1 and P2, 381 //! and returning a value of type R. 382 383 template<typename R, typename P1, typename P2, typename Marshal = class DefaultMarshal<R> > 384 class Signal2 : public Signal 385 { 386 typedef Signal2<R, P1, P2> Self; 387 callback(void * data,P1 p1,P2 p2)388 static R callback(void *data, P1 p1, P2 p2) 389 { 390 Self *s = static_cast<Self*>(data); 391 return s->emit(p1, p2); 392 } 393 394 public: 395 typedef Slot2<R, P1, P2> SlotType; 396 //!< Function signature for handlers connecting to the signal. 397 connect(SlotType * slot)398 Connection connect(SlotType *slot) 399 { 400 return Signal::connect(slot); 401 } 402 //!< Connect a slot to the signal. 403 //!< @param slot - a slot of type Slot2<R, P1, P2>. 404 //!< @return a connection object. 405 //!< 406 //!< <BR>The returned connection object can be used alter or change the connection. 407 slot()408 SlotType* slot() 409 { 410 return new SignalSlot2<Self, R, P1, P2>(this, &callback); 411 } 412 //!< Returns a slot for this signal. 413 //!< @return a new slot of type Slot2<R, P1, P2>. 414 //!< 415 //!< <BR>The returned slot can be passed to another signal allowing the 416 //!< other signal to call this signal when it gets emitted. 417 emit(P1 p1,P2 p2)418 R emit(P1 p1, P2 p2) 419 { 420 Marshal m; 421 ConnectionList::iterator i = connection_list.begin(); 422 while (i != connection_list.end()) 423 { 424 if (!(*i)->blocked()) 425 { 426 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 427 if (slot && m.marshal(slot->call(p1, p2))) 428 break; 429 } 430 ++i; 431 } 432 return m.value(); 433 } 434 //!< Emit the signal. 435 //!< @param p1 - passes p1 to the signal handler. 436 //!< @param p2 - passes p2 to the signal handler. 437 //!< @return the value returned by the signal handler. 438 //!< 439 //!< <BR>Calls every slot connected to this signal, in order of connection. 440 operator()441 R operator()(P1 p1, P2 p2) 442 { 443 return emit(p1, p2); 444 } 445 //!< Function operator; calls emit(). 446 }; 447 448 // Signal2 partially specialized for void return 449 450 template<typename P1, typename P2, typename IgnoreMarshal> 451 class Signal2<void, P1, P2, IgnoreMarshal> : public Signal 452 { 453 typedef Signal2<void, P1, P2, IgnoreMarshal> Self; 454 callback(void * data,P1 p1,P2 p2)455 static void callback(void *data, P1 p1, P2 p2) 456 { 457 Self *s = static_cast<Self*>(data); 458 s->emit(p1, p2); 459 } 460 461 public: 462 typedef Slot2<void, P1, P2> SlotType; 463 connect(SlotType * slot)464 Connection connect(SlotType *slot) 465 { 466 return Signal::connect(slot); 467 } 468 slot()469 SlotType* slot() 470 { 471 return new SignalSlot2<Self, void, P1, P2>(this, &callback); 472 } 473 emit(P1 p1,P2 p2)474 void emit(P1 p1, P2 p2) 475 { 476 ConnectionList::iterator i = connection_list.begin(); 477 while (i != connection_list.end()) 478 { 479 if (!(*i)->blocked()) 480 { 481 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 482 if (slot) slot->call(p1, p2); 483 } 484 ++i; 485 } 486 } 487 operator()488 void operator()(P1 p1, P2 p2) 489 { 490 emit(p1, p2); 491 } 492 }; 493 494 //! @class Signal3 495 //! @brief A template for a signal passing three arguments of type P1, P2 and P3, 496 //! and returning a value of type R. 497 498 template<typename R, typename P1, typename P2, typename P3, typename Marshal = class DefaultMarshal<R> > 499 class Signal3 : public Signal 500 { 501 typedef Signal3<R, P1, P2, P3> Self; 502 callback(void * data,P1 p1,P2 p2,P3 p3)503 static R callback(void *data, P1 p1, P2 p2, P3 p3) 504 { 505 Self *s = static_cast<Self*>(data); 506 return s->emit(p1, p2, p3); 507 } 508 509 public: 510 typedef Slot3<R, P1, P2, P3> SlotType; 511 //!< Function signature for handlers connecting to the signal. 512 connect(SlotType * slot)513 Connection connect(SlotType *slot) 514 { 515 return Signal::connect(slot); 516 } 517 //!< Connect a slot to the signal. 518 //!< @param slot - a slot of type Slot3<R, P1, P2, P3>. 519 //!< @return a connection object. 520 //!< 521 //!< <BR>The returned connection object can be used alter or change the connection. 522 slot()523 SlotType* slot() 524 { 525 return new SignalSlot3<Self, R, P1, P2, P3>(this, &callback); 526 } 527 //!< Returns a slot for this signal. 528 //!< @return a new slot of type Slot3<R, P1, P2, P3>. 529 //!< 530 //!< <BR>The returned slot can be passed to another signal allowing the 531 //!< other signal to call this signal when it gets emitted. 532 emit(P1 p1,P2 p2,P3 p3)533 R emit(P1 p1, P2 p2, P3 p3) 534 { 535 Marshal m; 536 ConnectionList::iterator i = connection_list.begin(); 537 while (i != connection_list.end()) 538 { 539 if (!(*i)->blocked()) 540 { 541 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 542 if (slot && m.marshal(slot->call(p1, p2, p3))) 543 break; 544 } 545 ++i; 546 } 547 return m.value(); 548 } 549 //!< Emit the signal. 550 //!< @param p1 - passes p1 to the signal handler. 551 //!< @param p2 - passes p2 to the signal handler. 552 //!< @param p3 - passes p3 to the signal handler. 553 //!< @return the value returned by the signal handler. 554 //!< 555 //!< <BR>Calls every slot connected to this signal, in order of connection. 556 operator()557 R operator()(P1 p1, P2 p2, P3 p3) 558 { 559 return emit(p1, p2, p3); 560 } 561 //!< Function operator; calls emit(). 562 }; 563 564 // Signal3 partially specialized for void return 565 566 template<typename P1, typename P2, typename P3, typename IgnoreMarshal> 567 class Signal3<void, P1, P2, P3, IgnoreMarshal> : public Signal 568 { 569 typedef Signal3<void, P1, P2, P3, IgnoreMarshal> Self; 570 callback(void * data,P1 p1,P2 p2,P3 p3)571 static void callback(void *data, P1 p1, P2 p2, P3 p3) 572 { 573 Self *s = static_cast<Self*>(data); 574 s->emit(p1, p2, p3); 575 } 576 577 public: 578 typedef Slot3<void, P1, P2, P3> SlotType; 579 connect(SlotType * slot)580 Connection connect(SlotType *slot) 581 { 582 return Signal::connect(slot); 583 } 584 slot()585 SlotType* slot() 586 { 587 return new SignalSlot3<Self, void, P1, P2, P3>(this, &callback); 588 } 589 emit(P1 p1,P2 p2,P3 p3)590 void emit(P1 p1, P2 p2, P3 p3) 591 { 592 ConnectionList::iterator i = connection_list.begin(); 593 while (i != connection_list.end()) 594 { 595 if (!(*i)->blocked()) 596 { 597 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 598 if (slot) slot->call(p1, p2, p3); 599 } 600 ++i; 601 } 602 } 603 operator()604 void operator()(P1 p1, P2 p2, P3 p3) 605 { 606 emit(p1, p2, p3); 607 } 608 }; 609 610 //! @class Signal4 611 //! @brief A template for a signal passing four arguments of type P1, P2, P3 and P4, 612 //! and returning a value of type R. 613 614 template<typename R, typename P1, typename P2, typename P3, typename P4, typename Marshal = class DefaultMarshal<R> > 615 class Signal4 : public Signal 616 { 617 typedef Signal4<R, P1, P2, P3, P4> Self; 618 callback(void * data,P1 p1,P2 p2,P3 p3,P4 p4)619 static R callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4) 620 { 621 Self *s = static_cast<Self*>(data); 622 return s->emit(p1, p2, p3, p4); 623 } 624 625 public: 626 typedef Slot4<R, P1, P2, P3, P4> SlotType; 627 //!< Function signature for handlers connecting to the signal. 628 connect(SlotType * slot)629 Connection connect(SlotType *slot) 630 { 631 return Signal::connect(slot); 632 } 633 //!< Connect a slot to the signal. 634 //!< @param slot - a slot of type Slot4<R, P1, P2, P3, P4>. 635 //!< @return a connection object. 636 //!< 637 //!< <BR>The returned connection object can be used alter or change the connection. 638 slot()639 SlotType* slot() 640 { 641 return new SignalSlot4<Self, R, P1, P2, P3, P4>(this, &callback); 642 } 643 //!< Returns a slot for this signal. 644 //!< @return a new slot of type Slot4<R, P1, P2, P3, P4>. 645 //!< 646 //!< <BR>The returned slot can be passed to another signal allowing the 647 //!< other signal to call this signal when it gets emitted. 648 emit(P1 p1,P2 p2,P3 p3,P4 p4)649 R emit(P1 p1, P2 p2, P3 p3, P4 p4) 650 { 651 Marshal m; 652 ConnectionList::iterator i = connection_list.begin(); 653 while (i != connection_list.end()) 654 { 655 if (!(*i)->blocked()) 656 { 657 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 658 if (slot && m.marshal(slot->call(p1, p2, p3, p4))) 659 break; 660 } 661 ++i; 662 } 663 return m.value(); 664 } 665 //!< Emit the signal. 666 //!< @param p1 - passes p1 to the signal handler. 667 //!< @param p2 - passes p2 to the signal handler. 668 //!< @param p3 - passes p3 to the signal handler. 669 //!< @param p4 - passes p4 to the signal handler. 670 //!< @return the value returned by the signal handler. 671 //!< 672 //!< <BR>Calls every slot connected to this signal, in order of connection. 673 operator()674 R operator()(P1 p1, P2 p2, P3 p3, P4 p4) 675 { 676 return emit(p1, p2, p3, p4); 677 } 678 //!< Function operator; calls emit(). 679 }; 680 681 // Signal4 partially specialized for void return 682 683 template<typename P1, typename P2, typename P3, typename P4, typename IgnoreMarshal> 684 class Signal4<void, P1, P2, P3, P4, IgnoreMarshal> : public Signal 685 { 686 typedef Signal4<void, P1, P2, P3, P4, IgnoreMarshal> Self; 687 callback(void * data,P1 p1,P2 p2,P3 p3,P4 p4)688 static void callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4) 689 { 690 Self *s = static_cast<Self*>(data); 691 s->emit(p1, p2, p3, p4); 692 } 693 694 public: 695 typedef Slot4<void, P1, P2, P3, P4> SlotType; 696 connect(SlotType * slot)697 Connection connect(SlotType *slot) 698 { 699 return Signal::connect(slot); 700 } 701 slot()702 SlotType* slot() 703 { 704 return new SignalSlot4<Self, void, P1, P2, P3, P4>(this, &callback); 705 } 706 emit(P1 p1,P2 p2,P3 p3,P4 p4)707 void emit(P1 p1, P2 p2, P3 p3, P4 p4) 708 { 709 ConnectionList::iterator i = connection_list.begin(); 710 while (i != connection_list.end()) 711 { 712 if (!(*i)->blocked()) 713 { 714 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 715 if (slot) slot->call(p1, p2, p3, p4); 716 } 717 ++i; 718 } 719 } 720 operator()721 void operator()(P1 p1, P2 p2, P3 p3, P4 p4) 722 { 723 emit(p1, p2, p3, p4); 724 } 725 }; 726 727 //! @class Signal5 728 //! @brief A template for a signal passing five arguments of type P1, P2, P3, P4 and P5, 729 //! and returning a value of type R. 730 731 template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename Marshal = class DefaultMarshal<R> > 732 class Signal5 : public Signal 733 { 734 typedef Signal5<R, P1, P2, P3, P4, P5> Self; 735 callback(void * data,P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)736 static R callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 737 { 738 Self *s = static_cast<Self*>(data); 739 return s->emit(p1, p2, p3, p4, p5); 740 } 741 742 public: 743 typedef Slot5<R, P1, P2, P3, P4, P5> SlotType; 744 //!< Function signature for handlers connecting to the signal. 745 connect(SlotType * slot)746 Connection connect(SlotType *slot) 747 { 748 return Signal::connect(slot); 749 } 750 //!< Connect a slot to the signal. 751 //!< @param slot - a slot of type Slot5<R, P1, P2, P3, P4, P5>. 752 //!< @return a connection object. 753 //!< 754 //!< <BR>The returned connection object can be used alter or change the connection. 755 slot()756 SlotType* slot() 757 { 758 return new SignalSlot5<Self, R, P1, P2, P3, P4, P5>(this, &callback); 759 } 760 //!< Returns a slot for this signal. 761 //!< @return a new slot of type Slot5<R, P1, P2, P3, P4, P5>. 762 //!< 763 //!< <BR>The returned slot can be passed to another signal allowing the 764 //!< other signal to call this signal when it gets emitted. 765 emit(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)766 R emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 767 { 768 Marshal m; 769 ConnectionList::iterator i = connection_list.begin(); 770 while (i != connection_list.end()) 771 { 772 if (!(*i)->blocked()) 773 { 774 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 775 if (slot && m.marshal(slot->call(p1, p2, p3, p4, p5))) 776 break; 777 } 778 ++i; 779 } 780 return m.value(); 781 } 782 //!< Emit the signal. 783 //!< @param p1 - passes p1 to the signal handler. 784 //!< @param p2 - passes p2 to the signal handler. 785 //!< @param p3 - passes p3 to the signal handler. 786 //!< @param p4 - passes p4 to the signal handler. 787 //!< @param p5 - passes p5 to the signal handler. 788 //!< @return the value returned by the signal handler. 789 //!< 790 //!< <BR>Calls every slot connected to this signal, in order of connection. 791 operator()792 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 793 { 794 return emit(p1, p2, p3, p4, p5); 795 } 796 //!< Function operator; calls emit(). 797 }; 798 799 // Signal5 partially specialized for void return 800 801 template<typename P1, typename P2, typename P3, typename P4, typename P5, typename IgnoreMarshal> 802 class Signal5<void, P1, P2, P3, P4, P5, IgnoreMarshal> : public Signal 803 { 804 typedef Signal5<void, P1, P2, P3, P4, P5, IgnoreMarshal> Self; 805 callback(void * data,P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)806 static void callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 807 { 808 Self *s = static_cast<Self*>(data); 809 s->emit(p1, p2, p3, p4, p5); 810 } 811 812 public: 813 typedef Slot5<void, P1, P2, P3, P4, P5> SlotType; 814 connect(SlotType * slot)815 Connection connect(SlotType *slot) 816 { 817 return Signal::connect(slot); 818 } 819 slot()820 SlotType* slot() 821 { 822 return new SignalSlot5<Self, void, P1, P2, P3, P4, P5>(this, &callback); 823 } 824 emit(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)825 void emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 826 { 827 ConnectionList::iterator i = connection_list.begin(); 828 while (i != connection_list.end()) 829 { 830 if (!(*i)->blocked()) 831 { 832 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 833 if (slot) slot->call(p1, p2, p3, p4, p5); 834 } 835 ++i; 836 } 837 } 838 operator()839 void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 840 { 841 emit(p1, p2, p3, p4, p5); 842 } 843 }; 844 845 //! @class Signal6 846 //! @brief A template for a signal passing six arguments of type P1, P2, P3, P4, P5 and P6, 847 //! and returning a value of type R. 848 849 template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename Marshal = class DefaultMarshal<R> > 850 class Signal6 : public Signal 851 { 852 typedef Signal6<R, P1, P2, P3, P4, P5, P6> Self; 853 callback(void * data,P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6)854 static R callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 855 { 856 Self *s = static_cast<Self*>(data); 857 return s->emit(p1, p2, p3, p4, p5, p6); 858 } 859 860 public: 861 typedef Slot6<R, P1, P2, P3, P4, P5, P6> SlotType; 862 //!< Function signature for handlers connecting to the signal. 863 connect(SlotType * slot)864 Connection connect(SlotType *slot) 865 { 866 return Signal::connect(slot); 867 } 868 //!< Connect a slot to the signal. 869 //!< @param slot - a slot of type Slot6<R, P1, P2, P3, P4, P5, P6>. 870 //!< @return a connection object. 871 //!< 872 //!< <BR>The returned connection object can be used alter or change the connection. 873 slot()874 SlotType* slot() 875 { 876 return new SignalSlot6<Self, R, P1, P2, P3, P4, P5, P6>(this, &callback); 877 } 878 //!< Returns a slot for this signal. 879 //!< @return a new slot of type Slot6<R, P1, P2, P3, P4, P5, P6>. 880 //!< 881 //!< <BR>The returned slot can be passed to another signal allowing the 882 //!< other signal to call this signal when it gets emitted. 883 emit(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6)884 R emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 885 { 886 Marshal m; 887 ConnectionList::iterator i = connection_list.begin(); 888 while (i != connection_list.end()) 889 { 890 if (!(*i)->blocked()) 891 { 892 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 893 if (slot && m.marshal(slot->call(p1, p2, p3, p4, p5, p6))) 894 break; 895 } 896 ++i; 897 } 898 return m.value(); 899 } 900 //!< Emit the signal. 901 //!< @param p1 - passes p1 to the signal handler. 902 //!< @param p2 - passes p2 to the signal handler. 903 //!< @param p3 - passes p3 to the signal handler. 904 //!< @param p4 - passes p4 to the signal handler. 905 //!< @param p5 - passes p5 to the signal handler. 906 //!< @param p6 - passes p6 to the signal handler. 907 //!< @return the value returned by the signal handler. 908 //!< 909 //!< <BR>Calls every slot connected to this signal, in order of connection. 910 operator()911 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 912 { 913 return emit(p1, p2, p3, p4, p5, p6); 914 } 915 //!< Function operator; calls emit(). 916 }; 917 918 /* Signal6 partially specialized for void return 919 */ 920 921 template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename IgnoreMarshal> 922 class Signal6<void, P1, P2, P3, P4, P5, P6, IgnoreMarshal> : public Signal 923 { 924 typedef Signal6<void, P1, P2, P3, P4, P5, P6, IgnoreMarshal> Self; 925 callback(void * data,P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6)926 static void callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 927 { 928 Self *s = static_cast<Self*>(data); 929 s->emit(p1, p2, p3, p4, p5, p6); 930 } 931 932 public: 933 typedef Slot6<void, P1, P2, P3, P4, P5, P6> SlotType; 934 connect(SlotType * slot)935 Connection connect(SlotType *slot) 936 { 937 return Signal::connect(slot); 938 } 939 slot()940 SlotType* slot() 941 { 942 return new SignalSlot6<Self, void, P1, P2, P3, P4, P5, P6>(this, &callback); 943 } 944 emit(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6)945 void emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 946 { 947 ConnectionList::iterator i = connection_list.begin(); 948 while (i != connection_list.end()) 949 { 950 if (!(*i)->blocked()) 951 { 952 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot()); 953 if (slot) slot->call(p1, p2, p3, p4, p5, p6); 954 } 955 ++i; 956 } 957 } 958 operator()959 void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 960 { 961 emit(p1, p2, p3, p4, p5, p6); 962 } 963 }; 964 965 /** @} */ 966 967 } // namespace scim 968 969 #endif //__SCIM_SIGNALS_H 970 971 /* 972 vi:ts=4:nowrap:ai:expandtab 973 */ 974 975