tSignal.h 26 KB

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