1 // sigslot.h: Signal/Slot classes 2 // 3 // Written by Sarah Thompson (sarah (at) telergy.com) 2002. 4 // 5 // License: Public domain. You are free to use this code however you like, with the proviso that 6 // the author takes on no responsibility or liability for any use. 7 // 8 // QUICK DOCUMENTATION 9 // 10 // (see also the full documentation at http://sigslot.sourceforge.net/) 11 // 12 // #define switches 13 // SIGSLOT_PURE_ISO - Define this to force ISO C++ compliance. This also disables 14 // all of the thread safety support on platforms where it is 15 // available. 16 // 17 // SIGSLOT_USE_POSIX_THREADS - Force use of Posix threads when using a C++ compiler other than 18 // gcc on a platform that supports Posix threads. (When using gcc, 19 // this is the default - use SIGSLOT_PURE_ISO to disable this if 20 // necessary) 21 // 22 // SIGSLOT_DEFAULT_MT_POLICY - Where thread support is enabled, this defaults to multi_threaded_global. 23 // Otherwise, the default is single_threaded. #define this yourself to 24 // override the default. In pure ISO mode, anything other than 25 // single_threaded will cause a compiler error. 26 // 27 // PLATFORM NOTES 28 // 29 // Win32 - On Win32, the WEBRTC_WIN symbol must be #defined. Most mainstream 30 // compilers do this by default, but you may need to define it 31 // yourself if your build environment is less standard. This causes 32 // the Win32 thread support to be compiled in and used automatically. 33 // 34 // Unix/Linux/BSD, etc. - If you're using gcc, it is assumed that you have Posix threads 35 // available, so they are used automatically. You can override this 36 // (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using 37 // something other than gcc but still want to use Posix threads, you 38 // need to #define SIGSLOT_USE_POSIX_THREADS. 39 // 40 // ISO C++ - If none of the supported platforms are detected, or if 41 // SIGSLOT_PURE_ISO is defined, all multithreading support is turned off, 42 // along with any code that might cause a pure ISO C++ environment to 43 // complain. Before you ask, gcc -ansi -pedantic won't compile this 44 // library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of 45 // errors that aren't really there. If you feel like investigating this, 46 // please contact the author. 47 // 48 // 49 // THREADING MODES 50 // 51 // single_threaded - Your program is assumed to be single threaded from the point of view 52 // of signal/slot usage (i.e. all objects using signals and slots are 53 // created and destroyed from a single thread). Behaviour if objects are 54 // destroyed concurrently is undefined (i.e. you'll get the occasional 55 // segmentation fault/memory exception). 56 // 57 // multi_threaded_global - Your program is assumed to be multi threaded. Objects using signals and 58 // slots can be safely created and destroyed from any thread, even when 59 // connections exist. In multi_threaded_global mode, this is achieved by a 60 // single global mutex (actually a critical section on Windows because they 61 // are faster). This option uses less OS resources, but results in more 62 // opportunities for contention, possibly resulting in more context switches 63 // than are strictly necessary. 64 // 65 // multi_threaded_local - Behaviour in this mode is essentially the same as multi_threaded_global, 66 // except that each signal, and each object that inherits has_slots, all 67 // have their own mutex/critical section. In practice, this means that 68 // mutex collisions (and hence context switches) only happen if they are 69 // absolutely essential. However, on some platforms, creating a lot of 70 // mutexes can slow down the whole OS, so use this option with care. 71 // 72 // USING THE LIBRARY 73 // 74 // See the full documentation at http://sigslot.sourceforge.net/ 75 // 76 // 77 // Libjingle specific: 78 // This file has been modified such that has_slots and signalx do not have to be 79 // using the same threading requirements. E.g. it is possible to connect a 80 // has_slots<single_threaded> and signal0<multi_threaded_local> or 81 // has_slots<multi_threaded_local> and signal0<single_threaded>. 82 // If has_slots is single threaded the user must ensure that it is not trying 83 // to connect or disconnect to signalx concurrently or data race may occur. 84 // If signalx is single threaded the user must ensure that disconnect, connect 85 // or signal is not happening concurrently or data race may occur. 86 87 #ifndef WEBRTC_BASE_SIGSLOT_H__ 88 #define WEBRTC_BASE_SIGSLOT_H__ 89 90 #include <list> 91 #include <set> 92 #include <stdlib.h> 93 94 // On our copy of sigslot.h, we set single threading as default. 95 #define SIGSLOT_DEFAULT_MT_POLICY single_threaded 96 97 #if defined(SIGSLOT_PURE_ISO) || (!defined(WEBRTC_WIN) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS)) 98 # define _SIGSLOT_SINGLE_THREADED 99 #elif defined(WEBRTC_WIN) 100 # define _SIGSLOT_HAS_WIN32_THREADS 101 # if !defined(WIN32_LEAN_AND_MEAN) 102 # define WIN32_LEAN_AND_MEAN 103 # endif 104 # include "webrtc/base/win32.h" 105 #elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS) 106 # define _SIGSLOT_HAS_POSIX_THREADS 107 # include <pthread.h> 108 #else 109 # define _SIGSLOT_SINGLE_THREADED 110 #endif 111 112 #ifndef SIGSLOT_DEFAULT_MT_POLICY 113 # ifdef _SIGSLOT_SINGLE_THREADED 114 # define SIGSLOT_DEFAULT_MT_POLICY single_threaded 115 # else 116 # define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local 117 # endif 118 #endif 119 120 // TODO: change this namespace to rtc? 121 namespace sigslot { 122 123 class single_threaded 124 { 125 public: 126 single_threaded() 127 { 128 ; 129 } 130 131 virtual ~single_threaded() 132 { 133 ; 134 } 135 136 virtual void lock() 137 { 138 ; 139 } 140 141 virtual void unlock() 142 { 143 ; 144 } 145 }; 146 147 #ifdef _SIGSLOT_HAS_WIN32_THREADS 148 // The multi threading policies only get compiled in if they are enabled. 149 class multi_threaded_global 150 { 151 public: 152 multi_threaded_global() 153 { 154 static bool isinitialised = false; 155 156 if(!isinitialised) 157 { 158 InitializeCriticalSection(get_critsec()); 159 isinitialised = true; 160 } 161 } 162 163 multi_threaded_global(const multi_threaded_global&) 164 { 165 ; 166 } 167 168 virtual ~multi_threaded_global() 169 { 170 ; 171 } 172 173 virtual void lock() 174 { 175 EnterCriticalSection(get_critsec()); 176 } 177 178 virtual void unlock() 179 { 180 LeaveCriticalSection(get_critsec()); 181 } 182 183 private: 184 CRITICAL_SECTION* get_critsec() 185 { 186 static CRITICAL_SECTION g_critsec; 187 return &g_critsec; 188 } 189 }; 190 191 class multi_threaded_local 192 { 193 public: 194 multi_threaded_local() 195 { 196 InitializeCriticalSection(&m_critsec); 197 } 198 199 multi_threaded_local(const multi_threaded_local&) 200 { 201 InitializeCriticalSection(&m_critsec); 202 } 203 204 virtual ~multi_threaded_local() 205 { 206 DeleteCriticalSection(&m_critsec); 207 } 208 209 virtual void lock() 210 { 211 EnterCriticalSection(&m_critsec); 212 } 213 214 virtual void unlock() 215 { 216 LeaveCriticalSection(&m_critsec); 217 } 218 219 private: 220 CRITICAL_SECTION m_critsec; 221 }; 222 #endif // _SIGSLOT_HAS_WIN32_THREADS 223 224 #ifdef _SIGSLOT_HAS_POSIX_THREADS 225 // The multi threading policies only get compiled in if they are enabled. 226 class multi_threaded_global 227 { 228 public: 229 multi_threaded_global() 230 { 231 pthread_mutex_init(get_mutex(), NULL); 232 } 233 234 multi_threaded_global(const multi_threaded_global&) 235 { 236 ; 237 } 238 239 virtual ~multi_threaded_global() 240 { 241 ; 242 } 243 244 virtual void lock() 245 { 246 pthread_mutex_lock(get_mutex()); 247 } 248 249 virtual void unlock() 250 { 251 pthread_mutex_unlock(get_mutex()); 252 } 253 254 private: 255 pthread_mutex_t* get_mutex() 256 { 257 static pthread_mutex_t g_mutex; 258 return &g_mutex; 259 } 260 }; 261 262 class multi_threaded_local 263 { 264 public: 265 multi_threaded_local() 266 { 267 pthread_mutex_init(&m_mutex, NULL); 268 } 269 270 multi_threaded_local(const multi_threaded_local&) 271 { 272 pthread_mutex_init(&m_mutex, NULL); 273 } 274 275 virtual ~multi_threaded_local() 276 { 277 pthread_mutex_destroy(&m_mutex); 278 } 279 280 virtual void lock() 281 { 282 pthread_mutex_lock(&m_mutex); 283 } 284 285 virtual void unlock() 286 { 287 pthread_mutex_unlock(&m_mutex); 288 } 289 290 private: 291 pthread_mutex_t m_mutex; 292 }; 293 #endif // _SIGSLOT_HAS_POSIX_THREADS 294 295 template<class mt_policy> 296 class lock_block 297 { 298 public: 299 mt_policy *m_mutex; 300 301 lock_block(mt_policy *mtx) 302 : m_mutex(mtx) 303 { 304 m_mutex->lock(); 305 } 306 307 ~lock_block() 308 { 309 m_mutex->unlock(); 310 } 311 }; 312 313 class has_slots_interface; 314 315 template<class mt_policy> 316 class _connection_base0 317 { 318 public: 319 virtual ~_connection_base0() {} 320 virtual has_slots_interface* getdest() const = 0; 321 virtual void emit() = 0; 322 virtual _connection_base0* clone() = 0; 323 virtual _connection_base0* duplicate(has_slots_interface* pnewdest) = 0; 324 }; 325 326 template<class arg1_type, class mt_policy> 327 class _connection_base1 328 { 329 public: 330 virtual ~_connection_base1() {} 331 virtual has_slots_interface* getdest() const = 0; 332 virtual void emit(arg1_type) = 0; 333 virtual _connection_base1<arg1_type, mt_policy>* clone() = 0; 334 virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots_interface* pnewdest) = 0; 335 }; 336 337 template<class arg1_type, class arg2_type, class mt_policy> 338 class _connection_base2 339 { 340 public: 341 virtual ~_connection_base2() {} 342 virtual has_slots_interface* getdest() const = 0; 343 virtual void emit(arg1_type, arg2_type) = 0; 344 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() = 0; 345 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots_interface* pnewdest) = 0; 346 }; 347 348 template<class arg1_type, class arg2_type, class arg3_type, class mt_policy> 349 class _connection_base3 350 { 351 public: 352 virtual ~_connection_base3() {} 353 virtual has_slots_interface* getdest() const = 0; 354 virtual void emit(arg1_type, arg2_type, arg3_type) = 0; 355 virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone() = 0; 356 virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots_interface* pnewdest) = 0; 357 }; 358 359 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy> 360 class _connection_base4 361 { 362 public: 363 virtual ~_connection_base4() {} 364 virtual has_slots_interface* getdest() const = 0; 365 virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type) = 0; 366 virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone() = 0; 367 virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots_interface* pnewdest) = 0; 368 }; 369 370 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 371 class arg5_type, class mt_policy> 372 class _connection_base5 373 { 374 public: 375 virtual ~_connection_base5() {} 376 virtual has_slots_interface* getdest() const = 0; 377 virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, 378 arg5_type) = 0; 379 virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, 380 arg5_type, mt_policy>* clone() = 0; 381 virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, 382 arg5_type, mt_policy>* duplicate(has_slots_interface* pnewdest) = 0; 383 }; 384 385 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 386 class arg5_type, class arg6_type, class mt_policy> 387 class _connection_base6 388 { 389 public: 390 virtual ~_connection_base6() {} 391 virtual has_slots_interface* getdest() const = 0; 392 virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, 393 arg6_type) = 0; 394 virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, 395 arg5_type, arg6_type, mt_policy>* clone() = 0; 396 virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, 397 arg5_type, arg6_type, mt_policy>* duplicate(has_slots_interface* pnewdest) = 0; 398 }; 399 400 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 401 class arg5_type, class arg6_type, class arg7_type, class mt_policy> 402 class _connection_base7 403 { 404 public: 405 virtual ~_connection_base7() {} 406 virtual has_slots_interface* getdest() const = 0; 407 virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, 408 arg6_type, arg7_type) = 0; 409 virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, 410 arg5_type, arg6_type, arg7_type, mt_policy>* clone() = 0; 411 virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, 412 arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots_interface* pnewdest) = 0; 413 }; 414 415 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 416 class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy> 417 class _connection_base8 418 { 419 public: 420 virtual ~_connection_base8() {} 421 virtual has_slots_interface* getdest() const = 0; 422 virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, 423 arg6_type, arg7_type, arg8_type) = 0; 424 virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, 425 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone() = 0; 426 virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, 427 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots_interface* pnewdest) = 0; 428 }; 429 430 class _signal_base_interface 431 { 432 public: 433 virtual void slot_disconnect(has_slots_interface* pslot) = 0; 434 virtual void slot_duplicate(const has_slots_interface* poldslot, has_slots_interface* pnewslot) = 0; 435 }; 436 437 template<class mt_policy> 438 class _signal_base : public _signal_base_interface, public mt_policy 439 { 440 }; 441 442 class has_slots_interface 443 { 444 public: 445 has_slots_interface() 446 { 447 ; 448 } 449 450 virtual void signal_connect(_signal_base_interface* sender) = 0; 451 452 virtual void signal_disconnect(_signal_base_interface* sender) = 0; 453 454 virtual ~has_slots_interface() 455 { 456 } 457 458 virtual void disconnect_all() = 0; 459 }; 460 461 template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 462 class has_slots : public has_slots_interface, public mt_policy 463 { 464 private: 465 typedef std::set<_signal_base_interface*> sender_set; 466 typedef sender_set::const_iterator const_iterator; 467 468 public: 469 has_slots() 470 { 471 ; 472 } 473 474 has_slots(const has_slots& hs) 475 { 476 lock_block<mt_policy> lock(this); 477 const_iterator it = hs.m_senders.begin(); 478 const_iterator itEnd = hs.m_senders.end(); 479 480 while(it != itEnd) 481 { 482 (*it)->slot_duplicate(&hs, this); 483 m_senders.insert(*it); 484 ++it; 485 } 486 } 487 488 void signal_connect(_signal_base_interface* sender) 489 { 490 lock_block<mt_policy> lock(this); 491 m_senders.insert(sender); 492 } 493 494 void signal_disconnect(_signal_base_interface* sender) 495 { 496 lock_block<mt_policy> lock(this); 497 m_senders.erase(sender); 498 } 499 500 virtual ~has_slots() 501 { 502 disconnect_all(); 503 } 504 505 void disconnect_all() 506 { 507 lock_block<mt_policy> lock(this); 508 const_iterator it = m_senders.begin(); 509 const_iterator itEnd = m_senders.end(); 510 511 while(it != itEnd) 512 { 513 (*it)->slot_disconnect(this); 514 ++it; 515 } 516 517 m_senders.erase(m_senders.begin(), m_senders.end()); 518 } 519 520 private: 521 sender_set m_senders; 522 }; 523 524 template<class mt_policy> 525 class _signal_base0 : public _signal_base<mt_policy> 526 { 527 public: 528 typedef std::list<_connection_base0<mt_policy> *> connections_list; 529 530 _signal_base0() 531 { 532 ; 533 } 534 535 _signal_base0(const _signal_base0& s) 536 : _signal_base<mt_policy>(s) 537 { 538 lock_block<mt_policy> lock(this); 539 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 540 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 541 542 while(it != itEnd) 543 { 544 (*it)->getdest()->signal_connect(this); 545 m_connected_slots.push_back((*it)->clone()); 546 547 ++it; 548 } 549 } 550 551 ~_signal_base0() 552 { 553 disconnect_all(); 554 } 555 556 bool is_empty() 557 { 558 lock_block<mt_policy> lock(this); 559 typename connections_list::const_iterator it = m_connected_slots.begin(); 560 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 561 return it == itEnd; 562 } 563 564 void disconnect_all() 565 { 566 lock_block<mt_policy> lock(this); 567 typename connections_list::const_iterator it = m_connected_slots.begin(); 568 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 569 570 while(it != itEnd) 571 { 572 (*it)->getdest()->signal_disconnect(this); 573 delete *it; 574 575 ++it; 576 } 577 578 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 579 } 580 581 #ifdef _DEBUG 582 bool connected(has_slots_interface* pclass) 583 { 584 lock_block<mt_policy> lock(this); 585 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 586 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 587 while(it != itEnd) 588 { 589 itNext = it; 590 ++itNext; 591 if ((*it)->getdest() == pclass) 592 return true; 593 it = itNext; 594 } 595 return false; 596 } 597 #endif 598 599 void disconnect(has_slots_interface* pclass) 600 { 601 lock_block<mt_policy> lock(this); 602 typename connections_list::iterator it = m_connected_slots.begin(); 603 typename connections_list::iterator itEnd = m_connected_slots.end(); 604 605 while(it != itEnd) 606 { 607 if((*it)->getdest() == pclass) 608 { 609 delete *it; 610 m_connected_slots.erase(it); 611 pclass->signal_disconnect(this); 612 return; 613 } 614 615 ++it; 616 } 617 } 618 619 void slot_disconnect(has_slots_interface* pslot) 620 { 621 lock_block<mt_policy> lock(this); 622 typename connections_list::iterator it = m_connected_slots.begin(); 623 typename connections_list::iterator itEnd = m_connected_slots.end(); 624 625 while(it != itEnd) 626 { 627 typename connections_list::iterator itNext = it; 628 ++itNext; 629 630 if((*it)->getdest() == pslot) 631 { 632 delete *it; 633 m_connected_slots.erase(it); 634 } 635 636 it = itNext; 637 } 638 } 639 640 void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) 641 { 642 lock_block<mt_policy> lock(this); 643 typename connections_list::iterator it = m_connected_slots.begin(); 644 typename connections_list::iterator itEnd = m_connected_slots.end(); 645 646 while(it != itEnd) 647 { 648 if((*it)->getdest() == oldtarget) 649 { 650 m_connected_slots.push_back((*it)->duplicate(newtarget)); 651 } 652 653 ++it; 654 } 655 } 656 657 protected: 658 connections_list m_connected_slots; 659 }; 660 661 template<class arg1_type, class mt_policy> 662 class _signal_base1 : public _signal_base<mt_policy> 663 { 664 public: 665 typedef std::list<_connection_base1<arg1_type, mt_policy> *> connections_list; 666 667 _signal_base1() 668 { 669 ; 670 } 671 672 _signal_base1(const _signal_base1<arg1_type, mt_policy>& s) 673 : _signal_base<mt_policy>(s) 674 { 675 lock_block<mt_policy> lock(this); 676 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 677 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 678 679 while(it != itEnd) 680 { 681 (*it)->getdest()->signal_connect(this); 682 m_connected_slots.push_back((*it)->clone()); 683 684 ++it; 685 } 686 } 687 688 void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) 689 { 690 lock_block<mt_policy> lock(this); 691 typename connections_list::iterator it = m_connected_slots.begin(); 692 typename connections_list::iterator itEnd = m_connected_slots.end(); 693 694 while(it != itEnd) 695 { 696 if((*it)->getdest() == oldtarget) 697 { 698 m_connected_slots.push_back((*it)->duplicate(newtarget)); 699 } 700 701 ++it; 702 } 703 } 704 705 ~_signal_base1() 706 { 707 disconnect_all(); 708 } 709 710 bool is_empty() 711 { 712 lock_block<mt_policy> lock(this); 713 typename connections_list::const_iterator it = m_connected_slots.begin(); 714 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 715 return it == itEnd; 716 } 717 718 void disconnect_all() 719 { 720 lock_block<mt_policy> lock(this); 721 typename connections_list::const_iterator it = m_connected_slots.begin(); 722 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 723 724 while(it != itEnd) 725 { 726 (*it)->getdest()->signal_disconnect(this); 727 delete *it; 728 729 ++it; 730 } 731 732 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 733 } 734 735 #ifdef _DEBUG 736 bool connected(has_slots_interface* pclass) 737 { 738 lock_block<mt_policy> lock(this); 739 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 740 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 741 while(it != itEnd) 742 { 743 itNext = it; 744 ++itNext; 745 if ((*it)->getdest() == pclass) 746 return true; 747 it = itNext; 748 } 749 return false; 750 } 751 #endif 752 753 void disconnect(has_slots_interface* pclass) 754 { 755 lock_block<mt_policy> lock(this); 756 typename connections_list::iterator it = m_connected_slots.begin(); 757 typename connections_list::iterator itEnd = m_connected_slots.end(); 758 759 while(it != itEnd) 760 { 761 if((*it)->getdest() == pclass) 762 { 763 delete *it; 764 m_connected_slots.erase(it); 765 pclass->signal_disconnect(this); 766 return; 767 } 768 769 ++it; 770 } 771 } 772 773 void slot_disconnect(has_slots_interface* pslot) 774 { 775 lock_block<mt_policy> lock(this); 776 typename connections_list::iterator it = m_connected_slots.begin(); 777 typename connections_list::iterator itEnd = m_connected_slots.end(); 778 779 while(it != itEnd) 780 { 781 typename connections_list::iterator itNext = it; 782 ++itNext; 783 784 if((*it)->getdest() == pslot) 785 { 786 delete *it; 787 m_connected_slots.erase(it); 788 } 789 790 it = itNext; 791 } 792 } 793 794 795 protected: 796 connections_list m_connected_slots; 797 }; 798 799 template<class arg1_type, class arg2_type, class mt_policy> 800 class _signal_base2 : public _signal_base<mt_policy> 801 { 802 public: 803 typedef std::list<_connection_base2<arg1_type, arg2_type, mt_policy> *> 804 connections_list; 805 806 _signal_base2() 807 { 808 ; 809 } 810 811 _signal_base2(const _signal_base2<arg1_type, arg2_type, mt_policy>& s) 812 : _signal_base<mt_policy>(s) 813 { 814 lock_block<mt_policy> lock(this); 815 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 816 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 817 818 while(it != itEnd) 819 { 820 (*it)->getdest()->signal_connect(this); 821 m_connected_slots.push_back((*it)->clone()); 822 823 ++it; 824 } 825 } 826 827 void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) 828 { 829 lock_block<mt_policy> lock(this); 830 typename connections_list::iterator it = m_connected_slots.begin(); 831 typename connections_list::iterator itEnd = m_connected_slots.end(); 832 833 while(it != itEnd) 834 { 835 if((*it)->getdest() == oldtarget) 836 { 837 m_connected_slots.push_back((*it)->duplicate(newtarget)); 838 } 839 840 ++it; 841 } 842 } 843 844 ~_signal_base2() 845 { 846 disconnect_all(); 847 } 848 849 bool is_empty() 850 { 851 lock_block<mt_policy> lock(this); 852 typename connections_list::const_iterator it = m_connected_slots.begin(); 853 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 854 return it == itEnd; 855 } 856 857 void disconnect_all() 858 { 859 lock_block<mt_policy> lock(this); 860 typename connections_list::const_iterator it = m_connected_slots.begin(); 861 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 862 863 while(it != itEnd) 864 { 865 (*it)->getdest()->signal_disconnect(this); 866 delete *it; 867 868 ++it; 869 } 870 871 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 872 } 873 874 #ifdef _DEBUG 875 bool connected(has_slots_interface* pclass) 876 { 877 lock_block<mt_policy> lock(this); 878 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 879 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 880 while(it != itEnd) 881 { 882 itNext = it; 883 ++itNext; 884 if ((*it)->getdest() == pclass) 885 return true; 886 it = itNext; 887 } 888 return false; 889 } 890 #endif 891 892 void disconnect(has_slots_interface* pclass) 893 { 894 lock_block<mt_policy> lock(this); 895 typename connections_list::iterator it = m_connected_slots.begin(); 896 typename connections_list::iterator itEnd = m_connected_slots.end(); 897 898 while(it != itEnd) 899 { 900 if((*it)->getdest() == pclass) 901 { 902 delete *it; 903 m_connected_slots.erase(it); 904 pclass->signal_disconnect(this); 905 return; 906 } 907 908 ++it; 909 } 910 } 911 912 void slot_disconnect(has_slots_interface* pslot) 913 { 914 lock_block<mt_policy> lock(this); 915 typename connections_list::iterator it = m_connected_slots.begin(); 916 typename connections_list::iterator itEnd = m_connected_slots.end(); 917 918 while(it != itEnd) 919 { 920 typename connections_list::iterator itNext = it; 921 ++itNext; 922 923 if((*it)->getdest() == pslot) 924 { 925 delete *it; 926 m_connected_slots.erase(it); 927 } 928 929 it = itNext; 930 } 931 } 932 933 protected: 934 connections_list m_connected_slots; 935 }; 936 937 template<class arg1_type, class arg2_type, class arg3_type, class mt_policy> 938 class _signal_base3 : public _signal_base<mt_policy> 939 { 940 public: 941 typedef std::list<_connection_base3<arg1_type, arg2_type, arg3_type, mt_policy> *> 942 connections_list; 943 944 _signal_base3() 945 { 946 ; 947 } 948 949 _signal_base3(const _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>& s) 950 : _signal_base<mt_policy>(s) 951 { 952 lock_block<mt_policy> lock(this); 953 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 954 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 955 956 while(it != itEnd) 957 { 958 (*it)->getdest()->signal_connect(this); 959 m_connected_slots.push_back((*it)->clone()); 960 961 ++it; 962 } 963 } 964 965 void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) 966 { 967 lock_block<mt_policy> lock(this); 968 typename connections_list::iterator it = m_connected_slots.begin(); 969 typename connections_list::iterator itEnd = m_connected_slots.end(); 970 971 while(it != itEnd) 972 { 973 if((*it)->getdest() == oldtarget) 974 { 975 m_connected_slots.push_back((*it)->duplicate(newtarget)); 976 } 977 978 ++it; 979 } 980 } 981 982 ~_signal_base3() 983 { 984 disconnect_all(); 985 } 986 987 bool is_empty() 988 { 989 lock_block<mt_policy> lock(this); 990 typename connections_list::const_iterator it = m_connected_slots.begin(); 991 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 992 return it == itEnd; 993 } 994 995 void disconnect_all() 996 { 997 lock_block<mt_policy> lock(this); 998 typename connections_list::const_iterator it = m_connected_slots.begin(); 999 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1000 1001 while(it != itEnd) 1002 { 1003 (*it)->getdest()->signal_disconnect(this); 1004 delete *it; 1005 1006 ++it; 1007 } 1008 1009 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 1010 } 1011 1012 #ifdef _DEBUG 1013 bool connected(has_slots_interface* pclass) 1014 { 1015 lock_block<mt_policy> lock(this); 1016 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 1017 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1018 while(it != itEnd) 1019 { 1020 itNext = it; 1021 ++itNext; 1022 if ((*it)->getdest() == pclass) 1023 return true; 1024 it = itNext; 1025 } 1026 return false; 1027 } 1028 #endif 1029 1030 void disconnect(has_slots_interface* pclass) 1031 { 1032 lock_block<mt_policy> lock(this); 1033 typename connections_list::iterator it = m_connected_slots.begin(); 1034 typename connections_list::iterator itEnd = m_connected_slots.end(); 1035 1036 while(it != itEnd) 1037 { 1038 if((*it)->getdest() == pclass) 1039 { 1040 delete *it; 1041 m_connected_slots.erase(it); 1042 pclass->signal_disconnect(this); 1043 return; 1044 } 1045 1046 ++it; 1047 } 1048 } 1049 1050 void slot_disconnect(has_slots_interface* pslot) 1051 { 1052 lock_block<mt_policy> lock(this); 1053 typename connections_list::iterator it = m_connected_slots.begin(); 1054 typename connections_list::iterator itEnd = m_connected_slots.end(); 1055 1056 while(it != itEnd) 1057 { 1058 typename connections_list::iterator itNext = it; 1059 ++itNext; 1060 1061 if((*it)->getdest() == pslot) 1062 { 1063 delete *it; 1064 m_connected_slots.erase(it); 1065 } 1066 1067 it = itNext; 1068 } 1069 } 1070 1071 protected: 1072 connections_list m_connected_slots; 1073 }; 1074 1075 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy> 1076 class _signal_base4 : public _signal_base<mt_policy> 1077 { 1078 public: 1079 typedef std::list<_connection_base4<arg1_type, arg2_type, arg3_type, 1080 arg4_type, mt_policy> *> connections_list; 1081 1082 _signal_base4() 1083 { 1084 ; 1085 } 1086 1087 _signal_base4(const _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s) 1088 : _signal_base<mt_policy>(s) 1089 { 1090 lock_block<mt_policy> lock(this); 1091 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 1092 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 1093 1094 while(it != itEnd) 1095 { 1096 (*it)->getdest()->signal_connect(this); 1097 m_connected_slots.push_back((*it)->clone()); 1098 1099 ++it; 1100 } 1101 } 1102 1103 void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) 1104 { 1105 lock_block<mt_policy> lock(this); 1106 typename connections_list::iterator it = m_connected_slots.begin(); 1107 typename connections_list::iterator itEnd = m_connected_slots.end(); 1108 1109 while(it != itEnd) 1110 { 1111 if((*it)->getdest() == oldtarget) 1112 { 1113 m_connected_slots.push_back((*it)->duplicate(newtarget)); 1114 } 1115 1116 ++it; 1117 } 1118 } 1119 1120 ~_signal_base4() 1121 { 1122 disconnect_all(); 1123 } 1124 1125 bool is_empty() 1126 { 1127 lock_block<mt_policy> lock(this); 1128 typename connections_list::const_iterator it = m_connected_slots.begin(); 1129 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1130 return it == itEnd; 1131 } 1132 1133 void disconnect_all() 1134 { 1135 lock_block<mt_policy> lock(this); 1136 typename connections_list::const_iterator it = m_connected_slots.begin(); 1137 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1138 1139 while(it != itEnd) 1140 { 1141 (*it)->getdest()->signal_disconnect(this); 1142 delete *it; 1143 1144 ++it; 1145 } 1146 1147 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 1148 } 1149 1150 #ifdef _DEBUG 1151 bool connected(has_slots_interface* pclass) 1152 { 1153 lock_block<mt_policy> lock(this); 1154 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 1155 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1156 while(it != itEnd) 1157 { 1158 itNext = it; 1159 ++itNext; 1160 if ((*it)->getdest() == pclass) 1161 return true; 1162 it = itNext; 1163 } 1164 return false; 1165 } 1166 #endif 1167 1168 void disconnect(has_slots_interface* pclass) 1169 { 1170 lock_block<mt_policy> lock(this); 1171 typename connections_list::iterator it = m_connected_slots.begin(); 1172 typename connections_list::iterator itEnd = m_connected_slots.end(); 1173 1174 while(it != itEnd) 1175 { 1176 if((*it)->getdest() == pclass) 1177 { 1178 delete *it; 1179 m_connected_slots.erase(it); 1180 pclass->signal_disconnect(this); 1181 return; 1182 } 1183 1184 ++it; 1185 } 1186 } 1187 1188 void slot_disconnect(has_slots_interface* pslot) 1189 { 1190 lock_block<mt_policy> lock(this); 1191 typename connections_list::iterator it = m_connected_slots.begin(); 1192 typename connections_list::iterator itEnd = m_connected_slots.end(); 1193 1194 while(it != itEnd) 1195 { 1196 typename connections_list::iterator itNext = it; 1197 ++itNext; 1198 1199 if((*it)->getdest() == pslot) 1200 { 1201 delete *it; 1202 m_connected_slots.erase(it); 1203 } 1204 1205 it = itNext; 1206 } 1207 } 1208 1209 protected: 1210 connections_list m_connected_slots; 1211 }; 1212 1213 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 1214 class arg5_type, class mt_policy> 1215 class _signal_base5 : public _signal_base<mt_policy> 1216 { 1217 public: 1218 typedef std::list<_connection_base5<arg1_type, arg2_type, arg3_type, 1219 arg4_type, arg5_type, mt_policy> *> connections_list; 1220 1221 _signal_base5() 1222 { 1223 ; 1224 } 1225 1226 _signal_base5(const _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, 1227 arg5_type, mt_policy>& s) 1228 : _signal_base<mt_policy>(s) 1229 { 1230 lock_block<mt_policy> lock(this); 1231 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 1232 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 1233 1234 while(it != itEnd) 1235 { 1236 (*it)->getdest()->signal_connect(this); 1237 m_connected_slots.push_back((*it)->clone()); 1238 1239 ++it; 1240 } 1241 } 1242 1243 void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) 1244 { 1245 lock_block<mt_policy> lock(this); 1246 typename connections_list::iterator it = m_connected_slots.begin(); 1247 typename connections_list::iterator itEnd = m_connected_slots.end(); 1248 1249 while(it != itEnd) 1250 { 1251 if((*it)->getdest() == oldtarget) 1252 { 1253 m_connected_slots.push_back((*it)->duplicate(newtarget)); 1254 } 1255 1256 ++it; 1257 } 1258 } 1259 1260 ~_signal_base5() 1261 { 1262 disconnect_all(); 1263 } 1264 1265 bool is_empty() 1266 { 1267 lock_block<mt_policy> lock(this); 1268 typename connections_list::const_iterator it = m_connected_slots.begin(); 1269 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1270 return it == itEnd; 1271 } 1272 1273 void disconnect_all() 1274 { 1275 lock_block<mt_policy> lock(this); 1276 typename connections_list::const_iterator it = m_connected_slots.begin(); 1277 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1278 1279 while(it != itEnd) 1280 { 1281 (*it)->getdest()->signal_disconnect(this); 1282 delete *it; 1283 1284 ++it; 1285 } 1286 1287 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 1288 } 1289 1290 #ifdef _DEBUG 1291 bool connected(has_slots_interface* pclass) 1292 { 1293 lock_block<mt_policy> lock(this); 1294 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 1295 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1296 while(it != itEnd) 1297 { 1298 itNext = it; 1299 ++itNext; 1300 if ((*it)->getdest() == pclass) 1301 return true; 1302 it = itNext; 1303 } 1304 return false; 1305 } 1306 #endif 1307 1308 void disconnect(has_slots_interface* pclass) 1309 { 1310 lock_block<mt_policy> lock(this); 1311 typename connections_list::iterator it = m_connected_slots.begin(); 1312 typename connections_list::iterator itEnd = m_connected_slots.end(); 1313 1314 while(it != itEnd) 1315 { 1316 if((*it)->getdest() == pclass) 1317 { 1318 delete *it; 1319 m_connected_slots.erase(it); 1320 pclass->signal_disconnect(this); 1321 return; 1322 } 1323 1324 ++it; 1325 } 1326 } 1327 1328 void slot_disconnect(has_slots_interface* pslot) 1329 { 1330 lock_block<mt_policy> lock(this); 1331 typename connections_list::iterator it = m_connected_slots.begin(); 1332 typename connections_list::iterator itEnd = m_connected_slots.end(); 1333 1334 while(it != itEnd) 1335 { 1336 typename connections_list::iterator itNext = it; 1337 ++itNext; 1338 1339 if((*it)->getdest() == pslot) 1340 { 1341 delete *it; 1342 m_connected_slots.erase(it); 1343 } 1344 1345 it = itNext; 1346 } 1347 } 1348 1349 protected: 1350 connections_list m_connected_slots; 1351 }; 1352 1353 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 1354 class arg5_type, class arg6_type, class mt_policy> 1355 class _signal_base6 : public _signal_base<mt_policy> 1356 { 1357 public: 1358 typedef std::list<_connection_base6<arg1_type, arg2_type, arg3_type, 1359 arg4_type, arg5_type, arg6_type, mt_policy> *> connections_list; 1360 1361 _signal_base6() 1362 { 1363 ; 1364 } 1365 1366 _signal_base6(const _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, 1367 arg5_type, arg6_type, mt_policy>& s) 1368 : _signal_base<mt_policy>(s) 1369 { 1370 lock_block<mt_policy> lock(this); 1371 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 1372 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 1373 1374 while(it != itEnd) 1375 { 1376 (*it)->getdest()->signal_connect(this); 1377 m_connected_slots.push_back((*it)->clone()); 1378 1379 ++it; 1380 } 1381 } 1382 1383 void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) 1384 { 1385 lock_block<mt_policy> lock(this); 1386 typename connections_list::iterator it = m_connected_slots.begin(); 1387 typename connections_list::iterator itEnd = m_connected_slots.end(); 1388 1389 while(it != itEnd) 1390 { 1391 if((*it)->getdest() == oldtarget) 1392 { 1393 m_connected_slots.push_back((*it)->duplicate(newtarget)); 1394 } 1395 1396 ++it; 1397 } 1398 } 1399 1400 ~_signal_base6() 1401 { 1402 disconnect_all(); 1403 } 1404 1405 bool is_empty() 1406 { 1407 lock_block<mt_policy> lock(this); 1408 typename connections_list::const_iterator it = m_connected_slots.begin(); 1409 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1410 return it == itEnd; 1411 } 1412 1413 void disconnect_all() 1414 { 1415 lock_block<mt_policy> lock(this); 1416 typename connections_list::const_iterator it = m_connected_slots.begin(); 1417 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1418 1419 while(it != itEnd) 1420 { 1421 (*it)->getdest()->signal_disconnect(this); 1422 delete *it; 1423 1424 ++it; 1425 } 1426 1427 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 1428 } 1429 1430 #ifdef _DEBUG 1431 bool connected(has_slots_interface* pclass) 1432 { 1433 lock_block<mt_policy> lock(this); 1434 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 1435 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1436 while(it != itEnd) 1437 { 1438 itNext = it; 1439 ++itNext; 1440 if ((*it)->getdest() == pclass) 1441 return true; 1442 it = itNext; 1443 } 1444 return false; 1445 } 1446 #endif 1447 1448 void disconnect(has_slots_interface* pclass) 1449 { 1450 lock_block<mt_policy> lock(this); 1451 typename connections_list::iterator it = m_connected_slots.begin(); 1452 typename connections_list::iterator itEnd = m_connected_slots.end(); 1453 1454 while(it != itEnd) 1455 { 1456 if((*it)->getdest() == pclass) 1457 { 1458 delete *it; 1459 m_connected_slots.erase(it); 1460 pclass->signal_disconnect(this); 1461 return; 1462 } 1463 1464 ++it; 1465 } 1466 } 1467 1468 void slot_disconnect(has_slots_interface* pslot) 1469 { 1470 lock_block<mt_policy> lock(this); 1471 typename connections_list::iterator it = m_connected_slots.begin(); 1472 typename connections_list::iterator itEnd = m_connected_slots.end(); 1473 1474 while(it != itEnd) 1475 { 1476 typename connections_list::iterator itNext = it; 1477 ++itNext; 1478 1479 if((*it)->getdest() == pslot) 1480 { 1481 delete *it; 1482 m_connected_slots.erase(it); 1483 } 1484 1485 it = itNext; 1486 } 1487 } 1488 1489 protected: 1490 connections_list m_connected_slots; 1491 }; 1492 1493 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 1494 class arg5_type, class arg6_type, class arg7_type, class mt_policy> 1495 class _signal_base7 : public _signal_base<mt_policy> 1496 { 1497 public: 1498 typedef std::list<_connection_base7<arg1_type, arg2_type, arg3_type, 1499 arg4_type, arg5_type, arg6_type, arg7_type, mt_policy> *> connections_list; 1500 1501 _signal_base7() 1502 { 1503 ; 1504 } 1505 1506 _signal_base7(const _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, 1507 arg5_type, arg6_type, arg7_type, mt_policy>& s) 1508 : _signal_base<mt_policy>(s) 1509 { 1510 lock_block<mt_policy> lock(this); 1511 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 1512 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 1513 1514 while(it != itEnd) 1515 { 1516 (*it)->getdest()->signal_connect(this); 1517 m_connected_slots.push_back((*it)->clone()); 1518 1519 ++it; 1520 } 1521 } 1522 1523 void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) 1524 { 1525 lock_block<mt_policy> lock(this); 1526 typename connections_list::iterator it = m_connected_slots.begin(); 1527 typename connections_list::iterator itEnd = m_connected_slots.end(); 1528 1529 while(it != itEnd) 1530 { 1531 if((*it)->getdest() == oldtarget) 1532 { 1533 m_connected_slots.push_back((*it)->duplicate(newtarget)); 1534 } 1535 1536 ++it; 1537 } 1538 } 1539 1540 ~_signal_base7() 1541 { 1542 disconnect_all(); 1543 } 1544 1545 bool is_empty() 1546 { 1547 lock_block<mt_policy> lock(this); 1548 typename connections_list::const_iterator it = m_connected_slots.begin(); 1549 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1550 return it == itEnd; 1551 } 1552 1553 void disconnect_all() 1554 { 1555 lock_block<mt_policy> lock(this); 1556 typename connections_list::const_iterator it = m_connected_slots.begin(); 1557 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1558 1559 while(it != itEnd) 1560 { 1561 (*it)->getdest()->signal_disconnect(this); 1562 delete *it; 1563 1564 ++it; 1565 } 1566 1567 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 1568 } 1569 1570 #ifdef _DEBUG 1571 bool connected(has_slots_interface* pclass) 1572 { 1573 lock_block<mt_policy> lock(this); 1574 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 1575 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1576 while(it != itEnd) 1577 { 1578 itNext = it; 1579 ++itNext; 1580 if ((*it)->getdest() == pclass) 1581 return true; 1582 it = itNext; 1583 } 1584 return false; 1585 } 1586 #endif 1587 1588 void disconnect(has_slots_interface* pclass) 1589 { 1590 lock_block<mt_policy> lock(this); 1591 typename connections_list::iterator it = m_connected_slots.begin(); 1592 typename connections_list::iterator itEnd = m_connected_slots.end(); 1593 1594 while(it != itEnd) 1595 { 1596 if((*it)->getdest() == pclass) 1597 { 1598 delete *it; 1599 m_connected_slots.erase(it); 1600 pclass->signal_disconnect(this); 1601 return; 1602 } 1603 1604 ++it; 1605 } 1606 } 1607 1608 void slot_disconnect(has_slots_interface* pslot) 1609 { 1610 lock_block<mt_policy> lock(this); 1611 typename connections_list::iterator it = m_connected_slots.begin(); 1612 typename connections_list::iterator itEnd = m_connected_slots.end(); 1613 1614 while(it != itEnd) 1615 { 1616 typename connections_list::iterator itNext = it; 1617 ++itNext; 1618 1619 if((*it)->getdest() == pslot) 1620 { 1621 delete *it; 1622 m_connected_slots.erase(it); 1623 } 1624 1625 it = itNext; 1626 } 1627 } 1628 1629 protected: 1630 connections_list m_connected_slots; 1631 }; 1632 1633 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 1634 class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy> 1635 class _signal_base8 : public _signal_base<mt_policy> 1636 { 1637 public: 1638 typedef std::list<_connection_base8<arg1_type, arg2_type, arg3_type, 1639 arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> *> 1640 connections_list; 1641 1642 _signal_base8() 1643 { 1644 ; 1645 } 1646 1647 _signal_base8(const _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, 1648 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s) 1649 : _signal_base<mt_policy>(s) 1650 { 1651 lock_block<mt_policy> lock(this); 1652 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 1653 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 1654 1655 while(it != itEnd) 1656 { 1657 (*it)->getdest()->signal_connect(this); 1658 m_connected_slots.push_back((*it)->clone()); 1659 1660 ++it; 1661 } 1662 } 1663 1664 void slot_duplicate(const has_slots_interface* oldtarget, has_slots_interface* newtarget) 1665 { 1666 lock_block<mt_policy> lock(this); 1667 typename connections_list::iterator it = m_connected_slots.begin(); 1668 typename connections_list::iterator itEnd = m_connected_slots.end(); 1669 1670 while(it != itEnd) 1671 { 1672 if((*it)->getdest() == oldtarget) 1673 { 1674 m_connected_slots.push_back((*it)->duplicate(newtarget)); 1675 } 1676 1677 ++it; 1678 } 1679 } 1680 1681 ~_signal_base8() 1682 { 1683 disconnect_all(); 1684 } 1685 1686 bool is_empty() 1687 { 1688 lock_block<mt_policy> lock(this); 1689 typename connections_list::const_iterator it = m_connected_slots.begin(); 1690 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1691 return it == itEnd; 1692 } 1693 1694 void disconnect_all() 1695 { 1696 lock_block<mt_policy> lock(this); 1697 typename connections_list::const_iterator it = m_connected_slots.begin(); 1698 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1699 1700 while(it != itEnd) 1701 { 1702 (*it)->getdest()->signal_disconnect(this); 1703 delete *it; 1704 1705 ++it; 1706 } 1707 1708 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 1709 } 1710 1711 #ifdef _DEBUG 1712 bool connected(has_slots_interface* pclass) 1713 { 1714 lock_block<mt_policy> lock(this); 1715 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 1716 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 1717 while(it != itEnd) 1718 { 1719 itNext = it; 1720 ++itNext; 1721 if ((*it)->getdest() == pclass) 1722 return true; 1723 it = itNext; 1724 } 1725 return false; 1726 } 1727 #endif 1728 1729 void disconnect(has_slots_interface* pclass) 1730 { 1731 lock_block<mt_policy> lock(this); 1732 typename connections_list::iterator it = m_connected_slots.begin(); 1733 typename connections_list::iterator itEnd = m_connected_slots.end(); 1734 1735 while(it != itEnd) 1736 { 1737 if((*it)->getdest() == pclass) 1738 { 1739 delete *it; 1740 m_connected_slots.erase(it); 1741 pclass->signal_disconnect(this); 1742 return; 1743 } 1744 1745 ++it; 1746 } 1747 } 1748 1749 void slot_disconnect(has_slots_interface* pslot) 1750 { 1751 lock_block<mt_policy> lock(this); 1752 typename connections_list::iterator it = m_connected_slots.begin(); 1753 typename connections_list::iterator itEnd = m_connected_slots.end(); 1754 1755 while(it != itEnd) 1756 { 1757 typename connections_list::iterator itNext = it; 1758 ++itNext; 1759 1760 if((*it)->getdest() == pslot) 1761 { 1762 delete *it; 1763 m_connected_slots.erase(it); 1764 } 1765 1766 it = itNext; 1767 } 1768 } 1769 1770 protected: 1771 connections_list m_connected_slots; 1772 }; 1773 1774 1775 template<class dest_type, class mt_policy> 1776 class _connection0 : public _connection_base0<mt_policy> 1777 { 1778 public: 1779 _connection0() 1780 { 1781 m_pobject = NULL; 1782 m_pmemfun = NULL; 1783 } 1784 1785 _connection0(dest_type* pobject, void (dest_type::*pmemfun)()) 1786 { 1787 m_pobject = pobject; 1788 m_pmemfun = pmemfun; 1789 } 1790 1791 virtual ~_connection0() 1792 { 1793 } 1794 1795 virtual _connection_base0<mt_policy>* clone() 1796 { 1797 return new _connection0<dest_type, mt_policy>(*this); 1798 } 1799 1800 virtual _connection_base0<mt_policy>* duplicate(has_slots_interface* pnewdest) 1801 { 1802 return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 1803 } 1804 1805 virtual void emit() 1806 { 1807 (m_pobject->*m_pmemfun)(); 1808 } 1809 1810 virtual has_slots_interface* getdest() const 1811 { 1812 return m_pobject; 1813 } 1814 1815 private: 1816 dest_type* m_pobject; 1817 void (dest_type::* m_pmemfun)(); 1818 }; 1819 1820 template<class dest_type, class arg1_type, class mt_policy> 1821 class _connection1 : public _connection_base1<arg1_type, mt_policy> 1822 { 1823 public: 1824 _connection1() 1825 { 1826 m_pobject = NULL; 1827 m_pmemfun = NULL; 1828 } 1829 1830 _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type)) 1831 { 1832 m_pobject = pobject; 1833 m_pmemfun = pmemfun; 1834 } 1835 1836 virtual ~_connection1() 1837 { 1838 } 1839 1840 virtual _connection_base1<arg1_type, mt_policy>* clone() 1841 { 1842 return new _connection1<dest_type, arg1_type, mt_policy>(*this); 1843 } 1844 1845 virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots_interface* pnewdest) 1846 { 1847 return new _connection1<dest_type, arg1_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 1848 } 1849 1850 virtual void emit(arg1_type a1) 1851 { 1852 (m_pobject->*m_pmemfun)(a1); 1853 } 1854 1855 virtual has_slots_interface* getdest() const 1856 { 1857 return m_pobject; 1858 } 1859 1860 private: 1861 dest_type* m_pobject; 1862 void (dest_type::* m_pmemfun)(arg1_type); 1863 }; 1864 1865 template<class dest_type, class arg1_type, class arg2_type, class mt_policy> 1866 class _connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy> 1867 { 1868 public: 1869 _connection2() 1870 { 1871 m_pobject = NULL; 1872 m_pmemfun = NULL; 1873 } 1874 1875 _connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, 1876 arg2_type)) 1877 { 1878 m_pobject = pobject; 1879 m_pmemfun = pmemfun; 1880 } 1881 1882 virtual ~_connection2() 1883 { 1884 } 1885 1886 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() 1887 { 1888 return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(*this); 1889 } 1890 1891 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots_interface* pnewdest) 1892 { 1893 return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 1894 } 1895 1896 virtual void emit(arg1_type a1, arg2_type a2) 1897 { 1898 (m_pobject->*m_pmemfun)(a1, a2); 1899 } 1900 1901 virtual has_slots_interface* getdest() const 1902 { 1903 return m_pobject; 1904 } 1905 1906 private: 1907 dest_type* m_pobject; 1908 void (dest_type::* m_pmemfun)(arg1_type, arg2_type); 1909 }; 1910 1911 template<class dest_type, class arg1_type, class arg2_type, class arg3_type, class mt_policy> 1912 class _connection3 : public _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy> 1913 { 1914 public: 1915 _connection3() 1916 { 1917 m_pobject = NULL; 1918 m_pmemfun = NULL; 1919 } 1920 1921 _connection3(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, 1922 arg2_type, arg3_type)) 1923 { 1924 m_pobject = pobject; 1925 m_pmemfun = pmemfun; 1926 } 1927 1928 virtual ~_connection3() 1929 { 1930 } 1931 1932 virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone() 1933 { 1934 return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>(*this); 1935 } 1936 1937 virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots_interface* pnewdest) 1938 { 1939 return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 1940 } 1941 1942 virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3) 1943 { 1944 (m_pobject->*m_pmemfun)(a1, a2, a3); 1945 } 1946 1947 virtual has_slots_interface* getdest() const 1948 { 1949 return m_pobject; 1950 } 1951 1952 private: 1953 dest_type* m_pobject; 1954 void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type); 1955 }; 1956 1957 template<class dest_type, class arg1_type, class arg2_type, class arg3_type, 1958 class arg4_type, class mt_policy> 1959 class _connection4 : public _connection_base4<arg1_type, arg2_type, 1960 arg3_type, arg4_type, mt_policy> 1961 { 1962 public: 1963 _connection4() 1964 { 1965 m_pobject = NULL; 1966 m_pmemfun = NULL; 1967 } 1968 1969 _connection4(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, 1970 arg2_type, arg3_type, arg4_type)) 1971 { 1972 m_pobject = pobject; 1973 m_pmemfun = pmemfun; 1974 } 1975 1976 virtual ~_connection4() 1977 { 1978 } 1979 1980 virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone() 1981 { 1982 return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(*this); 1983 } 1984 1985 virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots_interface* pnewdest) 1986 { 1987 return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 1988 } 1989 1990 virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, 1991 arg4_type a4) 1992 { 1993 (m_pobject->*m_pmemfun)(a1, a2, a3, a4); 1994 } 1995 1996 virtual has_slots_interface* getdest() const 1997 { 1998 return m_pobject; 1999 } 2000 2001 private: 2002 dest_type* m_pobject; 2003 void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, 2004 arg4_type); 2005 }; 2006 2007 template<class dest_type, class arg1_type, class arg2_type, class arg3_type, 2008 class arg4_type, class arg5_type, class mt_policy> 2009 class _connection5 : public _connection_base5<arg1_type, arg2_type, 2010 arg3_type, arg4_type, arg5_type, mt_policy> 2011 { 2012 public: 2013 _connection5() 2014 { 2015 m_pobject = NULL; 2016 m_pmemfun = NULL; 2017 } 2018 2019 _connection5(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, 2020 arg2_type, arg3_type, arg4_type, arg5_type)) 2021 { 2022 m_pobject = pobject; 2023 m_pmemfun = pmemfun; 2024 } 2025 2026 virtual ~_connection5() 2027 { 2028 } 2029 2030 virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, 2031 arg5_type, mt_policy>* clone() 2032 { 2033 return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 2034 arg5_type, mt_policy>(*this); 2035 } 2036 2037 virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, 2038 arg5_type, mt_policy>* duplicate(has_slots_interface* pnewdest) 2039 { 2040 return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 2041 arg5_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 2042 } 2043 2044 virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2045 arg5_type a5) 2046 { 2047 (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5); 2048 } 2049 2050 virtual has_slots_interface* getdest() const 2051 { 2052 return m_pobject; 2053 } 2054 2055 private: 2056 dest_type* m_pobject; 2057 void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, 2058 arg5_type); 2059 }; 2060 2061 template<class dest_type, class arg1_type, class arg2_type, class arg3_type, 2062 class arg4_type, class arg5_type, class arg6_type, class mt_policy> 2063 class _connection6 : public _connection_base6<arg1_type, arg2_type, 2064 arg3_type, arg4_type, arg5_type, arg6_type, mt_policy> 2065 { 2066 public: 2067 _connection6() 2068 { 2069 m_pobject = NULL; 2070 m_pmemfun = NULL; 2071 } 2072 2073 _connection6(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, 2074 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type)) 2075 { 2076 m_pobject = pobject; 2077 m_pmemfun = pmemfun; 2078 } 2079 2080 virtual ~_connection6() 2081 { 2082 } 2083 2084 virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, 2085 arg5_type, arg6_type, mt_policy>* clone() 2086 { 2087 return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 2088 arg5_type, arg6_type, mt_policy>(*this); 2089 } 2090 2091 virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, 2092 arg5_type, arg6_type, mt_policy>* duplicate(has_slots_interface* pnewdest) 2093 { 2094 return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 2095 arg5_type, arg6_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 2096 } 2097 2098 virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2099 arg5_type a5, arg6_type a6) 2100 { 2101 (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6); 2102 } 2103 2104 virtual has_slots_interface* getdest() const 2105 { 2106 return m_pobject; 2107 } 2108 2109 private: 2110 dest_type* m_pobject; 2111 void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, 2112 arg5_type, arg6_type); 2113 }; 2114 2115 template<class dest_type, class arg1_type, class arg2_type, class arg3_type, 2116 class arg4_type, class arg5_type, class arg6_type, class arg7_type, class mt_policy> 2117 class _connection7 : public _connection_base7<arg1_type, arg2_type, 2118 arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, mt_policy> 2119 { 2120 public: 2121 _connection7() 2122 { 2123 m_pobject = NULL; 2124 m_pmemfun = NULL; 2125 } 2126 2127 _connection7(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, 2128 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type)) 2129 { 2130 m_pobject = pobject; 2131 m_pmemfun = pmemfun; 2132 } 2133 2134 virtual ~_connection7() 2135 { 2136 } 2137 2138 virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, 2139 arg5_type, arg6_type, arg7_type, mt_policy>* clone() 2140 { 2141 return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 2142 arg5_type, arg6_type, arg7_type, mt_policy>(*this); 2143 } 2144 2145 virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, 2146 arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots_interface* pnewdest) 2147 { 2148 return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 2149 arg5_type, arg6_type, arg7_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 2150 } 2151 2152 virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2153 arg5_type a5, arg6_type a6, arg7_type a7) 2154 { 2155 (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7); 2156 } 2157 2158 virtual has_slots_interface* getdest() const 2159 { 2160 return m_pobject; 2161 } 2162 2163 private: 2164 dest_type* m_pobject; 2165 void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, 2166 arg5_type, arg6_type, arg7_type); 2167 }; 2168 2169 template<class dest_type, class arg1_type, class arg2_type, class arg3_type, 2170 class arg4_type, class arg5_type, class arg6_type, class arg7_type, 2171 class arg8_type, class mt_policy> 2172 class _connection8 : public _connection_base8<arg1_type, arg2_type, 2173 arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> 2174 { 2175 public: 2176 _connection8() 2177 { 2178 m_pobject = NULL; 2179 m_pmemfun = NULL; 2180 } 2181 2182 _connection8(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, 2183 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, 2184 arg7_type, arg8_type)) 2185 { 2186 m_pobject = pobject; 2187 m_pmemfun = pmemfun; 2188 } 2189 2190 virtual ~_connection8() 2191 { 2192 } 2193 2194 virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, 2195 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone() 2196 { 2197 return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 2198 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(*this); 2199 } 2200 2201 virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, 2202 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots_interface* pnewdest) 2203 { 2204 return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 2205 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 2206 } 2207 2208 virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2209 arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) 2210 { 2211 (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7, a8); 2212 } 2213 2214 virtual has_slots_interface* getdest() const 2215 { 2216 return m_pobject; 2217 } 2218 2219 private: 2220 dest_type* m_pobject; 2221 void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, 2222 arg5_type, arg6_type, arg7_type, arg8_type); 2223 }; 2224 2225 template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 2226 class signal0 : public _signal_base0<mt_policy> 2227 { 2228 public: 2229 typedef _signal_base0<mt_policy> base; 2230 typedef typename base::connections_list connections_list; 2231 using base::m_connected_slots; 2232 2233 signal0() 2234 { 2235 ; 2236 } 2237 2238 signal0(const signal0<mt_policy>& s) 2239 : _signal_base0<mt_policy>(s) 2240 { 2241 ; 2242 } 2243 2244 template<class desttype> 2245 void connect(desttype* pclass, void (desttype::*pmemfun)()) 2246 { 2247 lock_block<mt_policy> lock(this); 2248 _connection0<desttype, mt_policy>* conn = 2249 new _connection0<desttype, mt_policy>(pclass, pmemfun); 2250 m_connected_slots.push_back(conn); 2251 pclass->signal_connect(this); 2252 } 2253 2254 void emit() 2255 { 2256 lock_block<mt_policy> lock(this); 2257 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2258 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2259 2260 while(it != itEnd) 2261 { 2262 itNext = it; 2263 ++itNext; 2264 2265 (*it)->emit(); 2266 2267 it = itNext; 2268 } 2269 } 2270 2271 void operator()() 2272 { 2273 lock_block<mt_policy> lock(this); 2274 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2275 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2276 2277 while(it != itEnd) 2278 { 2279 itNext = it; 2280 ++itNext; 2281 2282 (*it)->emit(); 2283 2284 it = itNext; 2285 } 2286 } 2287 }; 2288 2289 template<class arg1_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 2290 class signal1 : public _signal_base1<arg1_type, mt_policy> 2291 { 2292 public: 2293 typedef _signal_base1<arg1_type, mt_policy> base; 2294 typedef typename base::connections_list connections_list; 2295 using base::m_connected_slots; 2296 2297 signal1() 2298 { 2299 ; 2300 } 2301 2302 signal1(const signal1<arg1_type, mt_policy>& s) 2303 : _signal_base1<arg1_type, mt_policy>(s) 2304 { 2305 ; 2306 } 2307 2308 template<class desttype> 2309 void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type)) 2310 { 2311 lock_block<mt_policy> lock(this); 2312 _connection1<desttype, arg1_type, mt_policy>* conn = 2313 new _connection1<desttype, arg1_type, mt_policy>(pclass, pmemfun); 2314 m_connected_slots.push_back(conn); 2315 pclass->signal_connect(this); 2316 } 2317 2318 void emit(arg1_type a1) 2319 { 2320 lock_block<mt_policy> lock(this); 2321 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2322 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2323 2324 while(it != itEnd) 2325 { 2326 itNext = it; 2327 ++itNext; 2328 2329 (*it)->emit(a1); 2330 2331 it = itNext; 2332 } 2333 } 2334 2335 void operator()(arg1_type a1) 2336 { 2337 lock_block<mt_policy> lock(this); 2338 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2339 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2340 2341 while(it != itEnd) 2342 { 2343 itNext = it; 2344 ++itNext; 2345 2346 (*it)->emit(a1); 2347 2348 it = itNext; 2349 } 2350 } 2351 }; 2352 2353 template<class arg1_type, class arg2_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 2354 class signal2 : public _signal_base2<arg1_type, arg2_type, mt_policy> 2355 { 2356 public: 2357 typedef _signal_base2<arg1_type, arg2_type, mt_policy> base; 2358 typedef typename base::connections_list connections_list; 2359 using base::m_connected_slots; 2360 2361 signal2() 2362 { 2363 ; 2364 } 2365 2366 signal2(const signal2<arg1_type, arg2_type, mt_policy>& s) 2367 : _signal_base2<arg1_type, arg2_type, mt_policy>(s) 2368 { 2369 ; 2370 } 2371 2372 template<class desttype> 2373 void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, 2374 arg2_type)) 2375 { 2376 lock_block<mt_policy> lock(this); 2377 _connection2<desttype, arg1_type, arg2_type, mt_policy>* conn = new 2378 _connection2<desttype, arg1_type, arg2_type, mt_policy>(pclass, pmemfun); 2379 m_connected_slots.push_back(conn); 2380 pclass->signal_connect(this); 2381 } 2382 2383 void emit(arg1_type a1, arg2_type a2) 2384 { 2385 lock_block<mt_policy> lock(this); 2386 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2387 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2388 2389 while(it != itEnd) 2390 { 2391 itNext = it; 2392 ++itNext; 2393 2394 (*it)->emit(a1, a2); 2395 2396 it = itNext; 2397 } 2398 } 2399 2400 void operator()(arg1_type a1, arg2_type a2) 2401 { 2402 lock_block<mt_policy> lock(this); 2403 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2404 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2405 2406 while(it != itEnd) 2407 { 2408 itNext = it; 2409 ++itNext; 2410 2411 (*it)->emit(a1, a2); 2412 2413 it = itNext; 2414 } 2415 } 2416 }; 2417 2418 template<class arg1_type, class arg2_type, class arg3_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 2419 class signal3 : public _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy> 2420 { 2421 public: 2422 typedef _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy> base; 2423 typedef typename base::connections_list connections_list; 2424 using base::m_connected_slots; 2425 2426 signal3() 2427 { 2428 ; 2429 } 2430 2431 signal3(const signal3<arg1_type, arg2_type, arg3_type, mt_policy>& s) 2432 : _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>(s) 2433 { 2434 ; 2435 } 2436 2437 template<class desttype> 2438 void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, 2439 arg2_type, arg3_type)) 2440 { 2441 lock_block<mt_policy> lock(this); 2442 _connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>* conn = 2443 new _connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>(pclass, 2444 pmemfun); 2445 m_connected_slots.push_back(conn); 2446 pclass->signal_connect(this); 2447 } 2448 2449 void emit(arg1_type a1, arg2_type a2, arg3_type a3) 2450 { 2451 lock_block<mt_policy> lock(this); 2452 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2453 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2454 2455 while(it != itEnd) 2456 { 2457 itNext = it; 2458 ++itNext; 2459 2460 (*it)->emit(a1, a2, a3); 2461 2462 it = itNext; 2463 } 2464 } 2465 2466 void operator()(arg1_type a1, arg2_type a2, arg3_type a3) 2467 { 2468 lock_block<mt_policy> lock(this); 2469 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2470 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2471 2472 while(it != itEnd) 2473 { 2474 itNext = it; 2475 ++itNext; 2476 2477 (*it)->emit(a1, a2, a3); 2478 2479 it = itNext; 2480 } 2481 } 2482 }; 2483 2484 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 2485 class signal4 : public _signal_base4<arg1_type, arg2_type, arg3_type, 2486 arg4_type, mt_policy> 2487 { 2488 public: 2489 typedef _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy> base; 2490 typedef typename base::connections_list connections_list; 2491 using base::m_connected_slots; 2492 2493 signal4() 2494 { 2495 ; 2496 } 2497 2498 signal4(const signal4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s) 2499 : _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(s) 2500 { 2501 ; 2502 } 2503 2504 template<class desttype> 2505 void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, 2506 arg2_type, arg3_type, arg4_type)) 2507 { 2508 lock_block<mt_policy> lock(this); 2509 _connection4<desttype, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* 2510 conn = new _connection4<desttype, arg1_type, arg2_type, arg3_type, 2511 arg4_type, mt_policy>(pclass, pmemfun); 2512 m_connected_slots.push_back(conn); 2513 pclass->signal_connect(this); 2514 } 2515 2516 void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) 2517 { 2518 lock_block<mt_policy> lock(this); 2519 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2520 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2521 2522 while(it != itEnd) 2523 { 2524 itNext = it; 2525 ++itNext; 2526 2527 (*it)->emit(a1, a2, a3, a4); 2528 2529 it = itNext; 2530 } 2531 } 2532 2533 void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) 2534 { 2535 lock_block<mt_policy> lock(this); 2536 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2537 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2538 2539 while(it != itEnd) 2540 { 2541 itNext = it; 2542 ++itNext; 2543 2544 (*it)->emit(a1, a2, a3, a4); 2545 2546 it = itNext; 2547 } 2548 } 2549 }; 2550 2551 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 2552 class arg5_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 2553 class signal5 : public _signal_base5<arg1_type, arg2_type, arg3_type, 2554 arg4_type, arg5_type, mt_policy> 2555 { 2556 public: 2557 typedef _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, mt_policy> base; 2558 typedef typename base::connections_list connections_list; 2559 using base::m_connected_slots; 2560 2561 signal5() 2562 { 2563 ; 2564 } 2565 2566 signal5(const signal5<arg1_type, arg2_type, arg3_type, arg4_type, 2567 arg5_type, mt_policy>& s) 2568 : _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, 2569 arg5_type, mt_policy>(s) 2570 { 2571 ; 2572 } 2573 2574 template<class desttype> 2575 void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, 2576 arg2_type, arg3_type, arg4_type, arg5_type)) 2577 { 2578 lock_block<mt_policy> lock(this); 2579 _connection5<desttype, arg1_type, arg2_type, arg3_type, arg4_type, 2580 arg5_type, mt_policy>* conn = new _connection5<desttype, arg1_type, arg2_type, 2581 arg3_type, arg4_type, arg5_type, mt_policy>(pclass, pmemfun); 2582 m_connected_slots.push_back(conn); 2583 pclass->signal_connect(this); 2584 } 2585 2586 void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2587 arg5_type a5) 2588 { 2589 lock_block<mt_policy> lock(this); 2590 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2591 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2592 2593 while(it != itEnd) 2594 { 2595 itNext = it; 2596 ++itNext; 2597 2598 (*it)->emit(a1, a2, a3, a4, a5); 2599 2600 it = itNext; 2601 } 2602 } 2603 2604 void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2605 arg5_type a5) 2606 { 2607 lock_block<mt_policy> lock(this); 2608 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2609 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2610 2611 while(it != itEnd) 2612 { 2613 itNext = it; 2614 ++itNext; 2615 2616 (*it)->emit(a1, a2, a3, a4, a5); 2617 2618 it = itNext; 2619 } 2620 } 2621 }; 2622 2623 2624 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 2625 class arg5_type, class arg6_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 2626 class signal6 : public _signal_base6<arg1_type, arg2_type, arg3_type, 2627 arg4_type, arg5_type, arg6_type, mt_policy> 2628 { 2629 public: 2630 typedef _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, mt_policy> base; 2631 typedef typename base::connections_list connections_list; 2632 using base::m_connected_slots; 2633 2634 signal6() 2635 { 2636 ; 2637 } 2638 2639 signal6(const signal6<arg1_type, arg2_type, arg3_type, arg4_type, 2640 arg5_type, arg6_type, mt_policy>& s) 2641 : _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, 2642 arg5_type, arg6_type, mt_policy>(s) 2643 { 2644 ; 2645 } 2646 2647 template<class desttype> 2648 void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, 2649 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type)) 2650 { 2651 lock_block<mt_policy> lock(this); 2652 _connection6<desttype, arg1_type, arg2_type, arg3_type, arg4_type, 2653 arg5_type, arg6_type, mt_policy>* conn = 2654 new _connection6<desttype, arg1_type, arg2_type, arg3_type, 2655 arg4_type, arg5_type, arg6_type, mt_policy>(pclass, pmemfun); 2656 m_connected_slots.push_back(conn); 2657 pclass->signal_connect(this); 2658 } 2659 2660 void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2661 arg5_type a5, arg6_type a6) 2662 { 2663 lock_block<mt_policy> lock(this); 2664 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2665 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2666 2667 while(it != itEnd) 2668 { 2669 itNext = it; 2670 ++itNext; 2671 2672 (*it)->emit(a1, a2, a3, a4, a5, a6); 2673 2674 it = itNext; 2675 } 2676 } 2677 2678 void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2679 arg5_type a5, arg6_type a6) 2680 { 2681 lock_block<mt_policy> lock(this); 2682 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2683 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2684 2685 while(it != itEnd) 2686 { 2687 itNext = it; 2688 ++itNext; 2689 2690 (*it)->emit(a1, a2, a3, a4, a5, a6); 2691 2692 it = itNext; 2693 } 2694 } 2695 }; 2696 2697 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 2698 class arg5_type, class arg6_type, class arg7_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 2699 class signal7 : public _signal_base7<arg1_type, arg2_type, arg3_type, 2700 arg4_type, arg5_type, arg6_type, arg7_type, mt_policy> 2701 { 2702 public: 2703 typedef _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, 2704 arg5_type, arg6_type, arg7_type, mt_policy> base; 2705 typedef typename base::connections_list connections_list; 2706 using base::m_connected_slots; 2707 2708 signal7() 2709 { 2710 ; 2711 } 2712 2713 signal7(const signal7<arg1_type, arg2_type, arg3_type, arg4_type, 2714 arg5_type, arg6_type, arg7_type, mt_policy>& s) 2715 : _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, 2716 arg5_type, arg6_type, arg7_type, mt_policy>(s) 2717 { 2718 ; 2719 } 2720 2721 template<class desttype> 2722 void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, 2723 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, 2724 arg7_type)) 2725 { 2726 lock_block<mt_policy> lock(this); 2727 _connection7<desttype, arg1_type, arg2_type, arg3_type, arg4_type, 2728 arg5_type, arg6_type, arg7_type, mt_policy>* conn = 2729 new _connection7<desttype, arg1_type, arg2_type, arg3_type, 2730 arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>(pclass, pmemfun); 2731 m_connected_slots.push_back(conn); 2732 pclass->signal_connect(this); 2733 } 2734 2735 void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2736 arg5_type a5, arg6_type a6, arg7_type a7) 2737 { 2738 lock_block<mt_policy> lock(this); 2739 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2740 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2741 2742 while(it != itEnd) 2743 { 2744 itNext = it; 2745 ++itNext; 2746 2747 (*it)->emit(a1, a2, a3, a4, a5, a6, a7); 2748 2749 it = itNext; 2750 } 2751 } 2752 2753 void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2754 arg5_type a5, arg6_type a6, arg7_type a7) 2755 { 2756 lock_block<mt_policy> lock(this); 2757 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2758 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2759 2760 while(it != itEnd) 2761 { 2762 itNext = it; 2763 ++itNext; 2764 2765 (*it)->emit(a1, a2, a3, a4, a5, a6, a7); 2766 2767 it = itNext; 2768 } 2769 } 2770 }; 2771 2772 template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, 2773 class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 2774 class signal8 : public _signal_base8<arg1_type, arg2_type, arg3_type, 2775 arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> 2776 { 2777 public: 2778 typedef _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, 2779 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> base; 2780 typedef typename base::connections_list connections_list; 2781 using base::m_connected_slots; 2782 2783 signal8() 2784 { 2785 ; 2786 } 2787 2788 signal8(const signal8<arg1_type, arg2_type, arg3_type, arg4_type, 2789 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s) 2790 : _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, 2791 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(s) 2792 { 2793 ; 2794 } 2795 2796 template<class desttype> 2797 void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, 2798 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, 2799 arg7_type, arg8_type)) 2800 { 2801 lock_block<mt_policy> lock(this); 2802 _connection8<desttype, arg1_type, arg2_type, arg3_type, arg4_type, 2803 arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* conn = 2804 new _connection8<desttype, arg1_type, arg2_type, arg3_type, 2805 arg4_type, arg5_type, arg6_type, arg7_type, 2806 arg8_type, mt_policy>(pclass, pmemfun); 2807 m_connected_slots.push_back(conn); 2808 pclass->signal_connect(this); 2809 } 2810 2811 void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2812 arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) 2813 { 2814 lock_block<mt_policy> lock(this); 2815 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2816 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2817 2818 while(it != itEnd) 2819 { 2820 itNext = it; 2821 ++itNext; 2822 2823 (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8); 2824 2825 it = itNext; 2826 } 2827 } 2828 2829 void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, 2830 arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) 2831 { 2832 lock_block<mt_policy> lock(this); 2833 typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); 2834 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 2835 2836 while(it != itEnd) 2837 { 2838 itNext = it; 2839 ++itNext; 2840 2841 (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8); 2842 2843 it = itNext; 2844 } 2845 } 2846 }; 2847 2848 }; // namespace sigslot 2849 2850 #endif // WEBRTC_BASE_SIGSLOT_H__ 2851