tSignal.h

Engine/source/core/util/tSignal.h

More...

Classes:

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _TSIGNAL_H_
 25#define _TSIGNAL_H_
 26
 27#ifndef _UTIL_DELEGATE_H_
 28#include "core/util/delegate.h"
 29#endif
 30
 31#ifndef _TVECTOR_H_
 32#include "core/util/tVector.h"
 33#endif
 34
 35/// Signals (Multi-cast Delegates)
 36/// 
 37/// Signals are used throughout this engine to allow subscribers to listen
 38/// for generated events for various things.  
 39/// 
 40/// Signals are called according to their order parameter (lower
 41/// numbers first).
 42///
 43/// Signal functions can return bool or void.  If bool then returning false
 44/// from a signal function will cause entries in the ordered signal list after 
 45/// that one to not be called.
 46///
 47/// This allows handlers of a given event to say to the signal generator, "I handled this message, and 
 48/// it is no longer appropriate for other listeners to handle it"
 49
 50class SignalBase
 51{
 52public:
 53
 54   SignalBase()
 55   {
 56      mList.next = mList.prev = &mList;
 57      mList.mOrder = 0.5f;
 58   }
 59
 60   ~SignalBase();
 61
 62   /// Removes all the delegates from the signal.
 63   void removeAll();
 64
 65   /// Returns true if the delegate list is empty.
 66   bool isEmpty() const
 67   {
 68      return mList.next == &mList;
 69   }
 70
 71protected:
 72
 73   struct DelegateLink
 74   {
 75      DelegateLink *next,*prev;
 76      F32 mOrder;
 77
 78      void insert(DelegateLink* node, F32 order);
 79      void unlink();
 80      DelegateLink() :next(NULL), prev(NULL), mOrder(0) {}
 81      virtual ~DelegateLink() {}
 82   };
 83
 84   DelegateLink mList;
 85
 86   /// We need to protect the delegate list against removal of the currently
 87   /// triggering node as well removal of the next node in the list.  When not
 88   /// handling these two cases correctly, removing delegates from a signal
 89   /// while it is triggering will lead to crashes.
 90   ///
 91   /// So this field stores the next node of each active traversal so that when
 92   /// we unlink a node, we can check it against this field and move the traversal
 93   /// along if needed.
 94   Vector<DelegateLink*> mTriggerNext;
 95};
 96
 97template<typename Signature> class SignalBaseT;
 98
 99/// Class for handle automatic diconnect form Signal when destroyed
100template< typename Signature >
101class SignalSlot
102{
103public:
104   typedef Delegate< Signature > DelegateSig;
105   typedef SignalBaseT< Signature> SignalSig;
106
107   SignalSlot() : mSignal(NULL)
108   {
109
110   }
111
112   ~SignalSlot()
113   {
114      disconnect();
115   }
116
117   const DelegateSig& getDelegate() { return mDlg; }
118
119   /// setDelegate disconect form Signal old delegate and connect new delegate
120   template<typename X>
121   void setDelegate( const X &fn ) { setDelegate( DelegateSig( fn ) ); }
122
123   template<typename X, typename Y>
124   void setDelegate( const X &ptr, const Y &fn ) { setDelegate( DelegateSig( ptr, fn ) ); }
125
126   void setDelegate( const DelegateSig &dlg) 
127   {
128      SignalSig* signal = mSignal;
129      if( isConnected() )
130         disconnect();      
131
132      mDlg = dlg;
133      if( signal && mDlg )
134         signal->notify( mDlg );
135   }
136
137   /// is connected to Signal
138   bool isConnected() const { return mSignal; }
139
140   /// disconnect from Signal
141   void disconnect()
142   {
143      if( mSignal )
144      {
145         SignalSig *oldSignal = mSignal;
146         mSignal = NULL;
147         oldSignal->remove( mDlg );
148      }
149   }
150
151protected:
152   friend class SignalBaseT< Signature >;
153
154   void _setSignal(SignalSig *sig)
155   {      
156      mSignal = sig;
157   }
158
159   SignalSig* _getSignal() const { return mSignal; }   
160
161   DelegateSig mDlg;
162   SignalSig *mSignal;
163
164private:
165   SignalSlot( const SignalSlot&);
166   SignalSlot& operator=( const SignalSlot&);
167};
168
169template<typename Signature> class SignalBaseT : public SignalBase
170{
171public:
172
173   /// The delegate signature for this signal.
174   typedef Delegate<Signature> DelegateSig;
175
176   SignalBaseT() {}
177
178   SignalBaseT( const SignalBaseT &base )
179   {
180      mList.next = mList.prev = &mList;
181      merge( base );
182   }
183
184   void operator=( const SignalBaseT &base )
185   {
186      removeAll();
187      merge( base );
188   }
189
190   void merge( const SignalBaseT &base )
191   {
192      for ( DelegateLink *ptr = base.mList.next; ptr != &base.mList; ptr = ptr->next )
193      {
194         DelegateLinkImpl *del = static_cast<DelegateLinkImpl*>( ptr );
195         notify( del->mDelegate, del->mOrder );
196      }
197   }
198
199   void notify( const DelegateSig &dlg, F32 order = 0.5f)
200   {
201      mList.insert(new DelegateLinkImpl(dlg), order);
202   }
203
204   void remove( DelegateSig dlg )
205   {
206      for( DelegateLink* ptr = mList.next;ptr != &mList; ptr = ptr->next )
207      {
208         if( DelegateLinkImpl* del = static_cast< DelegateLinkImpl* >( ptr ) )
209         {
210            if( del->mDelegate == dlg )
211            {
212               for ( S32 i = 0; i < mTriggerNext.size(); i++ )
213               {
214                  if( mTriggerNext[i] == ptr )
215                     mTriggerNext[i] = ptr->next;
216               }
217
218               del->unlink();
219               delete del;
220               return;
221            }
222         }
223      }
224   } 
225
226   template <class T,class U>
227   void notify(T obj,U func, F32 order = 0.5f)
228   {
229      DelegateSig dlg(obj, func);
230      notify(dlg, order);
231   }
232
233   template <class T>
234   void notify(T func, F32 order = 0.5f)
235   {
236      DelegateSig dlg(func);
237      notify(dlg, order);
238   }
239
240   void notify( SignalSlot<Signature> &slot, F32 order = 0.5f)
241   {
242      if( !slot.getDelegate() )
243         return;
244
245      if( slot.isConnected() )
246         slot.disconnect();
247
248      slot._setSignal( this );
249      mList.insert( new SlotLinkImpl(slot), order );
250   }
251
252   template <class T,class U>
253   void remove(T obj,U func)
254   {
255      DelegateSig compDelegate(obj, func);
256      remove(compDelegate);
257   }
258
259   template <class T>
260   void remove(T func)
261   {
262      DelegateSig compDelegate(func);
263      remove(compDelegate);
264   } 
265
266   /// Returns true if the signal already contains this delegate.
267   bool contains( const DelegateSig &dlg ) const
268   {
269      for ( DelegateLink *ptr = mList.next; ptr != &mList; ptr = ptr->next )
270      {
271         DelegateLinkImpl *del = static_cast<DelegateLinkImpl*>( ptr );
272         if ( del->mDelegate == dlg )
273            return true;
274      }
275
276      return false;
277   } 
278
279protected:
280
281   struct DelegateLinkImpl : public SignalBase::DelegateLink
282   {
283      DelegateSig mDelegate;
284      DelegateLinkImpl(DelegateSig dlg) : mDelegate(dlg) {}
285   };
286
287   struct SlotLinkImpl : public DelegateLinkImpl
288   {      
289      SlotLinkImpl(SignalSlot<Signature>& slot) : mSlot( &slot ), DelegateLinkImpl( slot.getDelegate() )
290      {
291
292      }
293
294      ~SlotLinkImpl()
295      {
296         if( mSlot )
297            mSlot->_setSignal( NULL ); 
298      }
299
300   protected:
301      SignalSlot<Signature> *mSlot;
302   };
303
304   DelegateSig & getDelegate(SignalBase::DelegateLink * link)
305   {
306      return ((DelegateLinkImpl*)link)->mDelegate;
307   }
308};
309
310//-----------------------------------------------------------------------------
311
312template<typename Signature> class Signal;
313
314// Short-circuit signal implementations
315
316template<> 
317class Signal<bool()> : public SignalBaseT<bool()>
318{
319   public:
320
321      bool trigger()
322      {
323         this->mTriggerNext.push_back(NULL);
324         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
325         {
326            this->mTriggerNext.last() = ptr->next;
327            if( !this->getDelegate( ptr )() )
328            {
329               this->mTriggerNext.pop_back();
330               return false;
331            }
332            ptr = this->mTriggerNext.last();
333         }
334         this->mTriggerNext.pop_back();
335         return true;
336      }
337};
338
339template<class A> 
340class Signal<bool(A)> : public SignalBaseT<bool(A)>
341{   
342   public:
343
344      bool trigger( A a )
345      {
346         this->mTriggerNext.push_back(NULL);
347         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
348         {
349            this->mTriggerNext.last() = ptr->next;
350            if( !this->getDelegate( ptr )( a ) )
351            {
352               this->mTriggerNext.pop_back();
353               return false;
354            }
355            ptr = this->mTriggerNext.last();
356         }
357         this->mTriggerNext.pop_back();
358         return true;
359      }
360};
361
362template<class A, class B>
363class Signal<bool(A,B)> : public SignalBaseT<bool(A,B)>
364{
365   public:
366
367      bool trigger( A a, B b )
368      {
369         this->mTriggerNext.push_back(NULL);
370         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
371         {
372            this->mTriggerNext.last() = ptr->next;
373            if( !this->getDelegate( ptr )( a, b ) )
374            {
375               this->mTriggerNext.pop_back();
376               return false;
377            }
378            ptr = this->mTriggerNext.last();
379         }
380         this->mTriggerNext.pop_back();
381         return true;
382      }
383};
384
385template<class A, class B, class C> 
386class Signal<bool(A,B,C)> : public SignalBaseT<bool(A,B,C)>
387{
388   public:
389
390      bool trigger( A a, B b, C c )
391      {
392         this->mTriggerNext.push_back(NULL);
393         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
394         {
395            this->mTriggerNext.last() = ptr->next;
396            if( !this->getDelegate( ptr )( a, b, c ) )
397            {
398               this->mTriggerNext.pop_back();
399               return false;
400            }
401            ptr = this->mTriggerNext.last();
402         }
403         this->mTriggerNext.pop_back();
404         return true;
405      }
406};
407
408template<class A, class B, class C, class D> 
409class Signal<bool(A,B,C,D)> : public SignalBaseT<bool(A,B,C,D)>
410{
411   public:
412
413      bool trigger( A a, B b, C c, D d )
414      {
415         this->mTriggerNext.push_back(NULL);
416         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
417         {
418            this->mTriggerNext.last() = ptr->next;
419            if( !this->getDelegate( ptr )( a, b, c, d ) )
420            {
421               this->mTriggerNext.pop_back();
422               return false;
423            }
424            ptr = this->mTriggerNext.last();
425         }
426         this->mTriggerNext.pop_back();
427         return true;
428      }
429};
430
431template<class A, class B, class C, class D, class E> 
432class Signal<bool(A,B,C,D,E)> : public SignalBaseT<bool(A,B,C,D,E)>
433{
434   public:
435
436      bool trigger( A a, B b, C c, D d, E e )
437      {
438         this->mTriggerNext.push_back(NULL);
439         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
440         {
441            this->mTriggerNext.last() = ptr->next;
442            if( !this->getDelegate( ptr )( a, b, c, d, e ) )
443            {
444               this->mTriggerNext.pop_back();
445               return false;
446            }
447            ptr = this->mTriggerNext.last();
448         }
449         this->mTriggerNext.pop_back();
450         return true;
451      }
452};
453
454template<class A, class B, class C, class D, class E, class F> 
455class Signal<bool(A,B,C,D,E,F)> : public SignalBaseT<bool(A,B,C,D,E,F)>
456{
457   public:
458
459      bool trigger( A a, B b, C c, D d, E e, F f )
460      {
461         this->mTriggerNext.push_back(NULL);
462         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
463         {
464            this->mTriggerNext.last() = ptr->next;
465            if( !this->getDelegate( ptr )( a, b, c, d, e, f ) )
466            {
467               this->mTriggerNext.pop_back();
468               return false;
469            }
470            ptr = this->mTriggerNext.last();
471         }
472         this->mTriggerNext.pop_back();
473         return true;
474      }
475};
476
477template<class A, class B, class C, class D, class E, class F, class G> 
478class Signal<bool(A,B,C,D,E,F,G)> : public SignalBaseT<bool(A,B,C,D,E,F,G)>
479{
480   public:
481
482      bool trigger( A a, B b, C c, D d, E e, F f, G g )
483      {
484         this->mTriggerNext.push_back(NULL);
485         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
486         {
487            this->mTriggerNext.last() = ptr->next;
488            if( !this->getDelegate( ptr )( a, b, c, d, e, f, g ) )
489            {
490               this->mTriggerNext.pop_back();
491               return false;
492            }
493            ptr = this->mTriggerNext.last();
494         }
495         this->mTriggerNext.pop_back();
496         return true;
497      }
498};
499
500template<class A, class B, class C, class D, class E, class F, class G, class H> 
501class Signal<bool(A,B,C,D,E,F,G,H)> : public SignalBaseT<bool(A,B,C,D,E,F,G,H)>
502{
503   public:
504
505      bool trigger( A a, B b, C c, D d, E e, F f, G g, H h )
506      {
507         this->mTriggerNext.push_back(NULL);
508         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
509         {
510            this->mTriggerNext.last() = ptr->next;
511            if( !this->getDelegate( ptr )( a, b, c, d, e, f, g, h ) )
512            {
513               this->mTriggerNext.pop_back();
514               return false;
515            }
516            ptr = this->mTriggerNext.last();
517         }
518         this->mTriggerNext.pop_back();
519         return true;
520      }
521};
522
523template<class A, class B, class C, class D, class E, class F, class G, class H, class I> 
524class Signal<bool(A,B,C,D,E,F,G,H,I)> : public SignalBaseT<bool(A,B,C,D,E,F,G,H,I)>
525{
526   public:
527
528      bool trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i )
529      {
530         this->mTriggerNext.push_back(NULL);
531         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
532         {
533            this->mTriggerNext.last() = ptr->next;
534            if( !this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i ) )
535            {
536               this->mTriggerNext.pop_back();
537               return false;
538            }
539            ptr = this->mTriggerNext.last();
540         }
541         this->mTriggerNext.pop_back();
542         return true;
543      }
544};
545
546template<class A, class B, class C, class D, class E, class F, class G, class H, class I, class J> 
547class Signal<bool(A,B,C,D,E,F,G,H,I,J)> : public SignalBaseT<bool(A,B,C,D,E,F,G,H,I,J)>
548{
549   public:
550
551      bool trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
552      {
553         this->mTriggerNext.push_back(NULL);
554         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
555         {
556            this->mTriggerNext.last() = ptr->next;
557            if( !this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j ) )
558            {
559               this->mTriggerNext.pop_back();
560               return false;
561            }
562            ptr = this->mTriggerNext.last();
563         }
564         this->mTriggerNext.pop_back();
565         return true;
566      }
567};
568
569template<class A, class B, class C, class D, class E, class F, class G, class H, class I, class J, class K> 
570class Signal<bool(A,B,C,D,E,F,G,H,I,J,K)> : public SignalBaseT<bool(A,B,C,D,E,F,G,H,I,J,K)>
571{
572   public:
573
574      bool trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
575      {
576         this->mTriggerNext.push_back(NULL);
577         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
578         {
579            this->mTriggerNext.last() = ptr->next;
580            if( !this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k ) )
581            {
582               this->mTriggerNext.pop_back();
583               return false;
584            }
585            ptr = this->mTriggerNext.last();
586         }
587         this->mTriggerNext.pop_back();
588         return true;
589      }
590};
591
592template<class A, class B, class C, class D, class E, class F, class G, class H, class I, class J, class K, class L> 
593class Signal<bool(A,B,C,D,E,F,G,H,I,J,K,L)> : public SignalBaseT<bool(A,B,C,D,E,F,G,H,I,J,K,L)>
594{
595   public:
596
597      bool trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l )
598      {
599         this->mTriggerNext.push_back(NULL);
600         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
601         {
602            this->mTriggerNext.last() = ptr->next;
603            if( !this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k, l ) )
604            {
605               this->mTriggerNext.pop_back();
606               return false;
607            }
608            ptr = this->mTriggerNext.last();
609         }
610         this->mTriggerNext.pop_back();
611         return true;
612      }
613};
614
615template<class A, class B, class C, class D, class E, class F, class G, class H, class I, class J, class K, class L, class M> 
616class Signal<bool(A,B,C,D,E,F,G,H,I,J,K,L,M)> : public SignalBaseT<bool(A,B,C,D,E,F,G,H,I,J,K,L,M)>
617{
618   public:
619
620      bool trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m )
621      {
622         this->mTriggerNext.push_back(NULL);
623         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
624         {
625            this->mTriggerNext.last() = ptr->next;
626            if( !this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k, l, m ) )
627            {
628               this->mTriggerNext.pop_back();
629               return false;
630            }
631            ptr = this->mTriggerNext.last();
632         }
633         this->mTriggerNext.pop_back();
634         return true;
635      }
636};
637
638// Non short-circuit signal implementations
639
640template<> 
641class Signal<void()> : public SignalBaseT<void()>
642{
643   public:
644
645      void trigger()
646      {
647         this->mTriggerNext.push_back(NULL);
648         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
649         {
650            this->mTriggerNext.last() = ptr->next;
651            this->getDelegate( ptr )();
652            ptr = this->mTriggerNext.last();
653         }
654         this->mTriggerNext.pop_back();
655      }
656};
657
658template<class A>
659class Signal<void(A)> : public SignalBaseT<void(A)>
660{
661   public:
662
663      void trigger( A a )
664      {
665         this->mTriggerNext.push_back(NULL);
666         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
667         {
668            this->mTriggerNext.last() = ptr->next;
669            this->getDelegate( ptr )( a );
670            ptr = this->mTriggerNext.last();
671         }
672         this->mTriggerNext.pop_back();
673      }
674};
675
676template<class A, class B> 
677class Signal<void(A,B)> : public SignalBaseT<void(A,B)>
678{
679   public:
680
681     void trigger( A a, B b )
682     {
683        this->mTriggerNext.push_back(NULL);
684        for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
685        {
686           this->mTriggerNext.last() = ptr->next;
687           this->getDelegate( ptr )( a, b );
688           ptr = this->mTriggerNext.last();
689        }
690        this->mTriggerNext.pop_back();
691      }
692};
693
694template<class A, class B, class C> 
695class Signal<void(A,B,C)> : public SignalBaseT<void(A,B,C)>
696{
697   public:
698
699      void trigger( A a, B b, C c )
700      {
701         this->mTriggerNext.push_back(NULL);
702         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
703         {
704            this->mTriggerNext.last() = ptr->next;
705            this->getDelegate( ptr )( a, b, c );
706            ptr = this->mTriggerNext.last();
707         }
708         this->mTriggerNext.pop_back();
709      }
710};
711
712template<class A, class B, class C, class D>
713class Signal<void(A,B,C,D)> : public SignalBaseT<void(A,B,C,D)>
714{
715   public:
716
717      void trigger( A a, B b, C c, D d )
718      {
719         this->mTriggerNext.push_back(NULL);
720         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
721         {
722            this->mTriggerNext.last() = ptr->next;
723            this->getDelegate( ptr )( a, b, c, d );
724            ptr = this->mTriggerNext.last();
725         }
726         this->mTriggerNext.pop_back();
727      }
728};
729
730template<class A, class B, class C, class D, class E> 
731class Signal<void(A,B,C,D,E)> : public SignalBaseT<void(A,B,C,D,E)>
732{
733   public:
734
735      void trigger( A a, B b, C c, D d, E e )
736      {
737         this->mTriggerNext.push_back(NULL);
738         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
739         {
740            this->mTriggerNext.last() = ptr->next;
741            this->getDelegate( ptr )( a, b, c, d, e );
742            ptr = this->mTriggerNext.last();
743         }
744         this->mTriggerNext.pop_back();
745      }
746};
747
748template<class A, class B, class C, class D, class E, class F> 
749class Signal<void(A,B,C,D,E,F)> : public SignalBaseT<void(A,B,C,D,E,F)>
750{
751   public:
752
753      void trigger( A a, B b, C c, D d, E e, F f )
754      {
755         this->mTriggerNext.push_back(NULL);
756         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
757         {
758            this->mTriggerNext.last() = ptr->next;
759            this->getDelegate( ptr )( a, b, c, d, e, f );
760            ptr = this->mTriggerNext.last();
761         }
762         this->mTriggerNext.pop_back();
763      }
764};
765
766template<class A, class B, class C, class D, class E, class F, class G> 
767class Signal<void(A,B,C,D,E,F,G)> : public SignalBaseT<void(A,B,C,D,E,F,G)>
768{
769   public:
770
771      void trigger( A a, B b, C c, D d, E e, F f, G g )
772      {
773         this->mTriggerNext.push_back(NULL);
774         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
775         {
776            this->mTriggerNext.last() = ptr->next;
777            this->getDelegate( ptr )( a, b, c, d, e, f, g );
778            ptr = this->mTriggerNext.last();
779         }
780         this->mTriggerNext.pop_back();
781      }
782};
783
784template<class A, class B, class C, class D, class E, class F, class G, class H> 
785class Signal<void(A,B,C,D,E,F,G,H)> : public SignalBaseT<void(A,B,C,D,E,F,G,H)>
786{
787   public:
788
789      void trigger( A a, B b, C c, D d, E e, F f, G g, H h )
790      {
791         this->mTriggerNext.push_back(NULL);
792         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
793         {
794            this->mTriggerNext.last() = ptr->next;
795            this->getDelegate( ptr )( a, b, c, d, e, f, g, h );
796            ptr = this->mTriggerNext.last();
797         }
798         this->mTriggerNext.pop_back();
799      }
800};
801
802template<class A, class B, class C, class D, class E, class F, class G, class H, class I> 
803class Signal<void(A,B,C,D,E,F,G,H,I)> : public SignalBaseT<void(A,B,C,D,E,F,G,H,I)>
804{
805   public:
806
807      void trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i )
808      {
809         this->mTriggerNext.push_back(NULL);
810         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
811         {
812            this->mTriggerNext.last() = ptr->next;
813            this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i );
814            ptr = this->mTriggerNext.last();
815         }
816         this->mTriggerNext.pop_back();
817      }
818};
819
820template<class A, class B, class C, class D, class E, class F, class G, class H, class I, class J> 
821class Signal<void(A,B,C,D,E,F,G,H,I,J)> : public SignalBaseT<void(A,B,C,D,E,F,G,H,I,J)>
822{
823   public:
824
825      void trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
826      {
827         this->mTriggerNext.push_back(NULL);
828         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
829         {
830            this->mTriggerNext.last() = ptr->next;
831            this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j );
832            ptr = this->mTriggerNext.last();
833         }
834         this->mTriggerNext.pop_back();
835      }
836};
837
838template<class A, class B, class C, class D, class E, class F, class G, class H, class I, class J, class K> 
839class Signal<void(A,B,C,D,E,F,G,H,I,J,K)> : public SignalBaseT<void(A,B,C,D,E,F,G,H,I,J,K)>
840{
841   public:
842
843      void trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
844      {
845         this->mTriggerNext.push_back(NULL);
846         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
847         {
848            this->mTriggerNext.last() = ptr->next;
849            this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k );
850            ptr = this->mTriggerNext.last();
851         }
852         this->mTriggerNext.pop_back();
853      }
854};
855
856template<class A, class B, class C, class D, class E, class F, class G, class H, class I, class J, class K, class L> 
857class Signal<void(A,B,C,D,E,F,G,H,I,J,K,L)> : public SignalBaseT<void(A,B,C,D,E,F,G,H,I,J,K,L)>
858{
859   public:
860
861      void trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l )
862      {
863         this->mTriggerNext.push_back(NULL);
864         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
865         {
866            this->mTriggerNext.last() = ptr->next;
867            this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k, l );
868            ptr = this->mTriggerNext.last();
869         }
870         this->mTriggerNext.pop_back();
871      }
872};
873
874template<class A, class B, class C, class D, class E, class F, class G, class H, class I, class J, class K, class L, class M> 
875class Signal<void(A,B,C,D,E,F,G,H,I,J,K,L,M)> : public SignalBaseT<void(A,B,C,D,E,F,G,H,I,J,K,L,M)>
876{
877   public:
878
879      void trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m )
880      {
881         this->mTriggerNext.push_back(NULL);
882         for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; )
883         {
884            this->mTriggerNext.last() = ptr->next;
885            this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k, l, m );
886            ptr = this->mTriggerNext.last();
887         }
888         this->mTriggerNext.pop_back();
889      }
890};
891
892#endif // _TSIGNAL_H_
893