Updated Changelog
[centerim/davrieb.git] / libicq2000 / libicq2000 / sigslot.h
blobb7509c0823c6d03c8be46969c091558fcf1a328a
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.
12 // QUICK DOCUMENTATION
13 //
14 // (see also the full documentation at http://sigslot.sourceforge.net/)
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.
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)
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.
31 // PLATFORM NOTES
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.
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.
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.
52 //
53 // THREADING MODES
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).
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.
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.
76 // USING THE LIBRARY
78 // See the full documentation at http://sigslot.sourceforge.net/
82 #ifndef SIGSLOT_H__
83 #define SIGSLOT_H__
85 #include <set>
86 #include <list>
88 #if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(SIGSLOT_USE_POSIX_THREADS))
89 # define _SIGSLOT_SINGLE_THREADED
90 #elif defined(WIN32)
91 # define _SIGSLOT_HAS_WIN32_THREADS
92 # include <windows.h>
93 #elif defined(SIGSLOT_USE_POSIX_THREADS)
94 # define _SIGSLOT_HAS_POSIX_THREADS
95 # include <pthread.h>
96 #else
97 # define _SIGSLOT_SINGLE_THREADED
98 #endif
100 #ifndef SIGSLOT_DEFAULT_MT_POLICY
101 # ifdef _SIGSLOT_SINGLE_THREADED
102 # define SIGSLOT_DEFAULT_MT_POLICY single_threaded
103 # else
104 # define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local
105 # endif
106 #endif
109 namespace sigslot {
111 class single_threaded
113 public:
114 single_threaded()
119 virtual ~single_threaded()
124 virtual void lock()
129 virtual void unlock()
135 #ifdef _SIGSLOT_HAS_WIN32_THREADS
136 // The multi threading policies only get compiled in if they are enabled.
137 class multi_threaded_global
139 public:
140 multi_threaded_global()
142 static bool isinitialised = false;
144 if(!isinitialised)
146 InitializeCriticalSection(get_critsec());
147 isinitialised = true;
151 multi_threaded_global(const multi_threaded_global&)
156 virtual ~multi_threaded_global()
161 virtual void lock()
163 EnterCriticalSection(get_critsec());
166 virtual void unlock()
168 LeaveCriticalSection(get_critsec());
171 private:
172 CRITICAL_SECTION* get_critsec()
174 static CRITICAL_SECTION g_critsec;
175 return &g_critsec;
179 class multi_threaded_local
181 public:
182 multi_threaded_local()
184 InitializeCriticalSection(&m_critsec);
187 multi_threaded_local(const multi_threaded_local&)
189 InitializeCriticalSection(&m_critsec);
192 virtual ~multi_threaded_local()
194 DeleteCriticalSection(&m_critsec);
197 virtual void lock()
199 EnterCriticalSection(&m_critsec);
202 virtual void unlock()
204 LeaveCriticalSection(&m_critsec);
207 private:
208 CRITICAL_SECTION m_critsec;
210 #endif // _SIGSLOT_HAS_WIN32_THREADS
212 #ifdef _SIGSLOT_HAS_POSIX_THREADS
213 // The multi threading policies only get compiled in if they are enabled.
214 class multi_threaded_global
216 public:
217 multi_threaded_global()
219 pthread_mutex_init(get_mutex(), NULL);
222 multi_threaded_global(const multi_threaded_global&)
227 virtual ~multi_threaded_global()
232 virtual void lock()
234 pthread_mutex_lock(get_mutex());
237 virtual void unlock()
239 pthread_mutex_unlock(get_mutex());
242 private:
243 pthread_mutex_t* get_mutex()
245 static pthread_mutex_t g_mutex;
246 return &g_mutex;
250 class multi_threaded_local
252 public:
253 multi_threaded_local()
255 pthread_mutex_init(&m_mutex, NULL);
258 multi_threaded_local(const multi_threaded_local&)
260 pthread_mutex_init(&m_mutex, NULL);
263 virtual ~multi_threaded_local()
265 pthread_mutex_destroy(&m_mutex);
268 virtual void lock()
270 pthread_mutex_lock(&m_mutex);
273 virtual void unlock()
275 pthread_mutex_unlock(&m_mutex);
278 private:
279 pthread_mutex_t m_mutex;
281 #endif // _SIGSLOT_HAS_POSIX_THREADS
283 template<class mt_policy>
284 class lock_block
286 public:
287 mt_policy *m_mutex;
289 lock_block(mt_policy *mtx)
290 : m_mutex(mtx)
292 m_mutex->lock();
295 ~lock_block()
297 m_mutex->unlock();
301 template<class mt_policy>
302 class has_slots;
304 template<class mt_policy>
305 class _connection_base0
307 public:
308 virtual has_slots<mt_policy>* getdest() const = 0;
309 virtual void emit() = 0;
310 virtual _connection_base0<mt_policy>* clone() = 0;
311 virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
314 template<class arg1_type, class mt_policy>
315 class _connection_base1
317 public:
318 virtual has_slots<mt_policy>* getdest() const = 0;
319 virtual void emit(arg1_type) = 0;
320 virtual _connection_base1<arg1_type, mt_policy>* clone() = 0;
321 virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
324 template<class arg1_type, class arg2_type, class mt_policy>
325 class _connection_base2
327 public:
328 virtual has_slots<mt_policy>* getdest() const = 0;
329 virtual void emit(arg1_type, arg2_type) = 0;
330 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() = 0;
331 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
334 template<class mt_policy>
335 class _signal_base : public has_slots<mt_policy>
337 public:
338 virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;
339 virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0;
342 template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
343 class has_slots : public mt_policy
345 private:
346 typedef std::set<_signal_base<mt_policy> *> sender_set;
347 typedef typename sender_set::const_iterator const_iterator;
349 public:
350 has_slots()
355 has_slots(const has_slots& hs)
356 : mt_policy(hs)
358 lock_block<mt_policy> lock(this);
359 const_iterator it = hs.m_senders.begin();
360 const_iterator itEnd = hs.m_senders.end();
362 while(it != itEnd)
364 (*it)->slot_duplicate(&hs, this);
365 m_senders.insert(*it);
366 ++it;
370 void signal_connect(_signal_base<mt_policy>* sender)
372 lock_block<mt_policy> lock(this);
373 m_senders.insert(sender);
376 void signal_disconnect(_signal_base<mt_policy>* sender)
378 lock_block<mt_policy> lock(this);
379 m_senders.erase(sender);
382 virtual ~has_slots()
384 disconnect_all();
387 void disconnect_all()
389 lock_block<mt_policy> lock(this);
390 const_iterator it = m_senders.begin();
391 const_iterator itEnd = m_senders.end();
393 while(it != itEnd)
395 (*it)->slot_disconnect(this);
396 ++it;
399 m_senders.erase(m_senders.begin(), m_senders.end());
402 private:
403 sender_set m_senders;
406 template<class mt_policy>
407 class _signal_base0 : public _signal_base<mt_policy>
409 public:
410 typedef typename std::list<_connection_base0<mt_policy> *>
411 connections_list;
413 _signal_base0()
418 _signal_base0(const _signal_base0<mt_policy>& s)
419 : _signal_base<mt_policy>(s)
421 lock_block<mt_policy> lock(this);
422 typename connections_list::const_iterator it = s.m_connected_slots.begin();
423 typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
425 while(it != itEnd)
427 (*it)->getdest()->signal_connect(this);
428 m_connected_slots.push_back((*it)->clone());
430 ++it;
434 void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
436 lock_block<mt_policy> lock(this);
437 typename connections_list::iterator it = m_connected_slots.begin();
438 typename connections_list::iterator itEnd = m_connected_slots.end();
440 while(it != itEnd)
442 if((*it)->getdest() == oldtarget)
444 m_connected_slots.push_back((*it)->duplicate(newtarget));
447 ++it;
451 ~_signal_base0()
453 disconnect_all();
456 void disconnect_all()
458 lock_block<mt_policy> lock(this);
459 typename connections_list::const_iterator it = m_connected_slots.begin();
460 typename connections_list::const_iterator itEnd = m_connected_slots.end();
462 while(it != itEnd)
464 (*it)->getdest()->signal_disconnect(this);
465 delete *it;
467 ++it;
470 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
473 void disconnect(has_slots<mt_policy>* pclass)
475 lock_block<mt_policy> lock(this);
476 typename connections_list::iterator it = m_connected_slots.begin();
477 typename connections_list::iterator itEnd = m_connected_slots.end();
479 while(it != itEnd)
481 typename connections_list::iterator itNext = it;
482 ++itNext;
484 if((*it)->getdest() == pclass)
486 delete *it;
487 m_connected_slots.erase(it);
488 pclass->signal_disconnect(this);
489 return;
492 it = itNext;
496 void slot_disconnect(has_slots<mt_policy>* pslot)
498 lock_block<mt_policy> lock(this);
499 typename connections_list::iterator it = m_connected_slots.begin();
500 typename connections_list::iterator itEnd = m_connected_slots.end();
502 while(it != itEnd)
504 typename connections_list::iterator itNext = it;
505 ++itNext;
507 if((*it)->getdest() == pslot)
509 delete *it;
510 m_connected_slots.erase(it);
513 it = itNext;
517 protected:
518 connections_list m_connected_slots;
521 template<class arg1_type, class mt_policy>
522 class _signal_base1 : public _signal_base<mt_policy>
524 public:
525 typedef typename std::list<_connection_base1<arg1_type, mt_policy> *>
526 connections_list;
528 _signal_base1()
533 _signal_base1(const _signal_base1<arg1_type, mt_policy>& s)
534 : _signal_base<mt_policy>(s)
536 lock_block<mt_policy> lock(this);
537 typename connections_list::const_iterator it = s.m_connected_slots.begin();
538 typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
540 while(it != itEnd)
542 (*it)->getdest()->signal_connect(this);
543 m_connected_slots.push_back((*it)->clone());
545 ++it;
549 void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
551 lock_block<mt_policy> lock(this);
552 typename connections_list::iterator it = m_connected_slots.begin();
553 typename connections_list::iterator itEnd = m_connected_slots.end();
555 while(it != itEnd)
557 if((*it)->getdest() == oldtarget)
559 m_connected_slots.push_back((*it)->duplicate(newtarget));
562 ++it;
566 ~_signal_base1()
568 disconnect_all();
571 void disconnect_all()
573 lock_block<mt_policy> lock(this);
574 typename connections_list::const_iterator it = m_connected_slots.begin();
575 typename connections_list::const_iterator itEnd = m_connected_slots.end();
577 while(it != itEnd)
579 (*it)->getdest()->signal_disconnect(this);
580 delete *it;
582 ++it;
585 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
588 void disconnect(has_slots<mt_policy>* pclass)
590 lock_block<mt_policy> lock(this);
591 typename connections_list::iterator it = m_connected_slots.begin();
592 typename connections_list::iterator itEnd = m_connected_slots.end();
594 while(it != itEnd)
596 typename connections_list::iterator itNext = it;
597 ++itNext;
599 if((*it)->getdest() == pclass)
601 delete *it;
602 m_connected_slots.erase(it);
603 pclass->signal_disconnect(this);
604 return;
607 it = itNext;
611 void slot_disconnect(has_slots<mt_policy>* pslot)
613 lock_block<mt_policy> lock(this);
614 typename connections_list::iterator it = m_connected_slots.begin();
615 typename connections_list::iterator itEnd = m_connected_slots.end();
617 while(it != itEnd)
619 typename connections_list::iterator itNext = it;
620 ++itNext;
622 if((*it)->getdest() == pslot)
624 delete *it;
625 m_connected_slots.erase(it);
628 it = itNext;
632 protected:
633 connections_list m_connected_slots;
636 template<class arg1_type, class arg2_type, class mt_policy>
637 class _signal_base2 : public _signal_base<mt_policy>
639 public:
640 typedef typename std::list<_connection_base2<arg1_type, arg2_type, mt_policy> *>
641 connections_list;
643 _signal_base2()
648 _signal_base2(const _signal_base2<arg1_type, arg2_type, mt_policy>& s)
649 : _signal_base<mt_policy>(s)
651 lock_block<mt_policy> lock(this);
652 typename connections_list::const_iterator it = s.m_connected_slots.begin();
653 typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
655 while(it != itEnd)
657 (*it)->getdest()->signal_connect(this);
658 m_connected_slots.push_back((*it)->clone());
660 ++it;
664 void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
666 lock_block<mt_policy> lock(this);
667 typename connections_list::iterator it = m_connected_slots.begin();
668 typename connections_list::iterator itEnd = m_connected_slots.end();
670 while(it != itEnd)
672 if((*it)->getdest() == oldtarget)
674 m_connected_slots.push_back((*it)->duplicate(newtarget));
677 ++it;
681 ~_signal_base2()
683 disconnect_all();
686 void disconnect_all()
688 lock_block<mt_policy> lock(this);
689 typename connections_list::const_iterator it = m_connected_slots.begin();
690 typename connections_list::const_iterator itEnd = m_connected_slots.end();
692 while(it != itEnd)
694 (*it)->getdest()->signal_disconnect(this);
695 delete *it;
697 ++it;
700 m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
703 void disconnect(has_slots<mt_policy>* pclass)
705 lock_block<mt_policy> lock(this);
706 typename connections_list::iterator it = m_connected_slots.begin();
707 typename connections_list::iterator itEnd = m_connected_slots.end();
709 while(it != itEnd)
711 typename connections_list::iterator itNext = it;
712 ++itNext;
713 if((*it)->getdest() == pclass)
715 delete *it;
716 m_connected_slots.erase(it);
717 pclass->signal_disconnect(this);
718 return;
721 it = itNext;
725 void slot_disconnect(has_slots<mt_policy>* pslot)
727 lock_block<mt_policy> lock(this);
728 typename connections_list::iterator it = m_connected_slots.begin();
729 typename connections_list::iterator itEnd = m_connected_slots.end();
731 while(it != itEnd)
733 typename connections_list::iterator itNext = it;
734 ++itNext;
736 if((*it)->getdest() == pslot)
738 delete *it;
739 m_connected_slots.erase(it);
742 it = itNext;
746 protected:
747 connections_list m_connected_slots;
750 template<class dest_type, class mt_policy>
751 class _connection0 : public _connection_base0<mt_policy>
753 public:
754 _connection0()
756 this->pobject = NULL;
757 this->pmemfun = NULL;
760 _connection0(dest_type* pobject, void (dest_type::*pmemfun)())
762 m_pobject = pobject;
763 m_pmemfun = pmemfun;
766 virtual _connection_base0<mt_policy>* clone()
768 return new _connection0<dest_type, mt_policy>(*this);
771 virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
773 return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
776 virtual void emit()
778 (m_pobject->*m_pmemfun)();
781 virtual has_slots<mt_policy>* getdest() const
783 return m_pobject;
786 private:
787 dest_type* m_pobject;
788 void (dest_type::* m_pmemfun)();
791 template<class dest_type, class arg1_type, class mt_policy>
792 class _connection1 : public _connection_base1<arg1_type, mt_policy>
794 public:
795 _connection1()
797 this->pobject = NULL;
798 this->pmemfun = NULL;
801 _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type))
803 m_pobject = pobject;
804 m_pmemfun = pmemfun;
807 virtual _connection_base1<arg1_type, mt_policy>* clone()
809 return new _connection1<dest_type, arg1_type, mt_policy>(*this);
812 virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
814 return new _connection1<dest_type, arg1_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
817 virtual void emit(arg1_type a1)
819 (m_pobject->*m_pmemfun)(a1);
822 virtual has_slots<mt_policy>* getdest() const
824 return m_pobject;
827 private:
828 dest_type* m_pobject;
829 void (dest_type::* m_pmemfun)(arg1_type);
832 template<class dest_type, class arg1_type, class arg2_type, class mt_policy>
833 class _connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy>
835 public:
836 _connection2()
838 this->pobject = NULL;
839 this->pmemfun = NULL;
842 _connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, arg2_type))
844 m_pobject = pobject;
845 m_pmemfun = pmemfun;
848 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone()
850 return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(*this);
853 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
855 return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
858 virtual void emit(arg1_type a1, arg2_type a2)
860 (m_pobject->*m_pmemfun)(a1, a2);
863 virtual has_slots<mt_policy>* getdest() const
865 return m_pobject;
868 private:
869 dest_type* m_pobject;
870 void (dest_type::* m_pmemfun)(arg1_type, arg2_type);
873 template<class mt_policy>
874 class _sig_connection0;
875 template<class arg1_type, class mt_policy>
876 class _sig_connection1;
877 template<class arg1_type, class arg2_type, class mt_policy>
878 class _sig_connection2;
879 template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
880 class signal0 : public _signal_base0<mt_policy>
882 public:
883 signal0()
888 signal0(const signal0<mt_policy>& s)
889 : _signal_base0<mt_policy>(s)
894 template<class dest_type>
895 void connect(dest_type* pclass, void (dest_type::*pmemfun)())
897 lock_block<mt_policy> lock(this);
898 _connection0<dest_type, mt_policy>* conn
899 = new _connection0<dest_type, mt_policy>(pclass, pmemfun);
900 this->m_connected_slots.push_back(conn);
901 pclass->signal_connect(this);
904 void connect(signal0<mt_policy>& chainsig)
906 lock_block<mt_policy> lock(this);
907 _sig_connection0<mt_policy>* conn = new _sig_connection0<mt_policy>(chainsig);
908 this->m_connected_slots.push_back(conn);
909 chainsig.signal_connect(this);
912 void emit()
914 lock_block<mt_policy> lock(this);
915 typename _signal_base0< mt_policy >::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
916 typename _signal_base0< mt_policy >::connections_list::const_iterator itEnd = this->m_connected_slots.end();
918 while(it != itEnd)
920 itNext = it;
921 ++itNext;
923 (*it)->emit();
925 it = itNext;
929 void operator()()
931 lock_block<mt_policy> lock(this);
932 typename _signal_base0< mt_policy >::connections_list::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
933 typename _signal_base0< mt_policy >::connections_list::connections_list::const_iterator itEnd = this->m_connected_slots.end();
935 while(it != itEnd)
937 itNext = it;
938 ++itNext;
940 (*it)->emit();
942 it = itNext;
947 template<class arg1_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
948 class signal1 : public _signal_base1<arg1_type, mt_policy>
950 public:
951 signal1()
956 signal1(const signal1<arg1_type, mt_policy>& s)
957 : _signal_base1<arg1_type, mt_policy>(s)
962 template<class dest_type>
963 void connect(dest_type* pclass, void (dest_type::*pmemfun)(arg1_type))
965 lock_block<mt_policy> lock(this);
966 _connection1<dest_type, arg1_type, mt_policy>* conn
967 = new _connection1<dest_type, arg1_type, mt_policy>(pclass, pmemfun);
968 this->m_connected_slots.push_back(conn);
969 pclass->signal_connect(this);
972 void connect(signal1<arg1_type, mt_policy>& chainsig)
974 lock_block<mt_policy> lock(this);
975 _sig_connection1<arg1_type, mt_policy>* conn = new _sig_connection1<arg1_type, mt_policy>(chainsig);
976 this->m_connected_slots.push_back(conn);
977 chainsig.signal_connect(this);
980 void emit(arg1_type a1)
982 lock_block<mt_policy> lock(this);
983 typename _signal_base1<arg1_type, mt_policy >::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
984 typename _signal_base1<arg1_type, mt_policy >::connections_list::const_iterator itEnd = this->m_connected_slots.end();
986 while(it != itEnd)
988 itNext = it;
989 ++itNext;
991 (*it)->emit(a1);
993 it = itNext;
997 void operator()(arg1_type a1)
999 lock_block<mt_policy> lock(this);
1000 typename _signal_base1<arg1_type, mt_policy >::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
1001 typename _signal_base1<arg1_type, mt_policy >::connections_list::const_iterator itEnd = this->m_connected_slots.end();
1003 while(it != itEnd)
1005 itNext = it;
1006 ++itNext;
1008 (*it)->emit(a1);
1010 it = itNext;
1015 template<class arg1_type, class arg2_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
1016 class signal2 : public _signal_base2<arg1_type, arg2_type, mt_policy>
1018 public:
1019 signal2()
1024 signal2(const signal2<arg1_type, arg2_type, mt_policy>& s)
1025 : _signal_base2<arg1_type, arg2_type, mt_policy>(s)
1030 template<class dest_type>
1031 void connect(dest_type* pclass, void (dest_type::*pmemfun)(arg1_type, arg2_type))
1033 lock_block<mt_policy> lock(this);
1034 _connection2<dest_type, arg1_type, arg2_type, mt_policy>* conn
1035 = new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(pclass, pmemfun);
1036 this->m_connected_slots.push_back(conn);
1037 pclass->signal_connect(this);
1040 void connect(signal2<arg1_type, arg2_type, mt_policy>& chainsig)
1042 lock_block<mt_policy> lock(this);
1043 _sig_connection2<arg1_type, arg2_type, mt_policy>* conn = new _sig_connection2<arg1_type, arg2_type, mt_policy>(chainsig);
1044 this->m_connected_slots.push_back(conn);
1045 chainsig.signal_connect(this);
1048 void emit(arg1_type a1, arg2_type a2)
1050 lock_block<mt_policy> lock(this);
1051 typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
1052 typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
1054 while(it != itEnd)
1056 itNext = it;
1057 ++itNext;
1059 (*it)->emit(a1, a2);
1061 it = itNext;
1065 void operator()(arg1_type a1, arg2_type a2)
1067 lock_block<mt_policy> lock(this);
1068 typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
1069 typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
1071 while(it != itEnd)
1073 itNext = it;
1074 ++itNext;
1076 (*it)->emit(a1, a2);
1078 it = itNext;
1083 // signal chaining connection types added by Barnaby Gray 24/11/2002
1085 template<class mt_policy>
1086 class _sig_connection0 : public _connection_base0<mt_policy>
1088 public:
1089 _sig_connection0(signal0<mt_policy>& sig)
1090 : m_signal(sig)
1094 _sig_connection0(const _sig_connection0<mt_policy>& conn)
1095 : m_signal( conn.m_signal )
1099 virtual _connection_base0<mt_policy>* clone()
1101 return new _sig_connection0<mt_policy>(*this);
1104 virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
1106 return new _sig_connection0<mt_policy>(m_signal);
1109 virtual void emit()
1111 m_signal.emit();
1114 virtual has_slots<mt_policy>* getdest() const
1116 return &m_signal;
1119 private:
1120 signal0<mt_policy>& m_signal;
1123 template<class arg1_type, class mt_policy>
1124 class _sig_connection1 : public _connection_base1<arg1_type, mt_policy>
1126 public:
1127 _sig_connection1(signal1<arg1_type, mt_policy>& sig)
1128 : m_signal(sig)
1132 _sig_connection1(const _sig_connection1<arg1_type, mt_policy>& conn)
1133 : m_signal( conn.m_signal )
1137 virtual _connection_base1<arg1_type, mt_policy>* clone()
1139 return new _sig_connection1<arg1_type, mt_policy>(*this);
1142 virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
1144 return new _sig_connection1<arg1_type, mt_policy>(m_signal);
1147 virtual void emit(arg1_type a1)
1149 m_signal.emit(a1);
1152 virtual has_slots<mt_policy>* getdest() const
1154 return &m_signal;
1157 private:
1158 signal1<arg1_type, mt_policy>& m_signal;
1161 template<class arg1_type, class arg2_type, class mt_policy>
1162 class _sig_connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy>
1164 public:
1165 _sig_connection2(signal2<arg1_type, arg2_type, mt_policy>& sig)
1166 : m_signal(sig)
1170 _sig_connection2(const _sig_connection2<arg1_type, arg2_type, mt_policy>& conn)
1171 : m_signal( conn.m_signal )
1175 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone()
1177 return new _sig_connection2<arg1_type, arg2_type, mt_policy>(*this);
1180 virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
1182 return new _sig_connection2<arg1_type, arg2_type, mt_policy>(m_signal);
1185 virtual void emit(arg1_type a1, arg2_type a2)
1187 m_signal.emit(a1, a2);
1190 virtual has_slots<mt_policy>* getdest() const
1192 return &m_signal;
1195 private:
1196 signal2<arg1_type, arg2_type, mt_policy>& m_signal;
1199 } // namespace sigslot
1201 #endif // SIGSLOT_H__