1 // sigslot.h: Signal/Slot classes 2 // 3 // Written by Sarah Thompson (sarah@telergy.com) 2002. 4 // Additions by Barnaby Gray (barnaby@pickle.me.uk) 2002. 5 // 6 // License: Public domain. You are free to use this code however you like, with the proviso that 7 // the author takes on no responsibility or liability for any use. 8 // 9 // This file is generated! DO NOT EDIT! 10 // Edit the original sigslot.pl script. 11 // 12 // QUICK DOCUMENTATION 13 // 14 // (see also the full documentation at http://sigslot.sourceforge.net/) 15 // 16 // #define switches 17 // SIGSLOT_PURE_ISO - Define this to force ISO C++ compliance. This also disables 18 // all of the thread safety support on platforms where it is 19 // available. 20 // 21 // SIGSLOT_USE_POSIX_THREADS - Force use of Posix threads when using a C++ compiler other than 22 // gcc on a platform that supports Posix threads. (When using gcc, 23 // this is the default - use SIGSLOT_PURE_ISO to disable this if 24 // necessary) 25 // 26 // SIGSLOT_DEFAULT_MT_POLICY - Where thread support is enabled, this defaults to multi_threaded_global. 27 // Otherwise, the default is single_threaded. #define this yourself to 28 // override the default. In pure ISO mode, anything other than 29 // single_threaded will cause a compiler error. 30 // 31 // PLATFORM NOTES 32 // 33 // Win32 - On Win32, the WIN32 symbol must be #defined. Most mainstream 34 // compilers do this by default, but you may need to define it 35 // yourself if your build environment is less standard. This causes 36 // the Win32 thread support to be compiled in and used automatically. 37 // 38 // Unix/Linux/BSD, etc. - If you're using gcc, it is assumed that you have Posix threads 39 // available, so they are used automatically. You can override this 40 // (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using 41 // something other than gcc but still want to use Posix threads, you 42 // need to #define SIGSLOT_USE_POSIX_THREADS. 43 // 44 // ISO C++ - If none of the supported platforms are detected, or if 45 // SIGSLOT_PURE_ISO is defined, all multithreading support is turned off, 46 // along with any code that might cause a pure ISO C++ environment to 47 // complain. Before you ask, gcc -ansi -pedantic won't compile this 48 // library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of 49 // errors that aren't really there. If you feel like investigating this, 50 // please contact the author. 51 // 52 // 53 // THREADING MODES 54 // 55 // single_threaded - Your program is assumed to be single threaded from the point of view 56 // of signal/slot usage (i.e. all objects using signals and slots are 57 // created and destroyed from a single thread). Behaviour if objects are 58 // destroyed concurrently is undefined (i.e. you'll get the occasional 59 // segmentation fault/memory exception). 60 // 61 // multi_threaded_global - Your program is assumed to be multi threaded. Objects using signals and 62 // slots can be safely created and destroyed from any thread, even when 63 // connections exist. In multi_threaded_global mode, this is achieved by a 64 // single global mutex (actually a critical section on Windows because they 65 // are faster). This option uses less OS resources, but results in more 66 // opportunities for contention, possibly resulting in more context switches 67 // than are strictly necessary. 68 // 69 // multi_threaded_local - Behaviour in this mode is essentially the same as multi_threaded_global, 70 // except that each signal, and each object that inherits has_slots, all 71 // have their own mutex/critical section. In practice, this means that 72 // mutex collisions (and hence context switches) only happen if they are 73 // absolutely essential. However, on some platforms, creating a lot of 74 // mutexes can slow down the whole OS, so use this option with care. 75 // 76 // USING THE LIBRARY 77 // 78 // See the full documentation at http://sigslot.sourceforge.net/ 79 // 80 // 81 82 #ifndef SIGSLOT_H__ 83 #define SIGSLOT_H__ 84 85 #include <set> 86 #include <list> 87 #include <cstddef> 88 89 #if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(SIGSLOT_USE_POSIX_THREADS)) 90 # define _SIGSLOT_SINGLE_THREADED 91 #elif defined(WIN32) 92 # define _SIGSLOT_HAS_WIN32_THREADS 93 # include <windows.h> 94 #elif defined(SIGSLOT_USE_POSIX_THREADS) 95 # define _SIGSLOT_HAS_POSIX_THREADS 96 # include <pthread.h> 97 #else 98 # define _SIGSLOT_SINGLE_THREADED 99 #endif 100 101 #ifndef SIGSLOT_DEFAULT_MT_POLICY 102 # ifdef _SIGSLOT_SINGLE_THREADED 103 # define SIGSLOT_DEFAULT_MT_POLICY single_threaded 104 # else 105 # define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local 106 # endif 107 #endif 108 109 110 namespace sigslot { 111 112 class single_threaded 113 { 114 public: single_threaded()115 single_threaded() 116 { 117 ; 118 } 119 ~single_threaded()120 virtual ~single_threaded() 121 { 122 ; 123 } 124 lock()125 virtual void lock() 126 { 127 ; 128 } 129 unlock()130 virtual void unlock() 131 { 132 ; 133 } 134 }; 135 136 #ifdef _SIGSLOT_HAS_WIN32_THREADS 137 // The multi threading policies only get compiled in if they are enabled. 138 class multi_threaded_global 139 { 140 public: multi_threaded_global()141 multi_threaded_global() 142 { 143 static bool isinitialised = false; 144 145 if(!isinitialised) 146 { 147 InitializeCriticalSection(get_critsec()); 148 isinitialised = true; 149 } 150 } 151 multi_threaded_global(const multi_threaded_global &)152 multi_threaded_global(const multi_threaded_global&) 153 { 154 ; 155 } 156 ~multi_threaded_global()157 virtual ~multi_threaded_global() 158 { 159 ; 160 } 161 lock()162 virtual void lock() 163 { 164 EnterCriticalSection(get_critsec()); 165 } 166 unlock()167 virtual void unlock() 168 { 169 LeaveCriticalSection(get_critsec()); 170 } 171 172 private: get_critsec()173 CRITICAL_SECTION* get_critsec() 174 { 175 static CRITICAL_SECTION g_critsec; 176 return &g_critsec; 177 } 178 }; 179 180 class multi_threaded_local 181 { 182 public: multi_threaded_local()183 multi_threaded_local() 184 { 185 InitializeCriticalSection(&m_critsec); 186 } 187 multi_threaded_local(const multi_threaded_local &)188 multi_threaded_local(const multi_threaded_local&) 189 { 190 InitializeCriticalSection(&m_critsec); 191 } 192 ~multi_threaded_local()193 virtual ~multi_threaded_local() 194 { 195 DeleteCriticalSection(&m_critsec); 196 } 197 lock()198 virtual void lock() 199 { 200 EnterCriticalSection(&m_critsec); 201 } 202 unlock()203 virtual void unlock() 204 { 205 LeaveCriticalSection(&m_critsec); 206 } 207 208 private: 209 CRITICAL_SECTION m_critsec; 210 }; 211 #endif // _SIGSLOT_HAS_WIN32_THREADS 212 213 #ifdef _SIGSLOT_HAS_POSIX_THREADS 214 // The multi threading policies only get compiled in if they are enabled. 215 class multi_threaded_global 216 { 217 public: multi_threaded_global()218 multi_threaded_global() 219 { 220 pthread_mutex_init(get_mutex(), NULL); 221 } 222 multi_threaded_global(const multi_threaded_global &)223 multi_threaded_global(const multi_threaded_global&) 224 { 225 ; 226 } 227 ~multi_threaded_global()228 virtual ~multi_threaded_global() 229 { 230 ; 231 } 232 lock()233 virtual void lock() 234 { 235 pthread_mutex_lock(get_mutex()); 236 } 237 unlock()238 virtual void unlock() 239 { 240 pthread_mutex_unlock(get_mutex()); 241 } 242 243 private: get_mutex()244 pthread_mutex_t* get_mutex() 245 { 246 static pthread_mutex_t g_mutex; 247 return &g_mutex; 248 } 249 }; 250 251 class multi_threaded_local 252 { 253 public: multi_threaded_local()254 multi_threaded_local() 255 { 256 pthread_mutex_init(&m_mutex, NULL); 257 } 258 multi_threaded_local(const multi_threaded_local &)259 multi_threaded_local(const multi_threaded_local&) 260 { 261 pthread_mutex_init(&m_mutex, NULL); 262 } 263 ~multi_threaded_local()264 virtual ~multi_threaded_local() 265 { 266 pthread_mutex_destroy(&m_mutex); 267 } 268 lock()269 virtual void lock() 270 { 271 pthread_mutex_lock(&m_mutex); 272 } 273 unlock()274 virtual void unlock() 275 { 276 pthread_mutex_unlock(&m_mutex); 277 } 278 279 private: 280 pthread_mutex_t m_mutex; 281 }; 282 #endif // _SIGSLOT_HAS_POSIX_THREADS 283 284 template<class mt_policy> 285 class lock_block 286 { 287 public: 288 mt_policy *m_mutex; 289 lock_block(mt_policy * mtx)290 lock_block(mt_policy *mtx) 291 : m_mutex(mtx) 292 { 293 m_mutex->lock(); 294 } 295 ~lock_block()296 ~lock_block() 297 { 298 m_mutex->unlock(); 299 } 300 }; 301 302 template<class mt_policy> 303 class has_slots; 304 305 template<class mt_policy> 306 class _connection_base0 307 { 308 public: 309 virtual has_slots<mt_policy>* getdest() const = 0; 310 virtual void emit() = 0; 311 virtual _connection_base0<mt_policy>* clone() = 0; 312 virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; 313 }; 314 315 template<class arg1_type, class mt_policy> 316 class _connection_base1 317 { 318 public: 319 virtual has_slots<mt_policy>* getdest() const = 0; 320 virtual void emit(arg1_type) = 0; 321 virtual _connection_base1<arg1_type, mt_policy>* clone() = 0; 322 virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; 323 }; 324 325 template<class arg1_type, class arg2_type, class mt_policy> 326 class _connection_base2 327 { 328 public: 329 virtual has_slots<mt_policy>* getdest() const = 0; 330 virtual void emit(arg1_type, arg2_type) = 0; 331 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() = 0; 332 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; 333 }; 334 335 template<class mt_policy> 336 class _signal_base : public has_slots<mt_policy> 337 { 338 public: 339 virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0; 340 virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0; 341 }; 342 343 template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 344 class has_slots : public mt_policy 345 { 346 private: 347 typedef std::set<_signal_base<mt_policy> *> sender_set; 348 typedef typename sender_set::const_iterator const_iterator; 349 350 public: has_slots()351 has_slots() 352 { 353 ; 354 } 355 has_slots(const has_slots & hs)356 has_slots(const has_slots& hs) 357 : mt_policy(hs) 358 { 359 lock_block<mt_policy> lock(this); 360 const_iterator it = hs.m_senders.begin(); 361 const_iterator itEnd = hs.m_senders.end(); 362 363 while(it != itEnd) 364 { 365 (*it)->slot_duplicate(&hs, this); 366 m_senders.insert(*it); 367 ++it; 368 } 369 } 370 signal_connect(_signal_base<mt_policy> * sender)371 void signal_connect(_signal_base<mt_policy>* sender) 372 { 373 lock_block<mt_policy> lock(this); 374 m_senders.insert(sender); 375 } 376 signal_disconnect(_signal_base<mt_policy> * sender)377 void signal_disconnect(_signal_base<mt_policy>* sender) 378 { 379 lock_block<mt_policy> lock(this); 380 m_senders.erase(sender); 381 } 382 ~has_slots()383 virtual ~has_slots() 384 { 385 disconnect_all(); 386 } 387 disconnect_all()388 void disconnect_all() 389 { 390 lock_block<mt_policy> lock(this); 391 const_iterator it = m_senders.begin(); 392 const_iterator itEnd = m_senders.end(); 393 394 while(it != itEnd) 395 { 396 (*it)->slot_disconnect(this); 397 ++it; 398 } 399 400 m_senders.erase(m_senders.begin(), m_senders.end()); 401 } 402 403 private: 404 sender_set m_senders; 405 }; 406 407 template<class mt_policy> 408 class _signal_base0 : public _signal_base<mt_policy> 409 { 410 public: 411 typedef typename std::list<_connection_base0<mt_policy> *> 412 connections_list; 413 _signal_base0()414 _signal_base0() 415 { 416 ; 417 } 418 _signal_base0(const _signal_base0<mt_policy> & s)419 _signal_base0(const _signal_base0<mt_policy>& s) 420 : _signal_base<mt_policy>(s) 421 { 422 lock_block<mt_policy> lock(this); 423 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 424 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 425 426 while(it != itEnd) 427 { 428 (*it)->getdest()->signal_connect(this); 429 m_connected_slots.push_back((*it)->clone()); 430 431 ++it; 432 } 433 } 434 slot_duplicate(const has_slots<mt_policy> * oldtarget,has_slots<mt_policy> * newtarget)435 void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) 436 { 437 lock_block<mt_policy> lock(this); 438 typename connections_list::iterator it = m_connected_slots.begin(); 439 typename connections_list::iterator itEnd = m_connected_slots.end(); 440 441 while(it != itEnd) 442 { 443 if((*it)->getdest() == oldtarget) 444 { 445 m_connected_slots.push_back((*it)->duplicate(newtarget)); 446 } 447 448 ++it; 449 } 450 } 451 ~_signal_base0()452 ~_signal_base0() 453 { 454 disconnect_all(); 455 } 456 disconnect_all()457 void disconnect_all() 458 { 459 lock_block<mt_policy> lock(this); 460 typename connections_list::const_iterator it = m_connected_slots.begin(); 461 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 462 463 while(it != itEnd) 464 { 465 (*it)->getdest()->signal_disconnect(this); 466 delete *it; 467 468 ++it; 469 } 470 471 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 472 } 473 disconnect(has_slots<mt_policy> * pclass)474 void disconnect(has_slots<mt_policy>* pclass) 475 { 476 lock_block<mt_policy> lock(this); 477 typename connections_list::iterator it = m_connected_slots.begin(); 478 typename connections_list::iterator itEnd = m_connected_slots.end(); 479 480 while(it != itEnd) 481 { 482 typename connections_list::iterator itNext = it; 483 ++itNext; 484 485 if((*it)->getdest() == pclass) 486 { 487 delete *it; 488 m_connected_slots.erase(it); 489 pclass->signal_disconnect(this); 490 return; 491 } 492 493 it = itNext; 494 } 495 } 496 slot_disconnect(has_slots<mt_policy> * pslot)497 void slot_disconnect(has_slots<mt_policy>* pslot) 498 { 499 lock_block<mt_policy> lock(this); 500 typename connections_list::iterator it = m_connected_slots.begin(); 501 typename connections_list::iterator itEnd = m_connected_slots.end(); 502 503 while(it != itEnd) 504 { 505 typename connections_list::iterator itNext = it; 506 ++itNext; 507 508 if((*it)->getdest() == pslot) 509 { 510 delete *it; 511 m_connected_slots.erase(it); 512 } 513 514 it = itNext; 515 } 516 } 517 518 protected: 519 connections_list m_connected_slots; 520 }; 521 522 template<class arg1_type, class mt_policy> 523 class _signal_base1 : public _signal_base<mt_policy> 524 { 525 public: 526 typedef typename std::list<_connection_base1<arg1_type, mt_policy> *> 527 connections_list; 528 _signal_base1()529 _signal_base1() 530 { 531 ; 532 } 533 _signal_base1(const _signal_base1<arg1_type,mt_policy> & s)534 _signal_base1(const _signal_base1<arg1_type, mt_policy>& s) 535 : _signal_base<mt_policy>(s) 536 { 537 lock_block<mt_policy> lock(this); 538 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 539 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 540 541 while(it != itEnd) 542 { 543 (*it)->getdest()->signal_connect(this); 544 m_connected_slots.push_back((*it)->clone()); 545 546 ++it; 547 } 548 } 549 slot_duplicate(const has_slots<mt_policy> * oldtarget,has_slots<mt_policy> * newtarget)550 void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) 551 { 552 lock_block<mt_policy> lock(this); 553 typename connections_list::iterator it = m_connected_slots.begin(); 554 typename connections_list::iterator itEnd = m_connected_slots.end(); 555 556 while(it != itEnd) 557 { 558 if((*it)->getdest() == oldtarget) 559 { 560 m_connected_slots.push_back((*it)->duplicate(newtarget)); 561 } 562 563 ++it; 564 } 565 } 566 ~_signal_base1()567 ~_signal_base1() 568 { 569 disconnect_all(); 570 } 571 disconnect_all()572 void disconnect_all() 573 { 574 lock_block<mt_policy> lock(this); 575 typename connections_list::const_iterator it = m_connected_slots.begin(); 576 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 577 578 while(it != itEnd) 579 { 580 (*it)->getdest()->signal_disconnect(this); 581 delete *it; 582 583 ++it; 584 } 585 586 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 587 } 588 disconnect(has_slots<mt_policy> * pclass)589 void disconnect(has_slots<mt_policy>* pclass) 590 { 591 lock_block<mt_policy> lock(this); 592 typename connections_list::iterator it = m_connected_slots.begin(); 593 typename connections_list::iterator itEnd = m_connected_slots.end(); 594 595 while(it != itEnd) 596 { 597 typename connections_list::iterator itNext = it; 598 ++itNext; 599 600 if((*it)->getdest() == pclass) 601 { 602 delete *it; 603 m_connected_slots.erase(it); 604 pclass->signal_disconnect(this); 605 return; 606 } 607 608 it = itNext; 609 } 610 } 611 slot_disconnect(has_slots<mt_policy> * pslot)612 void slot_disconnect(has_slots<mt_policy>* pslot) 613 { 614 lock_block<mt_policy> lock(this); 615 typename connections_list::iterator it = m_connected_slots.begin(); 616 typename connections_list::iterator itEnd = m_connected_slots.end(); 617 618 while(it != itEnd) 619 { 620 typename connections_list::iterator itNext = it; 621 ++itNext; 622 623 if((*it)->getdest() == pslot) 624 { 625 delete *it; 626 m_connected_slots.erase(it); 627 } 628 629 it = itNext; 630 } 631 } 632 633 protected: 634 connections_list m_connected_slots; 635 }; 636 637 template<class arg1_type, class arg2_type, class mt_policy> 638 class _signal_base2 : public _signal_base<mt_policy> 639 { 640 public: 641 typedef typename std::list<_connection_base2<arg1_type, arg2_type, mt_policy> *> 642 connections_list; 643 _signal_base2()644 _signal_base2() 645 { 646 ; 647 } 648 _signal_base2(const _signal_base2<arg1_type,arg2_type,mt_policy> & s)649 _signal_base2(const _signal_base2<arg1_type, arg2_type, mt_policy>& s) 650 : _signal_base<mt_policy>(s) 651 { 652 lock_block<mt_policy> lock(this); 653 typename connections_list::const_iterator it = s.m_connected_slots.begin(); 654 typename connections_list::const_iterator itEnd = s.m_connected_slots.end(); 655 656 while(it != itEnd) 657 { 658 (*it)->getdest()->signal_connect(this); 659 m_connected_slots.push_back((*it)->clone()); 660 661 ++it; 662 } 663 } 664 slot_duplicate(const has_slots<mt_policy> * oldtarget,has_slots<mt_policy> * newtarget)665 void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) 666 { 667 lock_block<mt_policy> lock(this); 668 typename connections_list::iterator it = m_connected_slots.begin(); 669 typename connections_list::iterator itEnd = m_connected_slots.end(); 670 671 while(it != itEnd) 672 { 673 if((*it)->getdest() == oldtarget) 674 { 675 m_connected_slots.push_back((*it)->duplicate(newtarget)); 676 } 677 678 ++it; 679 } 680 } 681 ~_signal_base2()682 ~_signal_base2() 683 { 684 disconnect_all(); 685 } 686 disconnect_all()687 void disconnect_all() 688 { 689 lock_block<mt_policy> lock(this); 690 typename connections_list::const_iterator it = m_connected_slots.begin(); 691 typename connections_list::const_iterator itEnd = m_connected_slots.end(); 692 693 while(it != itEnd) 694 { 695 (*it)->getdest()->signal_disconnect(this); 696 delete *it; 697 698 ++it; 699 } 700 701 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); 702 } 703 disconnect(has_slots<mt_policy> * pclass)704 void disconnect(has_slots<mt_policy>* pclass) 705 { 706 lock_block<mt_policy> lock(this); 707 typename connections_list::iterator it = m_connected_slots.begin(); 708 typename connections_list::iterator itEnd = m_connected_slots.end(); 709 710 while(it != itEnd) 711 { 712 typename connections_list::iterator itNext = it; 713 ++itNext; 714 if((*it)->getdest() == pclass) 715 { 716 delete *it; 717 m_connected_slots.erase(it); 718 pclass->signal_disconnect(this); 719 return; 720 } 721 722 it = itNext; 723 } 724 } 725 slot_disconnect(has_slots<mt_policy> * pslot)726 void slot_disconnect(has_slots<mt_policy>* pslot) 727 { 728 lock_block<mt_policy> lock(this); 729 typename connections_list::iterator it = m_connected_slots.begin(); 730 typename connections_list::iterator itEnd = m_connected_slots.end(); 731 732 while(it != itEnd) 733 { 734 typename connections_list::iterator itNext = it; 735 ++itNext; 736 737 if((*it)->getdest() == pslot) 738 { 739 delete *it; 740 m_connected_slots.erase(it); 741 } 742 743 it = itNext; 744 } 745 } 746 747 protected: 748 connections_list m_connected_slots; 749 }; 750 751 template<class dest_type, class mt_policy> 752 class _connection0 : public _connection_base0<mt_policy> 753 { 754 public: _connection0()755 _connection0() 756 { 757 this->pobject = NULL; 758 this->pmemfun = NULL; 759 } 760 _connection0(dest_type * pobject,void (dest_type::* pmemfun)())761 _connection0(dest_type* pobject, void (dest_type::*pmemfun)()) 762 { 763 m_pobject = pobject; 764 m_pmemfun = pmemfun; 765 } 766 clone()767 virtual _connection_base0<mt_policy>* clone() 768 { 769 return new _connection0<dest_type, mt_policy>(*this); 770 } 771 duplicate(has_slots<mt_policy> * pnewdest)772 virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) 773 { 774 return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 775 } 776 emit()777 virtual void emit() 778 { 779 (m_pobject->*m_pmemfun)(); 780 } 781 getdest()782 virtual has_slots<mt_policy>* getdest() const 783 { 784 return m_pobject; 785 } 786 787 private: 788 dest_type* m_pobject; 789 void (dest_type::* m_pmemfun)(); 790 }; 791 792 template<class dest_type, class arg1_type, class mt_policy> 793 class _connection1 : public _connection_base1<arg1_type, mt_policy> 794 { 795 public: _connection1()796 _connection1() 797 { 798 this->pobject = NULL; 799 this->pmemfun = NULL; 800 } 801 _connection1(dest_type * pobject,void (dest_type::* pmemfun)(arg1_type))802 _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type)) 803 { 804 m_pobject = pobject; 805 m_pmemfun = pmemfun; 806 } 807 clone()808 virtual _connection_base1<arg1_type, mt_policy>* clone() 809 { 810 return new _connection1<dest_type, arg1_type, mt_policy>(*this); 811 } 812 duplicate(has_slots<mt_policy> * pnewdest)813 virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) 814 { 815 return new _connection1<dest_type, arg1_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 816 } 817 emit(arg1_type a1)818 virtual void emit(arg1_type a1) 819 { 820 (m_pobject->*m_pmemfun)(a1); 821 } 822 getdest()823 virtual has_slots<mt_policy>* getdest() const 824 { 825 return m_pobject; 826 } 827 828 private: 829 dest_type* m_pobject; 830 void (dest_type::* m_pmemfun)(arg1_type); 831 }; 832 833 template<class dest_type, class arg1_type, class arg2_type, class mt_policy> 834 class _connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy> 835 { 836 public: _connection2()837 _connection2() 838 { 839 this->pobject = NULL; 840 this->pmemfun = NULL; 841 } 842 _connection2(dest_type * pobject,void (dest_type::* pmemfun)(arg1_type,arg2_type))843 _connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, arg2_type)) 844 { 845 m_pobject = pobject; 846 m_pmemfun = pmemfun; 847 } 848 clone()849 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() 850 { 851 return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(*this); 852 } 853 duplicate(has_slots<mt_policy> * pnewdest)854 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) 855 { 856 return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); 857 } 858 emit(arg1_type a1,arg2_type a2)859 virtual void emit(arg1_type a1, arg2_type a2) 860 { 861 (m_pobject->*m_pmemfun)(a1, a2); 862 } 863 getdest()864 virtual has_slots<mt_policy>* getdest() const 865 { 866 return m_pobject; 867 } 868 869 private: 870 dest_type* m_pobject; 871 void (dest_type::* m_pmemfun)(arg1_type, arg2_type); 872 }; 873 874 template<class mt_policy> 875 class _sig_connection0; 876 template<class arg1_type, class mt_policy> 877 class _sig_connection1; 878 template<class arg1_type, class arg2_type, class mt_policy> 879 class _sig_connection2; 880 template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 881 class signal0 : public _signal_base0<mt_policy> 882 { 883 public: signal0()884 signal0() 885 { 886 ; 887 } 888 signal0(const signal0<mt_policy> & s)889 signal0(const signal0<mt_policy>& s) 890 : _signal_base0<mt_policy>(s) 891 { 892 ; 893 } 894 895 template<class dest_type> connect(dest_type * pclass,void (dest_type::* pmemfun)())896 void connect(dest_type* pclass, void (dest_type::*pmemfun)()) 897 { 898 lock_block<mt_policy> lock(this); 899 _connection0<dest_type, mt_policy>* conn 900 = new _connection0<dest_type, mt_policy>(pclass, pmemfun); 901 this->m_connected_slots.push_back(conn); 902 pclass->signal_connect(this); 903 } 904 connect(signal0<mt_policy> & chainsig)905 void connect(signal0<mt_policy>& chainsig) 906 { 907 lock_block<mt_policy> lock(this); 908 _sig_connection0<mt_policy>* conn = new _sig_connection0<mt_policy>(chainsig); 909 this->m_connected_slots.push_back(conn); 910 chainsig.signal_connect(this); 911 } 912 emit()913 void emit() 914 { 915 lock_block<mt_policy> lock(this); 916 typename _signal_base0< mt_policy >::connections_list::const_iterator itNext, it = this->m_connected_slots.begin(); 917 typename _signal_base0< mt_policy >::connections_list::const_iterator itEnd = this->m_connected_slots.end(); 918 919 while(it != itEnd) 920 { 921 itNext = it; 922 ++itNext; 923 924 (*it)->emit(); 925 926 it = itNext; 927 } 928 } 929 operator()930 void operator()() 931 { 932 lock_block<mt_policy> lock(this); 933 typename _signal_base0< mt_policy >::connections_list::connections_list::const_iterator itNext, it = this->m_connected_slots.begin(); 934 typename _signal_base0< mt_policy >::connections_list::connections_list::const_iterator itEnd = this->m_connected_slots.end(); 935 936 while(it != itEnd) 937 { 938 itNext = it; 939 ++itNext; 940 941 (*it)->emit(); 942 943 it = itNext; 944 } 945 } 946 }; 947 948 template<class arg1_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 949 class signal1 : public _signal_base1<arg1_type, mt_policy> 950 { 951 public: signal1()952 signal1() 953 { 954 ; 955 } 956 signal1(const signal1<arg1_type,mt_policy> & s)957 signal1(const signal1<arg1_type, mt_policy>& s) 958 : _signal_base1<arg1_type, mt_policy>(s) 959 { 960 ; 961 } 962 963 template<class dest_type> connect(dest_type * pclass,void (dest_type::* pmemfun)(arg1_type))964 void connect(dest_type* pclass, void (dest_type::*pmemfun)(arg1_type)) 965 { 966 lock_block<mt_policy> lock(this); 967 _connection1<dest_type, arg1_type, mt_policy>* conn 968 = new _connection1<dest_type, arg1_type, mt_policy>(pclass, pmemfun); 969 this->m_connected_slots.push_back(conn); 970 pclass->signal_connect(this); 971 } 972 connect(signal1<arg1_type,mt_policy> & chainsig)973 void connect(signal1<arg1_type, mt_policy>& chainsig) 974 { 975 lock_block<mt_policy> lock(this); 976 _sig_connection1<arg1_type, mt_policy>* conn = new _sig_connection1<arg1_type, mt_policy>(chainsig); 977 this->m_connected_slots.push_back(conn); 978 chainsig.signal_connect(this); 979 } 980 emit(arg1_type a1)981 void emit(arg1_type a1) 982 { 983 lock_block<mt_policy> lock(this); 984 typename _signal_base1<arg1_type, mt_policy >::connections_list::const_iterator itNext, it = this->m_connected_slots.begin(); 985 typename _signal_base1<arg1_type, mt_policy >::connections_list::const_iterator itEnd = this->m_connected_slots.end(); 986 987 while(it != itEnd) 988 { 989 itNext = it; 990 ++itNext; 991 992 (*it)->emit(a1); 993 994 it = itNext; 995 } 996 } 997 operator()998 void operator()(arg1_type a1) 999 { 1000 lock_block<mt_policy> lock(this); 1001 typename _signal_base1<arg1_type, mt_policy >::connections_list::const_iterator itNext, it = this->m_connected_slots.begin(); 1002 typename _signal_base1<arg1_type, mt_policy >::connections_list::const_iterator itEnd = this->m_connected_slots.end(); 1003 1004 while(it != itEnd) 1005 { 1006 itNext = it; 1007 ++itNext; 1008 1009 (*it)->emit(a1); 1010 1011 it = itNext; 1012 } 1013 } 1014 }; 1015 1016 template<class arg1_type, class arg2_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> 1017 class signal2 : public _signal_base2<arg1_type, arg2_type, mt_policy> 1018 { 1019 public: signal2()1020 signal2() 1021 { 1022 ; 1023 } 1024 signal2(const signal2<arg1_type,arg2_type,mt_policy> & s)1025 signal2(const signal2<arg1_type, arg2_type, mt_policy>& s) 1026 : _signal_base2<arg1_type, arg2_type, mt_policy>(s) 1027 { 1028 ; 1029 } 1030 1031 template<class dest_type> connect(dest_type * pclass,void (dest_type::* pmemfun)(arg1_type,arg2_type))1032 void connect(dest_type* pclass, void (dest_type::*pmemfun)(arg1_type, arg2_type)) 1033 { 1034 lock_block<mt_policy> lock(this); 1035 _connection2<dest_type, arg1_type, arg2_type, mt_policy>* conn 1036 = new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(pclass, pmemfun); 1037 this->m_connected_slots.push_back(conn); 1038 pclass->signal_connect(this); 1039 } 1040 connect(signal2<arg1_type,arg2_type,mt_policy> & chainsig)1041 void connect(signal2<arg1_type, arg2_type, mt_policy>& chainsig) 1042 { 1043 lock_block<mt_policy> lock(this); 1044 _sig_connection2<arg1_type, arg2_type, mt_policy>* conn = new _sig_connection2<arg1_type, arg2_type, mt_policy>(chainsig); 1045 this->m_connected_slots.push_back(conn); 1046 chainsig.signal_connect(this); 1047 } 1048 emit(arg1_type a1,arg2_type a2)1049 void emit(arg1_type a1, arg2_type a2) 1050 { 1051 lock_block<mt_policy> lock(this); 1052 typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin(); 1053 typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end(); 1054 1055 while(it != itEnd) 1056 { 1057 itNext = it; 1058 ++itNext; 1059 1060 (*it)->emit(a1, a2); 1061 1062 it = itNext; 1063 } 1064 } 1065 operator()1066 void operator()(arg1_type a1, arg2_type a2) 1067 { 1068 lock_block<mt_policy> lock(this); 1069 typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin(); 1070 typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end(); 1071 1072 while(it != itEnd) 1073 { 1074 itNext = it; 1075 ++itNext; 1076 1077 (*it)->emit(a1, a2); 1078 1079 it = itNext; 1080 } 1081 } 1082 }; 1083 1084 // signal chaining connection types added by Barnaby Gray 24/11/2002 1085 1086 template<class mt_policy> 1087 class _sig_connection0 : public _connection_base0<mt_policy> 1088 { 1089 public: _sig_connection0(signal0<mt_policy> & sig)1090 _sig_connection0(signal0<mt_policy>& sig) 1091 : m_signal(sig) 1092 { 1093 } 1094 _sig_connection0(const _sig_connection0<mt_policy> & conn)1095 _sig_connection0(const _sig_connection0<mt_policy>& conn) 1096 : m_signal( conn.m_signal ) 1097 { 1098 } 1099 clone()1100 virtual _connection_base0<mt_policy>* clone() 1101 { 1102 return new _sig_connection0<mt_policy>(*this); 1103 } 1104 duplicate(has_slots<mt_policy> * pnewdest)1105 virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) 1106 { 1107 return new _sig_connection0<mt_policy>(m_signal); 1108 } 1109 emit()1110 virtual void emit() 1111 { 1112 m_signal.emit(); 1113 } 1114 getdest()1115 virtual has_slots<mt_policy>* getdest() const 1116 { 1117 return &m_signal; 1118 } 1119 1120 private: 1121 signal0<mt_policy>& m_signal; 1122 }; 1123 1124 template<class arg1_type, class mt_policy> 1125 class _sig_connection1 : public _connection_base1<arg1_type, mt_policy> 1126 { 1127 public: _sig_connection1(signal1<arg1_type,mt_policy> & sig)1128 _sig_connection1(signal1<arg1_type, mt_policy>& sig) 1129 : m_signal(sig) 1130 { 1131 } 1132 _sig_connection1(const _sig_connection1<arg1_type,mt_policy> & conn)1133 _sig_connection1(const _sig_connection1<arg1_type, mt_policy>& conn) 1134 : m_signal( conn.m_signal ) 1135 { 1136 } 1137 clone()1138 virtual _connection_base1<arg1_type, mt_policy>* clone() 1139 { 1140 return new _sig_connection1<arg1_type, mt_policy>(*this); 1141 } 1142 duplicate(has_slots<mt_policy> * pnewdest)1143 virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) 1144 { 1145 return new _sig_connection1<arg1_type, mt_policy>(m_signal); 1146 } 1147 emit(arg1_type a1)1148 virtual void emit(arg1_type a1) 1149 { 1150 m_signal.emit(a1); 1151 } 1152 getdest()1153 virtual has_slots<mt_policy>* getdest() const 1154 { 1155 return &m_signal; 1156 } 1157 1158 private: 1159 signal1<arg1_type, mt_policy>& m_signal; 1160 }; 1161 1162 template<class arg1_type, class arg2_type, class mt_policy> 1163 class _sig_connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy> 1164 { 1165 public: _sig_connection2(signal2<arg1_type,arg2_type,mt_policy> & sig)1166 _sig_connection2(signal2<arg1_type, arg2_type, mt_policy>& sig) 1167 : m_signal(sig) 1168 { 1169 } 1170 _sig_connection2(const _sig_connection2<arg1_type,arg2_type,mt_policy> & conn)1171 _sig_connection2(const _sig_connection2<arg1_type, arg2_type, mt_policy>& conn) 1172 : m_signal( conn.m_signal ) 1173 { 1174 } 1175 clone()1176 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() 1177 { 1178 return new _sig_connection2<arg1_type, arg2_type, mt_policy>(*this); 1179 } 1180 duplicate(has_slots<mt_policy> * pnewdest)1181 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) 1182 { 1183 return new _sig_connection2<arg1_type, arg2_type, mt_policy>(m_signal); 1184 } 1185 emit(arg1_type a1,arg2_type a2)1186 virtual void emit(arg1_type a1, arg2_type a2) 1187 { 1188 m_signal.emit(a1, a2); 1189 } 1190 getdest()1191 virtual has_slots<mt_policy>* getdest() const 1192 { 1193 return &m_signal; 1194 } 1195 1196 private: 1197 signal2<arg1_type, arg2_type, mt_policy>& m_signal; 1198 }; 1199 1200 } // namespace sigslot 1201 1202 #endif // SIGSLOT_H__ 1203 1204