00001 /* 00002 This class provides basic signals and slots support. 00003 00004 Copyright (C) 2010 - 2014 Christoph Haenisch 00005 00006 Chair of Medical Engineering (mediTEC) 00007 RWTH Aachen University 00008 Pauwelsstr. 20 00009 52074 Aachen 00010 Germany 00011 00012 See license.txt for more information. 00013 00014 Version 1.2.2 (2014-07-03) 00015 */ 00016 00022 #ifndef SIGNALS_HPP_6243120120 00023 #define SIGNALS_HPP_6243120120 00024 00025 00026 #include <cstddef> 00027 #include <cstring> 00028 #include <list> 00029 #include <set> 00030 #include <stdexcept> 00031 #include <utility> 00032 00033 #include "Tools.hpp" 00034 00035 00036 /* 00037 00038 How does the implementation of the signal/slot concecpt work? 00039 00040 The signal/slot concecpt works according to the publish/subscribe pattern. A 00041 signal with certain properties is defined and subscribers with the same method 00042 signature are able to connect to this signal. If the signal is called (or emitted 00043 or send), the subscribers are informed (or called) as well. Everything is done 00044 transparently. 00045 00046 Example: 00047 00048 class A 00049 { 00050 public: 00051 // ... 00052 00053 void run() 00054 { 00055 // ... 00056 ++value; 00057 hasChanged.send(value); 00058 } 00059 00060 Signal<int> hasChanged; 00061 00062 private: 00063 int value; 00064 }; 00065 00066 class B 00067 { 00068 public: 00069 void function(int) {}; 00070 }; 00071 00072 A a; 00073 B b; 00074 00075 a.hasChanged.connect(&b, &B::function); 00076 a.run(); // calls also b.function() 00077 00078 B::function must have the same signature (int as first argument) as the signal 00079 hasChanged. 00080 00081 So, at the beginning, a signal must be defined which fixes the signature -- in our 00082 case the number and type of the input arguments. This can be easily done with 00083 templates. But, since the number of input arguments may vary, we need to specialize 00084 them. This is all done with(in) the Signal class. 00085 00086 With this information, appropriate connect functions are created. These are 00087 overloaded such that connecting to different slot types is possible. Slots may 00088 be global functions as well as static, non-static, constant, and non-constant 00089 member functions. We need to abstract these different types to be able to call 00090 them over the same interface. This is done with functors (GlobalFunctionSlot, 00091 MemberFunctionSlot, etc.) which are basically functions with an internal state. 00092 These are all derived from the same interface (SlotBase) whereupon we have to take 00093 into account the various numbers of input parameters (hence again the specialized 00094 Slot classes). 00095 00096 Managing the connections is done in the SignalBase class. Since all slots are 00097 derived from SlotBase, we can easily store pointers of this class. This way, we 00098 do not have to cope with different signatures. Calling a slot is done in the 00099 derived class, so that (after back casting) an appropriate call is easily possible. 00100 00101 SignalBase interacts with the Receiver class. If a class is derived from Receiver, 00102 disconnecting the slots is done fully automatically (this covers the destruction of 00103 signals or objects derived from the Receiver class as well as ordinary 00104 disconnections). 00105 00106 This is, basically, the overall logic. Everything around is more or less glue code. 00107 00108 One thing shall be noted, yet: Casting arbitrary pointers to void * is not possible 00109 with all compilers (in fact, it is not standard C++), since their implementation size 00110 might vary. For instance, a member function pointer might save the address to its 00111 member function plus an additional object address. That is why conversions between 00112 ordinary function pointers and member function pointers is not allowed. A way out of 00113 this is to use a field of characters and to copy the function addresses by using 00114 memcpy(). 00115 00116 Addendum: 00117 00118 All methods of the Signal class as well as of the Receiver class were changed to 00119 be constant. This allows constant member functions of classes that hold various 00120 instances of Signal to emit theses signals. To be able to do this, our class 00121 members must be declared mutable. In addition, it is now possible to connect slots 00122 to signals of constant classes. 00123 00124 Update: 00125 00126 A translation layer was added to be able to connect to signatures whose elements 00127 are compatible to that of the signal. That is, now, you can connect integers to 00128 doubles and vice versa; an implicit conversion is performed. 00129 00130 So the class hierarchy is as follows: 00131 00132 Slot classes abstract different function types and provide a unified call interface. 00133 00134 SlotBase 00135 Slot<> 00136 GlobalFunctionSlot<> 00137 MemberFunctionSlot<> 00138 ConstMemberFunction<> 00139 00140 Adapter classes allow for calling slots with a slightly different signature. 00141 The adapters store the needed type casts internally. This allows for performing 00142 calls if not all information is available (e.g. when casting base class pointers 00143 while only the caller-side's signature [i.e. the signal signature] is known). 00144 00145 SlotAdapterBase 00146 SlotAdapter<> 00147 ConcreteSlotAdapter<> 00148 00149 Signals store and manage slot connections and they provide call interfaces to 00150 the internally stored slots. In conjunction with the Receiver class an automatic 00151 disconnection mechanism is provieded. 00152 00153 SignalBase 00154 Signal<> 00155 00156 Receiver 00157 00158 Now, instead of directly dealing with Slots (i.e. storing SlotBase pointers) the 00159 signal classes deal with slot adapters (pointers to the SlotAdapterBase class). 00160 00161 */ 00162 00163 00164 namespace TRTK 00165 { 00166 00167 00172 namespace Signals 00173 { 00174 00175 00176 using TRTK::Tools::isDerivedFrom; 00177 00178 00179 class SignalBase; 00180 class SlotAdapterBase; 00181 00182 00184 // Receiver // 00186 00187 00188 // Classes that are derived from Receiver automatically inform signals, when 00189 // the classes are destroyed. This avoids dangling function pointers, if a 00190 // connection has not been disconnected manually (well, and it is way more 00191 // comfortable...). 00192 00193 class Receiver 00194 { 00195 public: 00196 00197 Receiver(); 00198 00199 // Informs all signals, which are connected to a class derived from Receiver, 00200 // from its destruction. 00201 00202 virtual ~Receiver(); 00203 00204 // If a signal is connected to a class derived from Receiver, it calls this function. 00205 00206 void notifyConnection(const SignalBase * signal, SlotAdapterBase * slot) const; 00207 00208 // If a signal connected to a class derived from Receiver is destroyed, it calls this function. 00209 00210 void notifyDisconnection(const SignalBase * signal) const; 00211 00212 // This function (and its overloaded counterpart) extracts the pointer to the receiver 00213 // class if 'pointer' is derived from it. In all other cases NULL is returned. 00214 00215 static const Receiver * getAddress(const Receiver * pointer) 00216 { 00217 return pointer; 00218 } 00219 00220 static const Receiver * getAddress(const void *) 00221 { 00222 return NULL; 00223 } 00224 00225 private: 00226 00227 mutable std::list<std::pair<const SignalBase *, SlotAdapterBase *> > m_connected_signals; 00228 }; 00229 00230 00232 // SlotBase and Slot // 00234 00235 00236 // WARNING: The size of a member function pointer is compiler specific and can 00237 // even differ between function pointers of classes that use or do not use multiple 00238 // inheritance. Thus, to be able to compare different function pointers, we use 00239 // a big enough character array to store them. Still, the question is, what is the 00240 // right size? It turned out, that using the size of a member function pointer of 00241 // a class with multiple inheritance works with most/all compilers, since these 00242 // pointers store most information and thus are the biggest ones. If this does not 00243 // work, just increase the size of MAX_MEMBER_FUNCTION_SIZE. 00244 00245 00246 class Base1 00247 { 00248 public: 00249 Base1() {}; 00250 virtual ~Base1() {}; 00251 }; 00252 00253 00254 class Base2 00255 { 00256 public: 00257 Base2() {}; 00258 virtual ~Base2() {}; 00259 }; 00260 00261 00262 class FunctionPointerTraits : public Base1, virtual public Base2 00263 { 00264 FunctionPointerTraits() {} 00265 virtual ~FunctionPointerTraits() {} 00266 00267 typedef void (FunctionPointerTraits::*mem_func_ptr)(); 00268 00269 public: 00270 enum {MAX_FUNCTION_POINTER_SIZE = sizeof(mem_func_ptr)}; 00271 }; 00272 00273 00274 class SlotBase 00275 { 00276 public: 00277 00278 SlotBase(); 00279 virtual ~SlotBase() {}; 00280 00281 // Shall return the function pointer to a member function or NULL in the 00282 // case of global functions. 00283 00284 virtual const char * getClassFunction() const {return NULL;} 00285 00286 // Shall return the function pointer to a global function or NULL in the 00287 // case of member functions. 00288 00289 virtual const char * getGlobalFunction() const {return NULL;} 00290 00291 // Shall return the object address or NULL in the case of global functions. 00292 00293 virtual const void * getObject() const {return NULL;} 00294 00295 // If the slot points to a member function and the object is derived from 00296 // Receiver, this function shall return true. 00297 00298 virtual bool isReceiver() const {return false;} 00299 00300 // If an object associated with a slot is derived from Receiver this function 00301 // shall return the receiver address and otherwise NULL. 00302 00303 virtual const Receiver * getReceiver() const {return NULL;} 00304 00305 enum {MAX_FUNCTION_POINTER_SIZE = FunctionPointerTraits::MAX_FUNCTION_POINTER_SIZE}; 00306 00307 protected: 00308 00309 char function_address[MAX_FUNCTION_POINTER_SIZE]; 00310 }; 00311 00312 00313 bool operator==(const SlotBase & x, const SlotBase & y); 00314 00315 00316 00317 // four arguments specified 00318 00319 template <typename arg1_type = void, typename arg2_type = void, typename arg3_type = void, typename arg4_type = void> 00320 class Slot : public SlotBase 00321 { 00322 public: 00323 00324 // Use this function to call the appropriate slot. 00325 00326 virtual void callFunction(arg1_type, arg2_type, arg3_type, arg4_type) = 0; 00327 }; 00328 00329 00330 // three arguments specified 00331 00332 template <typename arg1_type, typename arg2_type, typename arg3_type> 00333 class Slot<arg1_type, arg2_type, arg3_type, void> : public SlotBase 00334 { 00335 public: 00336 00337 // Use this function to call the appropriate slot. 00338 00339 virtual void callFunction(arg1_type, arg2_type, arg3_type) = 0; 00340 }; 00341 00342 00343 // two arguments specified 00344 00345 template <typename arg1_type, typename arg2_type> 00346 class Slot<arg1_type, arg2_type, void, void> : public SlotBase 00347 { 00348 public: 00349 00350 // Use this function to call the appropriate slot. 00351 00352 virtual void callFunction(arg1_type, arg2_type) = 0; 00353 }; 00354 00355 00356 // one argument specified 00357 00358 template <typename arg1_type> 00359 class Slot<arg1_type, void, void, void> : public SlotBase 00360 { 00361 public: 00362 00363 // Use this function to call the appropriate slot. 00364 00365 virtual void callFunction(arg1_type) = 0; 00366 }; 00367 00368 00369 // no argument specified 00370 00371 template <> 00372 class Slot<void, void, void, void> : public SlotBase 00373 { 00374 public: 00375 00376 // Use this function to call the appropriate slot. 00377 00378 virtual void callFunction(void) = 0; 00379 }; 00380 00381 00383 // GlobalFunctionSlot // 00385 00386 00387 // four arguments specified 00388 00389 template <typename return_type, typename arg1_type = void, typename arg2_type = void, typename arg3_type = void, typename arg4_type = void> 00390 class GlobalFunctionSlot : public Slot<arg1_type, arg2_type, arg3_type, arg4_type> 00391 { 00392 public: 00393 typedef return_type (*function_ptr)(arg1_type, arg2_type, arg3_type, arg4_type); 00394 00395 GlobalFunctionSlot(function_ptr function) 00396 { 00397 // store function pointer 00398 memcpy(SlotBase::function_address, &function, sizeof(function)); 00399 } 00400 00401 void callFunction(arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4) 00402 { 00403 // restore function pointer 00404 function_ptr function; 00405 memcpy(&function, SlotBase::function_address, sizeof(function)); 00406 00407 (*function)(arg1, arg2, arg3, arg4); 00408 } 00409 00410 const char * getGlobalFunction() const 00411 { 00412 return SlotBase::function_address; 00413 } 00414 }; 00415 00416 00417 // three arguments specified 00418 00419 template <typename return_type, typename arg1_type, typename arg2_type, typename arg3_type> 00420 class GlobalFunctionSlot<return_type, arg1_type, arg2_type, arg3_type, void> : public Slot<arg1_type, arg2_type, arg3_type> 00421 { 00422 public: 00423 typedef return_type (*function_ptr)(arg1_type, arg2_type, arg3_type); 00424 00425 GlobalFunctionSlot(function_ptr function) 00426 { 00427 // store function pointer 00428 memcpy(SlotBase::function_address, &function, sizeof(function)); 00429 } 00430 00431 void callFunction(arg1_type arg1, arg2_type arg2, arg3_type arg3) 00432 { 00433 // restore function pointer 00434 function_ptr function; 00435 memcpy(&function, SlotBase::function_address, sizeof(function)); 00436 00437 (*function)(arg1, arg2, arg3); 00438 } 00439 00440 const char * getGlobalFunction() const 00441 { 00442 return SlotBase::function_address; 00443 } 00444 }; 00445 00446 00447 // two arguments specified 00448 00449 template <typename return_type, typename arg1_type, typename arg2_type> 00450 class GlobalFunctionSlot<return_type, arg1_type, arg2_type, void, void> : public Slot<arg1_type, arg2_type> 00451 { 00452 public: 00453 typedef return_type (*function_ptr)(arg1_type, arg2_type); 00454 00455 GlobalFunctionSlot(function_ptr function) 00456 { 00457 // store function pointer 00458 memcpy(SlotBase::function_address, &function, sizeof(function)); 00459 } 00460 00461 void callFunction(arg1_type arg1, arg2_type arg2) 00462 { 00463 // restore function pointer 00464 function_ptr function; 00465 memcpy(&function, SlotBase::function_address, sizeof(function)); 00466 00467 (*function)(arg1, arg2); 00468 } 00469 00470 const char * getGlobalFunction() const 00471 { 00472 return SlotBase::function_address; 00473 } 00474 }; 00475 00476 00477 // one argument specified 00478 00479 template <typename return_type, typename arg1_type> 00480 class GlobalFunctionSlot<return_type, arg1_type, void, void, void> : public Slot<arg1_type> 00481 { 00482 public: 00483 typedef return_type (*function_ptr)(arg1_type); 00484 00485 GlobalFunctionSlot(function_ptr function) 00486 { 00487 // store function pointer 00488 memcpy(SlotBase::function_address, &function, sizeof(function)); 00489 } 00490 00491 void callFunction(arg1_type arg1) 00492 { 00493 // restore function pointer 00494 function_ptr function; 00495 memcpy(&function, SlotBase::function_address, sizeof(function)); 00496 00497 (*function)(arg1); 00498 } 00499 00500 const char * getGlobalFunction() const 00501 { 00502 return SlotBase::function_address; 00503 } 00504 }; 00505 00506 00507 // no argument specified 00508 00509 template <typename return_type> 00510 class GlobalFunctionSlot<return_type, void> : public Slot<void> 00511 { 00512 public: 00513 typedef return_type (*function_ptr)(); 00514 00515 GlobalFunctionSlot(function_ptr function) 00516 { 00517 // store function pointer 00518 memcpy(SlotBase::function_address, &function, sizeof(function)); 00519 } 00520 00521 void callFunction() 00522 { 00523 // restore function pointer 00524 function_ptr function; 00525 memcpy(&function, SlotBase::function_address, sizeof(function)); 00526 00527 (*function)(); 00528 } 00529 00530 const char * getGlobalFunction() const 00531 { 00532 return SlotBase::function_address; 00533 } 00534 }; 00535 00536 00538 // MemberFunctionSlot // 00540 00541 00542 // four arguments specified 00543 00544 template <typename class_type, typename return_type, typename arg1_type = void, typename arg2_type = void, typename arg3_type = void, typename arg4_type = void> 00545 class MemberFunctionSlot : public Slot<arg1_type, arg2_type, arg3_type, arg4_type> 00546 { 00547 public: 00548 typedef return_type (class_type::*function_ptr)(arg1_type, arg2_type, arg3_type, arg4_type); 00549 00550 MemberFunctionSlot(class_type * object, function_ptr function) : object(object) 00551 { 00552 // store function pointer 00553 memcpy(SlotBase::function_address, &function, sizeof(function)); 00554 }; 00555 00556 void callFunction(arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4) 00557 { 00558 // restore function pointer 00559 function_ptr function; 00560 memcpy(&function, SlotBase::function_address, sizeof(function)); 00561 00562 (object->*function)(arg1, arg2, arg3, arg4); 00563 } 00564 00565 const char * getClassFunction() const 00566 { 00567 return SlotBase::function_address; 00568 } 00569 00570 const void * getObject() const 00571 { 00572 return object; 00573 } 00574 00575 const Receiver * getReceiver() const 00576 { 00577 return Receiver::getAddress(object); 00578 } 00579 00580 private: 00581 class_type * object; 00582 }; 00583 00584 00585 // three arguments specified 00586 00587 template <typename class_type, typename return_type, typename arg1_type, typename arg2_type, typename arg3_type> 00588 class MemberFunctionSlot<class_type, return_type, arg1_type, arg2_type, arg3_type, void> : public Slot<arg1_type, arg2_type, arg3_type> 00589 { 00590 public: 00591 typedef return_type (class_type::*function_ptr)(arg1_type, arg2_type, arg3_type); 00592 00593 MemberFunctionSlot(class_type * object, function_ptr function) : object(object) 00594 { 00595 // store function pointer 00596 memcpy(SlotBase::function_address, &function, sizeof(function)); 00597 }; 00598 00599 void callFunction(arg1_type arg1, arg2_type arg2, arg3_type arg3) 00600 { 00601 // restore function pointer 00602 function_ptr function; 00603 memcpy(&function, SlotBase::function_address, sizeof(function)); 00604 00605 (object->*function)(arg1, arg2, arg3); 00606 } 00607 00608 const char * getClassFunction() const 00609 { 00610 return SlotBase::function_address; 00611 } 00612 00613 const void * getObject() const 00614 { 00615 return object; 00616 } 00617 00618 const Receiver * getReceiver() const 00619 { 00620 return Receiver::getAddress(object); 00621 } 00622 00623 private: 00624 class_type * object; 00625 }; 00626 00627 00628 // two arguments specified 00629 00630 template <typename class_type, typename return_type, typename arg1_type, typename arg2_type> 00631 class MemberFunctionSlot<class_type, return_type, arg1_type, arg2_type, void, void> : public Slot<arg1_type, arg2_type> 00632 { 00633 public: 00634 typedef return_type (class_type::*function_ptr)(arg1_type, arg2_type); 00635 00636 MemberFunctionSlot(class_type * object, function_ptr function) : object(object) 00637 { 00638 // store function pointer 00639 memcpy(SlotBase::function_address, &function, sizeof(function)); 00640 }; 00641 00642 void callFunction(arg1_type arg1, arg2_type arg2) 00643 { 00644 // restore function pointer 00645 function_ptr function; 00646 memcpy(&function, SlotBase::function_address, sizeof(function)); 00647 00648 (object->*function)(arg1, arg2); 00649 } 00650 00651 const char * getClassFunction() const 00652 { 00653 return SlotBase::function_address; 00654 } 00655 00656 const void * getObject() const 00657 { 00658 return object; 00659 } 00660 00661 const Receiver * getReceiver() const 00662 { 00663 return Receiver::getAddress(object); 00664 } 00665 00666 00667 private: 00668 class_type * object; 00669 }; 00670 00671 00672 // one argument specified 00673 00674 template <typename class_type, typename return_type, typename arg1_type> 00675 class MemberFunctionSlot<class_type, return_type, arg1_type, void, void, void> : public Slot<arg1_type> 00676 { 00677 public: 00678 typedef return_type (class_type::*function_ptr)(arg1_type); 00679 00680 MemberFunctionSlot(class_type * object, function_ptr function) : object(object) 00681 { 00682 // store function pointer 00683 memcpy(SlotBase::function_address, &function, sizeof(function)); 00684 }; 00685 00686 void callFunction(arg1_type arg1) 00687 { 00688 // restore function pointer 00689 function_ptr function; 00690 memcpy(&function, SlotBase::function_address, sizeof(function)); 00691 00692 (object->*function)(arg1); 00693 } 00694 00695 const char * getClassFunction() const 00696 { 00697 return SlotBase::function_address; 00698 } 00699 00700 const void * getObject() const 00701 { 00702 return object; 00703 } 00704 00705 const Receiver * getReceiver() const 00706 { 00707 return Receiver::getAddress(object); 00708 } 00709 00710 private: 00711 class_type * object; 00712 }; 00713 00714 00715 // no argument specified 00716 00717 template <typename class_type, typename return_type> 00718 class MemberFunctionSlot<class_type, return_type, void, void, void, void> : public Slot<void> 00719 { 00720 public: 00721 typedef return_type (class_type::*function_ptr)(); 00722 00723 MemberFunctionSlot(class_type * object, function_ptr function) : object(object) 00724 { 00725 // store function pointer 00726 memcpy(SlotBase::function_address, &function, sizeof(function)); 00727 }; 00728 00729 void callFunction() 00730 { 00731 // restore function pointer 00732 function_ptr function; 00733 memcpy(&function, SlotBase::function_address, sizeof(function)); 00734 00735 (object->*function)(); 00736 } 00737 00738 const char * getClassFunction() const 00739 { 00740 return SlotBase::function_address; 00741 } 00742 00743 const void * getObject() const 00744 { 00745 return object; 00746 } 00747 00748 const Receiver * getReceiver() const 00749 { 00750 return Receiver::getAddress(object); 00751 } 00752 00753 private: 00754 class_type * object; 00755 }; 00756 00757 00759 // ConstMemberFunctionSlot // 00761 00762 00763 // four arguments specified 00764 00765 template <typename class_type, typename return_type, typename arg1_type = void, typename arg2_type = void, typename arg3_type = void, typename arg4_type = void> 00766 class ConstMemberFunctionSlot : public Slot<arg1_type, arg2_type, arg3_type, arg4_type> 00767 { 00768 public: 00769 typedef return_type (class_type::*function_ptr)(arg1_type, arg2_type, arg3_type, arg4_type) const; 00770 00771 ConstMemberFunctionSlot(const class_type * object, function_ptr function) : object(object) 00772 { 00773 // store function pointer 00774 memcpy(SlotBase::function_address, &function, sizeof(function)); 00775 }; 00776 00777 void callFunction(arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4) 00778 { 00779 // restore function pointer 00780 function_ptr function; 00781 memcpy(&function, SlotBase::function_address, sizeof(function)); 00782 00783 (object->*function)(arg1, arg2, arg3, arg4); 00784 } 00785 00786 const char * getClassFunction() const 00787 { 00788 return SlotBase::function_address; 00789 } 00790 00791 const void * getObject() const 00792 { 00793 return object; 00794 } 00795 00796 const Receiver * getReceiver() const 00797 { 00798 return Receiver::getAddress(object); 00799 } 00800 00801 private: 00802 const class_type * object; 00803 }; 00804 00805 00806 // three arguments specified 00807 00808 template <typename class_type, typename return_type, typename arg1_type, typename arg2_type, typename arg3_type> 00809 class ConstMemberFunctionSlot<class_type, return_type, arg1_type, arg2_type, arg3_type, void> : public Slot<arg1_type, arg2_type, arg3_type> 00810 { 00811 public: 00812 typedef return_type (class_type::*function_ptr)(arg1_type, arg2_type, arg3_type) const; 00813 00814 ConstMemberFunctionSlot(const class_type * object, function_ptr function) : object(object) 00815 { 00816 // store function pointer 00817 memcpy(SlotBase::function_address, &function, sizeof(function)); 00818 }; 00819 00820 void callFunction(arg1_type arg1, arg2_type arg2, arg3_type arg3) 00821 { 00822 // restore function pointer 00823 function_ptr function; 00824 memcpy(&function, SlotBase::function_address, sizeof(function)); 00825 00826 (object->*function)(arg1, arg2, arg3); 00827 } 00828 00829 const char * getClassFunction() const 00830 { 00831 return SlotBase::function_address; 00832 } 00833 00834 const void * getObject() const 00835 { 00836 return object; 00837 } 00838 00839 const Receiver * getReceiver() const 00840 { 00841 return Receiver::getAddress(object); 00842 } 00843 00844 private: 00845 const class_type * object; 00846 }; 00847 00848 00849 // two arguments specified 00850 00851 template <typename class_type, typename return_type, typename arg1_type, typename arg2_type> 00852 class ConstMemberFunctionSlot<class_type, return_type, arg1_type, arg2_type, void, void> : public Slot<arg1_type, arg2_type> 00853 { 00854 public: 00855 typedef return_type (class_type::*function_ptr)(arg1_type, arg2_type) const; 00856 00857 ConstMemberFunctionSlot(const class_type * object, function_ptr function) : object(object) 00858 { 00859 // store function pointer 00860 memcpy(SlotBase::function_address, &function, sizeof(function)); 00861 }; 00862 00863 void callFunction(arg1_type arg1, arg2_type arg2) 00864 { 00865 // restore function pointer 00866 function_ptr function; 00867 memcpy(&function, SlotBase::function_address, sizeof(function)); 00868 00869 (object->*function)(arg1, arg2); 00870 } 00871 00872 const char * getClassFunction() const 00873 { 00874 return SlotBase::function_address; 00875 } 00876 00877 const void * getObject() const 00878 { 00879 return object; 00880 } 00881 00882 const Receiver * getReceiver() const 00883 { 00884 return Receiver::getAddress(object); 00885 } 00886 00887 00888 private: 00889 const class_type * object; 00890 }; 00891 00892 00893 // one argument specified 00894 00895 template <typename class_type, typename return_type, typename arg1_type> 00896 class ConstMemberFunctionSlot<class_type, return_type, arg1_type, void, void, void> : public Slot<arg1_type> 00897 { 00898 public: 00899 typedef return_type (class_type::*function_ptr)(arg1_type) const; 00900 00901 ConstMemberFunctionSlot(const class_type * object, function_ptr function) : object(object) 00902 { 00903 // store function pointer 00904 memcpy(SlotBase::function_address, &function, sizeof(function)); 00905 }; 00906 00907 void callFunction(arg1_type arg1) 00908 { 00909 // restore function pointer 00910 function_ptr function; 00911 memcpy(&function, SlotBase::function_address, sizeof(function)); 00912 00913 (object->*function)(arg1); 00914 } 00915 00916 const char * getClassFunction() const 00917 { 00918 return SlotBase::function_address; 00919 } 00920 00921 const void * getObject() const 00922 { 00923 return object; 00924 } 00925 00926 const Receiver * getReceiver() const 00927 { 00928 return Receiver::getAddress(object); 00929 } 00930 00931 private: 00932 const class_type * object; 00933 }; 00934 00935 00936 // no argument specified 00937 00938 template <typename class_type, typename return_type> 00939 class ConstMemberFunctionSlot<class_type, return_type, void, void, void, void> : public Slot<void> 00940 { 00941 public: 00942 typedef return_type (class_type::*function_ptr)() const; 00943 00944 ConstMemberFunctionSlot(const class_type * object, function_ptr function) : object(object) 00945 { 00946 // store function pointer 00947 memcpy(SlotBase::function_address, &function, sizeof(function)); 00948 }; 00949 00950 void callFunction() 00951 { 00952 // restore function pointer 00953 function_ptr function; 00954 memcpy(&function, SlotBase::function_address, sizeof(function)); 00955 00956 (object->*function)(); 00957 } 00958 00959 const char * getClassFunction() const 00960 { 00961 return SlotBase::function_address; 00962 } 00963 00964 const void * getObject() const 00965 { 00966 return object; 00967 } 00968 00969 const Receiver * getReceiver() const 00970 { 00971 return Receiver::getAddress(object); 00972 } 00973 00974 private: 00975 const class_type * object; 00976 }; 00977 00978 00980 // Slot Adapters // 00982 00983 00984 class SlotAdapterBase 00985 { 00986 public: 00987 SlotAdapterBase() : slot(NULL) 00988 { 00989 } 00990 00991 virtual ~SlotAdapterBase() 00992 { 00993 } 00994 00995 const char * getClassFunction() const 00996 { 00997 assert(slot != NULL); 00998 return slot->getClassFunction(); 00999 } 01000 01001 const char * getGlobalFunction() const 01002 { 01003 assert(slot != NULL); 01004 return slot->getGlobalFunction(); 01005 } 01006 01007 virtual unsigned getNumberOfArguments() const = 0; 01008 01009 const void * getObject() const 01010 { 01011 assert(slot != NULL); 01012 return slot->getObject(); 01013 } 01014 01015 const Receiver * getReceiver() const 01016 { 01017 assert(slot != NULL); 01018 return slot->getReceiver(); 01019 } 01020 01021 bool operator==(const SlotAdapterBase & other) 01022 { 01023 assert(slot != NULL); 01024 return *slot == *other.slot; 01025 } 01026 01027 protected: 01028 SlotBase * slot; 01029 }; 01030 01031 01032 // four arguments specified 01033 01034 template <typename arg1_type = void, typename arg2_type = void, typename arg3_type = void, typename arg4_type = void> 01035 class SlotAdapter : public SlotAdapterBase 01036 { 01037 public: 01038 virtual void callFunction(arg1_type, arg2_type, arg3_type, arg4_type) = 0; 01039 }; 01040 01041 01042 // three arguments specified 01043 01044 template <typename arg1_type, typename arg2_type, typename arg3_type> 01045 class SlotAdapter<arg1_type, arg2_type, arg3_type, void> : public SlotAdapterBase 01046 { 01047 public: 01048 virtual void callFunction(arg1_type, arg2_type, arg3_type) = 0; 01049 }; 01050 01051 01052 // two arguments specified 01053 01054 template <typename arg1_type, typename arg2_type> 01055 class SlotAdapter<arg1_type, arg2_type, void, void> : public SlotAdapterBase 01056 { 01057 public: 01058 virtual void callFunction(arg1_type, arg2_type) = 0; 01059 }; 01060 01061 01062 // one argument specified 01063 01064 template <typename arg1_type> 01065 class SlotAdapter<arg1_type, void, void, void> : public SlotAdapterBase 01066 { 01067 public: 01068 virtual void callFunction(arg1_type) = 0; 01069 }; 01070 01071 01072 // zero arguments specified 01073 01074 template <> 01075 class SlotAdapter<void, void, void, void> : public SlotAdapterBase 01076 { 01077 public: 01078 virtual void callFunction() = 0; 01079 }; 01080 01081 01082 // four arguments specified 01083 01084 template <typename arg1_type = void, typename arg2_type = void, typename arg3_type = void, typename arg4_type = void, 01085 typename slot_arg1_type = void, typename slot_arg2_type = void, typename slot_arg3_type = void, typename slot_arg4_type = void> 01086 class ConcreteSlotAdapter : public SlotAdapter<arg1_type, arg2_type, arg3_type, arg4_type> 01087 { 01088 public: 01089 typedef Slot<slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type> * slot_ptr; 01090 01091 // ConcreteSlotAdapter takes the ownership of 'slot'. 01092 01093 ConcreteSlotAdapter(slot_ptr slot) 01094 { 01095 SlotAdapterBase::slot = slot; 01096 } 01097 01098 ~ConcreteSlotAdapter() 01099 { 01100 delete SlotAdapterBase::slot; 01101 } 01102 01103 void callFunction(arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4) 01104 { 01105 static_cast<slot_ptr>(SlotAdapterBase::slot)->callFunction(static_cast<slot_arg1_type>(arg1), 01106 static_cast<slot_arg2_type>(arg2), 01107 static_cast<slot_arg3_type>(arg3), 01108 static_cast<slot_arg4_type>(arg4)); 01109 } 01110 01111 unsigned getNumberOfArguments() const 01112 { 01113 return 4; 01114 } 01115 }; 01116 01117 01118 // three arguments specified 01119 01120 template <typename arg1_type, typename arg2_type, typename arg3_type, 01121 typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 01122 class ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> 01123 : public SlotAdapter<arg1_type, arg2_type, arg3_type> 01124 { 01125 public: 01126 typedef Slot<slot_arg1_type, slot_arg2_type, slot_arg3_type> * slot_ptr; 01127 01128 // ConcreteSlotAdapter takes the ownership of 'slot'. 01129 01130 ConcreteSlotAdapter(slot_ptr slot) 01131 { 01132 SlotAdapterBase::slot = slot; 01133 } 01134 01135 ~ConcreteSlotAdapter() 01136 { 01137 delete SlotAdapterBase::slot; 01138 } 01139 01140 void callFunction(arg1_type arg1, arg2_type arg2, arg3_type arg3) 01141 { 01142 static_cast<slot_ptr>(SlotAdapterBase::slot)->callFunction(static_cast<slot_arg1_type>(arg1), 01143 static_cast<slot_arg2_type>(arg2), 01144 static_cast<slot_arg3_type>(arg3)); 01145 } 01146 01147 unsigned getNumberOfArguments() const 01148 { 01149 return 3; 01150 } 01151 }; 01152 01153 01154 // two arguments specified 01155 01156 template <typename arg1_type, typename arg2_type, typename slot_arg1_type, typename slot_arg2_type> 01157 class ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> 01158 : public SlotAdapter<arg1_type, arg2_type> 01159 { 01160 public: 01161 typedef Slot<slot_arg1_type, slot_arg2_type> * slot_ptr; 01162 01163 // ConcreteSlotAdapter takes the ownership of 'slot'. 01164 01165 ConcreteSlotAdapter(slot_ptr slot) 01166 { 01167 SlotAdapterBase::slot = slot; 01168 } 01169 01170 ~ConcreteSlotAdapter() 01171 { 01172 delete SlotAdapterBase::slot; 01173 } 01174 01175 void callFunction(arg1_type arg1, arg2_type arg2) 01176 { 01177 static_cast<slot_ptr>(SlotAdapterBase::slot)->callFunction(static_cast<slot_arg1_type>(arg1), static_cast<slot_arg2_type>(arg2)); 01178 } 01179 01180 unsigned getNumberOfArguments() const 01181 { 01182 return 2; 01183 } 01184 }; 01185 01186 01187 // one argument specified 01188 01189 template <typename arg1_type, typename slot_arg1_type> 01190 class ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> 01191 : public SlotAdapter<arg1_type> 01192 { 01193 public: 01194 typedef Slot<slot_arg1_type> * slot_ptr; 01195 01196 // ConcreteSlotAdapter takes the ownership of 'slot'. 01197 01198 ConcreteSlotAdapter(slot_ptr slot) 01199 { 01200 SlotAdapterBase::slot = slot; 01201 } 01202 01203 ~ConcreteSlotAdapter() 01204 { 01205 delete SlotAdapterBase::slot; 01206 } 01207 01208 void callFunction(arg1_type arg1) 01209 { 01210 static_cast<slot_ptr>(SlotAdapterBase::slot)->callFunction(static_cast<slot_arg1_type>(arg1)); 01211 } 01212 01213 unsigned getNumberOfArguments() const 01214 { 01215 return 1; 01216 } 01217 }; 01218 01219 01220 // zero arguments specified 01221 01222 template <> 01223 class ConcreteSlotAdapter<void, void, void, void, void, void, void, void> 01224 : public SlotAdapter<> 01225 { 01226 public: 01227 typedef Slot<> * slot_ptr; 01228 01229 // ConcreteSlotAdapter takes the ownership of 'slot'. 01230 01231 ConcreteSlotAdapter(slot_ptr slot) 01232 { 01233 SlotAdapterBase::slot = slot; 01234 } 01235 01236 ~ConcreteSlotAdapter() 01237 { 01238 delete SlotAdapterBase::slot; 01239 } 01240 01241 void callFunction() 01242 { 01243 static_cast<slot_ptr>(SlotAdapterBase::slot)->callFunction(); 01244 } 01245 01246 unsigned getNumberOfArguments() const 01247 { 01248 return 0; 01249 } 01250 }; 01251 01252 01254 // ConnectionType // 01256 01257 01267 enum ConnectionType 01268 { 01269 MULTIPLE_CONNECTIONS, 01270 SINGLE_CONNECTION 01271 }; 01272 01273 01275 // SignalBase // 01277 01278 01279 class SignalBase 01280 { 01281 public: 01282 01283 SignalBase() {} 01284 01285 virtual ~SignalBase() 01286 { 01287 // Inform classes that are derived from 'Receiver' that the signal has been destroyed. 01288 01289 std::set<const Receiver *>::iterator it; 01290 01291 for (it = m_receivers.begin(); it != m_receivers.end(); ++it) 01292 { 01293 (*it)->notifyDisconnection(this); 01294 } 01295 01296 // Delete all stored slots. 01297 01298 std::list<SlotAdapterBase *>::iterator slot_it = m_slots.begin(); 01299 01300 while (slot_it != m_slots.end()) 01301 { 01302 delete *slot_it; 01303 m_slots.erase(slot_it++); 01304 } 01305 } 01306 01307 // Save/manage the connection to a signal. 01308 // Note: The deletion of the input argument slot is managed by SignalBase. 01309 01310 void connect(SlotAdapterBase * slot, const ConnectionType connection_type = SINGLE_CONNECTION) const 01311 { 01312 switch (connection_type) 01313 { 01314 case MULTIPLE_CONNECTIONS: 01315 // Fall through... 01316 break; 01317 01318 case SINGLE_CONNECTION: 01319 if (isConnected(slot)) 01320 { 01321 return; 01322 } 01323 else 01324 { 01325 // Fall through... 01326 } 01327 break; 01328 01329 default: 01330 throw std::logic_error("SignalBase::connect(): Unknown connection type."); 01331 break; 01332 } 01333 01334 m_slots.push_back(slot); 01335 01336 // Notify 'Receiver' objects about the connection. 01337 01338 if (slot->getReceiver()) 01339 { 01340 const Receiver * receiver = slot->getReceiver(); 01341 m_receivers.insert(receiver); 01342 receiver->notifyConnection(this, slot); 01343 } 01344 } 01345 01346 // Deletes the last added entry in the case of SINGLE_CONNECTION. 01347 // Deletes all entries in the case of MULTIPLE_CONNECTIONS. 01348 01349 void disconnect(SlotAdapterBase * slot, const ConnectionType connection_type = SINGLE_CONNECTION) const 01350 { 01351 // Delete slot(s). 01352 01353 std::list<SlotAdapterBase *>::reverse_iterator rit = m_slots.rbegin(); 01354 01355 while (rit != m_slots.rend()) 01356 { 01357 if (**rit == *slot) 01358 { 01359 delete *rit; 01360 rit.base() = m_slots.erase(--rit.base()); 01361 01362 if (connection_type == SINGLE_CONNECTION) 01363 { 01364 break; 01365 } 01366 } 01367 else 01368 { 01369 ++rit; 01370 } 01371 } 01372 01373 // Update the set of 'Receiver' objects. 01374 01375 // There may be connections to other slots of the receiver object, hence 01376 // check how many are left and erase the receiver from the internal set 01377 // if necessary. Also notify the receiver object if applicable. 01378 01379 const Receiver * receiver = slot->getReceiver(); 01380 01381 if (receiver) 01382 { 01383 bool any_connections = false; // are there any connections left to the receiver object 01384 01385 std::list<SlotAdapterBase *>::iterator it; 01386 01387 for (it = m_slots.begin(); it != m_slots.end(); ++it) 01388 { 01389 if ((*it)->getReceiver() == receiver) 01390 { 01391 any_connections = true; 01392 break; 01393 } 01394 } 01395 01396 if (!any_connections) 01397 { 01398 m_receivers.erase(receiver); 01399 receiver->notifyDisconnection(this); 01400 } 01401 } 01402 } 01403 01404 // This function is called by 'Receiver' objects during their destruction 01405 // (automatic slot removal). 01406 01407 void disconnectReceiver(const SlotAdapterBase * slot) const 01408 { 01409 std::list<SlotAdapterBase *>::iterator it = m_slots.begin(); 01410 01411 while (it != m_slots.end()) 01412 { 01413 if (*it == slot) 01414 { 01415 it = m_slots.erase(it); 01416 break; 01417 } 01418 else 01419 { 01420 ++it; 01421 } 01422 } 01423 01424 m_receivers.erase(slot->getReceiver()); 01425 } 01426 01427 // Checks, whether a certain function/slot is already connected to this signal. 01428 01429 bool isConnected(const SlotAdapterBase * slot) const 01430 { 01431 std::list<SlotAdapterBase *>::const_iterator it; 01432 01433 for (it = m_slots.begin(); it != m_slots.end(); ++it) 01434 { 01435 if (**it == *slot) 01436 { 01437 return true; 01438 } 01439 } 01440 01441 return false; 01442 } 01443 01444 protected: 01445 01446 mutable std::list<SlotAdapterBase *> m_slots; 01447 mutable std::set<const Receiver *> m_receivers; 01448 }; 01449 01450 01452 // Signal // 01454 01455 01456 class Receiver; 01457 01652 // four arguments specified 01653 01654 01655 template <typename arg1_type = void, typename arg2_type = void, typename arg3_type = void, typename arg4_type = void> 01656 class Signal : public SignalBase 01657 { 01658 public: 01659 01660 Signal() {} 01661 virtual ~Signal() {} 01662 01676 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type, typename slot_arg4_type> 01677 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type), ConnectionType connection_type = SINGLE_CONNECTION) const 01678 { 01679 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, arg4_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type> slot_adapter_type; 01680 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type>(object, function)); 01681 super::connect(slot, connection_type); 01682 } 01683 01697 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 01698 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type), ConnectionType connection_type = SINGLE_CONNECTION) const 01699 { 01700 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 01701 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(object, function)); 01702 super::connect(slot, connection_type); 01703 } 01704 01718 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 01719 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 01720 { 01721 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 01722 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 01723 super::connect(slot, connection_type); 01724 } 01725 01739 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 01740 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 01741 { 01742 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 01743 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 01744 super::connect(slot, connection_type); 01745 } 01746 01760 template <typename slot_class_type, typename slot_return_type> 01761 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 01762 { 01763 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 01764 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 01765 super::connect(slot, connection_type); 01766 } 01767 01781 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type, typename slot_arg4_type> 01782 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 01783 { 01784 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, arg4_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type> slot_adapter_type; 01785 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type>(object, function)); 01786 super::connect(slot, connection_type); 01787 } 01788 01802 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 01803 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 01804 { 01805 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 01806 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(object, function)); 01807 super::connect(slot, connection_type); 01808 } 01809 01823 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 01824 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 01825 { 01826 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 01827 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 01828 super::connect(slot, connection_type); 01829 } 01830 01844 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 01845 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 01846 { 01847 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 01848 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 01849 super::connect(slot, connection_type); 01850 } 01851 01865 template <typename slot_class_type, typename slot_return_type> 01866 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 01867 { 01868 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 01869 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 01870 super::connect(slot, connection_type); 01871 } 01872 01885 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type, typename slot_arg4_type> 01886 void connect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type), ConnectionType connection_type = SINGLE_CONNECTION) const 01887 { 01888 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, arg4_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type> slot_adapter_type; 01889 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type>(function)); 01890 super::connect(slot, connection_type); 01891 } 01892 01905 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 01906 void connect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type), ConnectionType connection_type = SINGLE_CONNECTION) const 01907 { 01908 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 01909 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(function)); 01910 super::connect(slot, connection_type); 01911 } 01912 01925 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 01926 void connect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 01927 { 01928 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 01929 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type>(function)); 01930 super::connect(slot, connection_type); 01931 } 01932 01945 template <typename slot_return_type, typename slot_arg1_type> 01946 void connect(slot_return_type (*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 01947 { 01948 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 01949 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type>(function)); 01950 super::connect(slot, connection_type); 01951 } 01952 01965 template <typename slot_return_type> 01966 void connect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 01967 { 01968 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 01969 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 01970 super::connect(slot, connection_type); 01971 } 01972 01990 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type, typename slot_arg4_type> 01991 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type), ConnectionType connection_type = SINGLE_CONNECTION) const 01992 { 01993 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, arg4_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type> slot_adapter_type; 01994 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type>(object, function)); 01995 super::disconnect(slot, connection_type); 01996 delete slot; 01997 } 01998 02016 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 02017 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02018 { 02019 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 02020 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(object, function)); 02021 super::disconnect(slot, connection_type); 02022 delete slot; 02023 } 02024 02042 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02043 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02044 { 02045 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02046 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02047 super::disconnect(slot, connection_type); 02048 delete slot; 02049 } 02050 02068 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02069 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02070 { 02071 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02072 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02073 super::disconnect(slot, connection_type); 02074 delete slot; 02075 } 02076 02094 template <typename slot_class_type, typename slot_return_type> 02095 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02096 { 02097 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02098 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02099 super::disconnect(slot, connection_type); 02100 delete slot; 02101 } 02102 02120 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type, typename slot_arg4_type> 02121 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02122 { 02123 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, arg4_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type> slot_adapter_type; 02124 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type>(object, function)); 02125 super::disconnect(slot, connection_type); 02126 delete slot; 02127 } 02128 02146 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 02147 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02148 { 02149 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 02150 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(object, function)); 02151 super::disconnect(slot, connection_type); 02152 delete slot; 02153 } 02154 02172 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02173 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02174 { 02175 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02176 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02177 super::disconnect(slot, connection_type); 02178 delete slot; 02179 } 02180 02198 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02199 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02200 { 02201 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02202 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02203 super::disconnect(slot, connection_type); 02204 delete slot; 02205 } 02206 02224 template <typename slot_class_type, typename slot_return_type> 02225 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 02226 { 02227 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02228 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02229 super::disconnect(slot, connection_type); 02230 delete slot; 02231 } 02232 02249 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type, typename slot_arg4_type> 02250 void disconnect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02251 { 02252 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, arg4_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type> slot_adapter_type; 02253 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type, slot_arg4_type>(function)); 02254 super::disconnect(slot, connection_type); 02255 delete slot; 02256 } 02257 02274 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 02275 void disconnect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02276 { 02277 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 02278 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(function)); 02279 super::disconnect(slot, connection_type); 02280 delete slot; 02281 } 02282 02299 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02300 void disconnect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02301 { 02302 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02303 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type>(function)); 02304 super::disconnect(slot, connection_type); 02305 delete slot; 02306 } 02307 02324 template <typename slot_return_type, typename slot_arg1_type> 02325 void disconnect(slot_return_type (*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02326 { 02327 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02328 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type>(function)); 02329 super::disconnect(slot, connection_type); 02330 delete slot; 02331 } 02332 02349 template <typename slot_return_type> 02350 void disconnect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02351 { 02352 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02353 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 02354 super::disconnect(slot, connection_type); 02355 delete slot; 02356 } 02357 02380 void send(arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4) const 02381 { 02382 std::list<SlotAdapterBase *>::iterator it; 02383 02384 for (it = super::m_slots.begin(); it != super::m_slots.end(); ++it) 02385 { 02386 int num_args = (*it)->getNumberOfArguments(); 02387 02388 switch (num_args) 02389 { 02390 case 4: 02391 { 02392 typedef SlotAdapter<arg1_type, arg2_type, arg3_type, arg4_type> * slot_ptr; 02393 static_cast<slot_ptr>(*it)->callFunction(arg1, arg2, arg3, arg4); 02394 break; 02395 } 02396 02397 case 3: 02398 { 02399 typedef SlotAdapter<arg1_type, arg2_type, arg3_type> * slot_ptr; 02400 static_cast<slot_ptr>(*it)->callFunction(arg1, arg2, arg3); 02401 break; 02402 } 02403 02404 case 2: 02405 { 02406 typedef SlotAdapter<arg1_type, arg2_type> * slot_ptr; 02407 static_cast<slot_ptr>(*it)->callFunction(arg1, arg2); 02408 break; 02409 } 02410 02411 case 1: 02412 { 02413 typedef SlotAdapter<arg1_type> * slot_ptr; 02414 static_cast<slot_ptr>(*it)->callFunction(arg1); 02415 break; 02416 } 02417 02418 case 0: 02419 { 02420 typedef SlotAdapter<> * slot_ptr; 02421 static_cast<slot_ptr>(*it)->callFunction(); 02422 break; 02423 } 02424 } 02425 } 02426 } 02427 02428 private: 02429 02430 typedef SignalBase super; 02431 }; 02432 02433 02434 // three arguments specified 02435 02436 02437 template <typename arg1_type, typename arg2_type, typename arg3_type> 02438 class Signal<arg1_type, arg2_type, arg3_type, void> : public SignalBase 02439 { 02440 public: 02441 02442 Signal() {} 02443 virtual ~Signal() {} 02444 02445 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 02446 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02447 { 02448 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 02449 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(object, function)); 02450 super::connect(slot, connection_type); 02451 } 02452 02453 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02454 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02455 { 02456 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02457 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02458 super::connect(slot, connection_type); 02459 } 02460 02461 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02462 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02463 { 02464 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02465 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02466 super::connect(slot, connection_type); 02467 } 02468 02469 template <typename slot_class_type, typename slot_return_type> 02470 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02471 { 02472 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02473 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02474 super::connect(slot, connection_type); 02475 } 02476 02477 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 02478 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02479 { 02480 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 02481 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(object, function)); 02482 super::connect(slot, connection_type); 02483 } 02484 02485 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02486 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02487 { 02488 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02489 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02490 super::connect(slot, connection_type); 02491 } 02492 02493 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02494 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02495 { 02496 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02497 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02498 super::connect(slot, connection_type); 02499 } 02500 02501 template <typename slot_class_type, typename slot_return_type> 02502 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 02503 { 02504 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02505 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02506 super::connect(slot, connection_type); 02507 } 02508 02509 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 02510 void connect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02511 { 02512 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 02513 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(function)); 02514 super::connect(slot, connection_type); 02515 } 02516 02517 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02518 void connect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02519 { 02520 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02521 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type>(function)); 02522 super::connect(slot, connection_type); 02523 } 02524 02525 template <typename slot_return_type, typename slot_arg1_type> 02526 void connect(slot_return_type (*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02527 { 02528 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02529 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type>(function)); 02530 super::connect(slot, connection_type); 02531 } 02532 02533 template <typename slot_return_type> 02534 void connect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02535 { 02536 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02537 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 02538 super::connect(slot, connection_type); 02539 } 02540 02541 02542 02543 02544 02545 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 02546 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02547 { 02548 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 02549 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(object, function)); 02550 super::disconnect(slot, connection_type); 02551 } 02552 02553 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02554 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02555 { 02556 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02557 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02558 super::disconnect(slot, connection_type); 02559 } 02560 02561 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02562 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02563 { 02564 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02565 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02566 super::disconnect(slot, connection_type); 02567 } 02568 02569 template <typename slot_class_type, typename slot_return_type> 02570 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02571 { 02572 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02573 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02574 super::disconnect(slot, connection_type); 02575 } 02576 02577 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 02578 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02579 { 02580 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 02581 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(object, function)); 02582 super::disconnect(slot, connection_type); 02583 } 02584 02585 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02586 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02587 { 02588 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02589 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02590 super::disconnect(slot, connection_type); 02591 } 02592 02593 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02594 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02595 { 02596 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02597 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02598 super::disconnect(slot, connection_type); 02599 } 02600 02601 template <typename slot_class_type, typename slot_return_type> 02602 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 02603 { 02604 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02605 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02606 super::disconnect(slot, connection_type); 02607 } 02608 02609 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type, typename slot_arg3_type> 02610 void disconnect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type, slot_arg3_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02611 { 02612 typedef ConcreteSlotAdapter<arg1_type, arg2_type, arg3_type, void, slot_arg1_type, slot_arg2_type, slot_arg3_type, void> slot_adapter_type; 02613 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type, slot_arg3_type>(function)); 02614 super::disconnect(slot, connection_type); 02615 } 02616 02617 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02618 void disconnect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02619 { 02620 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02621 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type>(function)); 02622 super::disconnect(slot, connection_type); 02623 } 02624 02625 template <typename slot_return_type, typename slot_arg1_type> 02626 void disconnect(slot_return_type (*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02627 { 02628 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02629 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type>(function)); 02630 super::disconnect(slot, connection_type); 02631 } 02632 02633 template <typename slot_return_type> 02634 void disconnect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02635 { 02636 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02637 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 02638 super::disconnect(slot, connection_type); 02639 } 02640 02641 void send(arg1_type arg1, arg2_type arg2, arg3_type arg3) const 02642 { 02643 std::list<SlotAdapterBase *>::iterator it; 02644 02645 for (it = super::m_slots.begin(); it != super::m_slots.end(); ++it) 02646 { 02647 int num_args = (*it)->getNumberOfArguments(); 02648 02649 switch (num_args) 02650 { 02651 case 3: 02652 { 02653 typedef SlotAdapter<arg1_type, arg2_type, arg3_type> * slot_ptr; 02654 static_cast<slot_ptr>(*it)->callFunction(arg1, arg2, arg3); 02655 break; 02656 } 02657 02658 case 2: 02659 { 02660 typedef SlotAdapter<arg1_type, arg2_type> * slot_ptr; 02661 static_cast<slot_ptr>(*it)->callFunction(arg1, arg2); 02662 break; 02663 } 02664 02665 case 1: 02666 { 02667 typedef SlotAdapter<arg1_type> * slot_ptr; 02668 static_cast<slot_ptr>(*it)->callFunction(arg1); 02669 break; 02670 } 02671 02672 case 0: 02673 { 02674 typedef SlotAdapter<> * slot_ptr; 02675 static_cast<slot_ptr>(*it)->callFunction(); 02676 break; 02677 } 02678 } 02679 } 02680 } 02681 02682 private: 02683 02684 typedef SignalBase super; 02685 }; 02686 02687 02688 // two arguments specified 02689 02690 02691 template <typename arg1_type, typename arg2_type> 02692 class Signal<arg1_type, arg2_type, void, void> : public SignalBase 02693 { 02694 public: 02695 02696 Signal() {} 02697 virtual ~Signal() {} 02698 02699 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02700 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02701 { 02702 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02703 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02704 super::connect(slot, connection_type); 02705 } 02706 02707 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02708 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02709 { 02710 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02711 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02712 super::connect(slot, connection_type); 02713 } 02714 02715 template <typename slot_class_type, typename slot_return_type> 02716 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02717 { 02718 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02719 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02720 super::connect(slot, connection_type); 02721 } 02722 02723 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02724 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02725 { 02726 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02727 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02728 super::connect(slot, connection_type); 02729 } 02730 02731 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02732 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02733 { 02734 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02735 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02736 super::connect(slot, connection_type); 02737 } 02738 02739 template <typename slot_class_type, typename slot_return_type> 02740 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 02741 { 02742 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02743 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02744 super::connect(slot, connection_type); 02745 } 02746 02747 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02748 void connect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02749 { 02750 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02751 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type>(function)); 02752 super::connect(slot, connection_type); 02753 } 02754 02755 template <typename slot_return_type, typename slot_arg1_type> 02756 void connect(slot_return_type (*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02757 { 02758 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02759 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type>(function)); 02760 super::connect(slot, connection_type); 02761 } 02762 02763 template <typename slot_return_type> 02764 void connect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02765 { 02766 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02767 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 02768 super::connect(slot, connection_type); 02769 } 02770 02771 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02772 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02773 { 02774 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02775 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02776 super::disconnect(slot, connection_type); 02777 } 02778 02779 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02780 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02781 { 02782 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02783 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02784 super::disconnect(slot, connection_type); 02785 } 02786 02787 template <typename slot_class_type, typename slot_return_type> 02788 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02789 { 02790 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02791 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02792 super::disconnect(slot, connection_type); 02793 } 02794 02795 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02796 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type, slot_arg2_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02797 { 02798 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02799 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type, slot_arg2_type>(object, function)); 02800 super::disconnect(slot, connection_type); 02801 } 02802 02803 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02804 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02805 { 02806 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02807 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02808 super::disconnect(slot, connection_type); 02809 } 02810 02811 template <typename slot_class_type, typename slot_return_type> 02812 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 02813 { 02814 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02815 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02816 super::disconnect(slot, connection_type); 02817 } 02818 02819 template <typename slot_return_type, typename slot_arg1_type, typename slot_arg2_type> 02820 void disconnect(slot_return_type (*function)(slot_arg1_type, slot_arg2_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02821 { 02822 typedef ConcreteSlotAdapter<arg1_type, arg2_type, void, void, slot_arg1_type, slot_arg2_type, void, void> slot_adapter_type; 02823 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type, slot_arg2_type>(function)); 02824 super::disconnect(slot, connection_type); 02825 } 02826 02827 template <typename slot_return_type, typename slot_arg1_type> 02828 void disconnect(slot_return_type (*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02829 { 02830 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02831 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type>(function)); 02832 super::disconnect(slot, connection_type); 02833 } 02834 02835 template <typename slot_return_type> 02836 void disconnect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02837 { 02838 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02839 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 02840 super::disconnect(slot, connection_type); 02841 } 02842 02843 void send(arg1_type arg1, arg2_type arg2) const 02844 { 02845 std::list<SlotAdapterBase *>::iterator it; 02846 02847 for (it = super::m_slots.begin(); it != super::m_slots.end(); ++it) 02848 { 02849 int num_args = (*it)->getNumberOfArguments(); 02850 02851 switch (num_args) 02852 { 02853 case 2: 02854 { 02855 typedef SlotAdapter<arg1_type, arg2_type> * slot_ptr; 02856 static_cast<slot_ptr>(*it)->callFunction(arg1, arg2); 02857 break; 02858 } 02859 02860 case 1: 02861 { 02862 typedef SlotAdapter<arg1_type> * slot_ptr; 02863 static_cast<slot_ptr>(*it)->callFunction(arg1); 02864 break; 02865 } 02866 02867 case 0: 02868 { 02869 typedef SlotAdapter<> * slot_ptr; 02870 static_cast<slot_ptr>(*it)->callFunction(); 02871 break; 02872 } 02873 } 02874 } 02875 } 02876 02877 private: 02878 02879 typedef SignalBase super; 02880 }; 02881 02882 02883 // one argument specified 02884 02885 02886 template <typename arg1_type> 02887 class Signal<arg1_type, void, void, void> : public SignalBase 02888 { 02889 public: 02890 02891 Signal() {} 02892 virtual ~Signal() {} 02893 02894 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02895 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02896 { 02897 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02898 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02899 super::connect(slot, connection_type); 02900 } 02901 02902 template <typename slot_class_type, typename slot_return_type> 02903 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02904 { 02905 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02906 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02907 super::connect(slot, connection_type); 02908 } 02909 02910 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02911 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02912 { 02913 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02914 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02915 super::connect(slot, connection_type); 02916 } 02917 02918 template <typename slot_class_type, typename slot_return_type> 02919 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 02920 { 02921 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02922 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02923 super::connect(slot, connection_type); 02924 } 02925 02926 template <typename slot_return_type, typename slot_arg1_type> 02927 void connect(slot_return_type (*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02928 { 02929 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02930 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type>(function)); 02931 super::connect(slot, connection_type); 02932 } 02933 02934 template <typename slot_return_type> 02935 void connect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02936 { 02937 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02938 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 02939 super::connect(slot, connection_type); 02940 } 02941 02942 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02943 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02944 { 02945 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02946 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02947 super::disconnect(slot, connection_type); 02948 } 02949 02950 template <typename slot_class_type, typename slot_return_type> 02951 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02952 { 02953 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02954 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02955 super::disconnect(slot, connection_type); 02956 } 02957 02958 template <typename slot_class_type, typename slot_return_type, typename slot_arg1_type> 02959 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)(slot_arg1_type) const, ConnectionType connection_type = SINGLE_CONNECTION) const 02960 { 02961 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02962 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type, slot_arg1_type>(object, function)); 02963 super::disconnect(slot, connection_type); 02964 } 02965 02966 template <typename slot_class_type, typename slot_return_type> 02967 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 02968 { 02969 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02970 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 02971 super::disconnect(slot, connection_type); 02972 } 02973 02974 template <typename slot_return_type, typename slot_arg1_type> 02975 void disconnect(slot_return_type (*function)(slot_arg1_type), ConnectionType connection_type = SINGLE_CONNECTION) const 02976 { 02977 typedef ConcreteSlotAdapter<arg1_type, void, void, void, slot_arg1_type, void, void, void> slot_adapter_type; 02978 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type, slot_arg1_type>(function)); 02979 super::disconnect(slot, connection_type); 02980 } 02981 02982 template <typename slot_return_type> 02983 void disconnect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 02984 { 02985 typedef ConcreteSlotAdapter<void, void, void, void, void, void, void, void> slot_adapter_type; 02986 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 02987 super::disconnect(slot, connection_type); 02988 } 02989 02990 void send(arg1_type arg1) const 02991 { 02992 std::list<SlotAdapterBase *>::iterator it; 02993 02994 for (it = super::m_slots.begin(); it != super::m_slots.end(); ++it) 02995 { 02996 int num_args = (*it)->getNumberOfArguments(); 02997 02998 switch (num_args) 02999 { 03000 case 1: 03001 { 03002 typedef SlotAdapter<arg1_type> * slot_ptr; 03003 static_cast<slot_ptr>(*it)->callFunction(arg1); 03004 break; 03005 } 03006 03007 case 0: 03008 { 03009 typedef SlotAdapter<> * slot_ptr; 03010 static_cast<slot_ptr>(*it)->callFunction(); 03011 break; 03012 } 03013 } 03014 } 03015 } 03016 03017 private: 03018 03019 typedef SignalBase super; 03020 }; 03021 03022 03023 // no arguments specified 03024 03025 03026 template<> 03027 class Signal<void, void, void, void> : public SignalBase 03028 { 03029 public: 03030 03031 Signal() {} 03032 virtual ~Signal() {} 03033 03034 template <typename slot_class_type, typename slot_return_type> 03035 void connect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 03036 { 03037 typedef ConcreteSlotAdapter<> slot_adapter_type; 03038 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 03039 super::connect(slot, connection_type); 03040 } 03041 03042 template <typename slot_class_type, typename slot_return_type> 03043 void connect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 03044 { 03045 typedef ConcreteSlotAdapter<> slot_adapter_type; 03046 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 03047 super::connect(slot, connection_type); 03048 } 03049 03050 template <typename slot_return_type> 03051 void connect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 03052 { 03053 typedef ConcreteSlotAdapter<> slot_adapter_type; 03054 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 03055 super::connect(slot, connection_type); 03056 } 03057 03058 template <typename slot_class_type, typename slot_return_type> 03059 void disconnect(slot_class_type * object, slot_return_type (slot_class_type::*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 03060 { 03061 typedef ConcreteSlotAdapter<> slot_adapter_type; 03062 SlotAdapterBase * slot = new slot_adapter_type(new MemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 03063 super::disconnect(slot, connection_type); 03064 delete slot; 03065 } 03066 03067 template <typename slot_class_type, typename slot_return_type> 03068 void disconnect(const slot_class_type * object, slot_return_type (slot_class_type::*function)() const, ConnectionType connection_type = SINGLE_CONNECTION) const 03069 { 03070 typedef ConcreteSlotAdapter<> slot_adapter_type; 03071 SlotAdapterBase * slot = new slot_adapter_type(new ConstMemberFunctionSlot<slot_class_type, slot_return_type>(object, function)); 03072 super::disconnect(slot, connection_type); 03073 delete slot; 03074 } 03075 03076 template <typename slot_return_type> 03077 void disconnect(slot_return_type (*function)(), ConnectionType connection_type = SINGLE_CONNECTION) const 03078 { 03079 typedef ConcreteSlotAdapter<> slot_adapter_type; 03080 SlotAdapterBase * slot = new slot_adapter_type(new GlobalFunctionSlot<slot_return_type>(function)); 03081 super::disconnect(slot, connection_type); 03082 delete slot; 03083 } 03084 03085 void send() const 03086 { 03087 std::list<SlotAdapterBase *>::iterator it; 03088 03089 for (it = super::m_slots.begin(); it != super::m_slots.end(); ++it) 03090 { 03091 typedef SlotAdapter<> * slot_ptr; 03092 static_cast<slot_ptr>(*it)->callFunction(); 03093 } 03094 } 03095 03096 private: 03097 03098 typedef SignalBase super; 03099 }; 03100 03101 03102 } // namespace Signals 03103 03104 03105 // For convenience reasons, populate the TRTK namespace with some entities 03106 // from the Signals namespace. 03107 03108 using Signals::Signal; 03109 using Signals::Receiver; 03110 using Signals::ConnectionType; 03111 using Signals::MULTIPLE_CONNECTIONS; 03112 using Signals::SINGLE_CONNECTION; 03113 03114 03115 } // namespace TRTK 03116 03117 03118 #endif // SIGNALS_HPP_6243120120
Documentation generated by Doxygen