/src/utils/Sigslot.h

http://sumatrapdf.googlecode.com/ · C Header · 1860 lines · 1542 code · 293 blank · 25 comment · 155 complexity · ed6dd9c8ac556ee0b49b8c780b758654 MD5 · raw file

Large files are truncated click here to view the full file

  1. // sigslot.h: Signal/Slot classes
  2. //
  3. // Written by Sarah Thompson (sarah@telergy.com) 2002.
  4. //
  5. // License: Public domain. You are free to use this code however you like, with the proviso that
  6. // the author takes on no responsibility or liability for any use.
  7. // See full documentation at http://sigslot.sourceforge.net/)
  8. //
  9. // Sumatra notes:
  10. // - we removed non-windows code
  11. // - we only use multi_threaded_global threading policy, support for other
  12. // policies has been removed
  13. // - we replaced use of stl with our Vec
  14. //
  15. // TODO: optimize storage. Instead of having a Vec inside each has_slot,
  16. // they could use linked list and only a single pointer to the list.
  17. // allocations would be done from a single VecSegmented and freed item
  18. // would be put on a free list, so that we can reuse them
  19. #ifndef SIGSLOT_H__
  20. #define SIGSLOT_H__
  21. // including <list> at this point breaks debug compilation
  22. // under VS2008 due to the redefined operator new
  23. namespace std {
  24. template <typename T>
  25. class list : protected Vec<T> {
  26. public:
  27. list() { }
  28. T* begin() const { return els; }
  29. T* end() const { return els + len; }
  30. void push_back(T el) { Append(el); }
  31. void erase(T *el, T *end=NULL) { RemoveAt(el - els, end ? end - el : 1); }
  32. typedef T* iterator;
  33. typedef const T* const_iterator;
  34. };
  35. }
  36. namespace sigslot {
  37. class lock_block
  38. {
  39. public:
  40. lock_block()
  41. {
  42. static bool isinitialised = false;
  43. if (!isinitialised)
  44. {
  45. InitializeCriticalSection(get_critsec());
  46. isinitialised = true;
  47. }
  48. EnterCriticalSection(get_critsec());
  49. }
  50. ~lock_block() { LeaveCriticalSection(get_critsec()); }
  51. private:
  52. lock_block(const lock_block&) { }
  53. CRITICAL_SECTION* get_critsec()
  54. {
  55. static CRITICAL_SECTION g_critsec;
  56. return &g_critsec;
  57. }
  58. };
  59. class has_slots;
  60. class _connection_base0
  61. {
  62. public:
  63. virtual has_slots* getdest() const = 0;
  64. virtual void emit() = 0;
  65. virtual _connection_base0* clone() = 0;
  66. virtual _connection_base0* duplicate(has_slots* pnewdest) = 0;
  67. };
  68. template<class arg1_t>
  69. class _connection_base1
  70. {
  71. public:
  72. virtual has_slots* getdest() const = 0;
  73. virtual void emit(arg1_t) = 0;
  74. virtual _connection_base1<arg1_t>* clone() = 0;
  75. virtual _connection_base1<arg1_t>* duplicate(has_slots* pnewdest) = 0;
  76. };
  77. template<class arg1_t, class arg2_t>
  78. class _connection_base2
  79. {
  80. public:
  81. virtual has_slots* getdest() const = 0;
  82. virtual void emit(arg1_t, arg2_t) = 0;
  83. virtual _connection_base2<arg1_t, arg2_t>* clone() = 0;
  84. virtual _connection_base2<arg1_t, arg2_t>* duplicate(has_slots* pnewdest) = 0;
  85. };
  86. template<class arg1_t, class arg2_t, class arg3_t>
  87. class _connection_base3
  88. {
  89. public:
  90. virtual has_slots* getdest() const = 0;
  91. virtual void emit(arg1_t, arg2_t, arg3_t) = 0;
  92. virtual _connection_base3<arg1_t, arg2_t, arg3_t>* clone() = 0;
  93. virtual _connection_base3<arg1_t, arg2_t, arg3_t>* duplicate(has_slots* pnewdest) = 0;
  94. };
  95. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t>
  96. class _connection_base4
  97. {
  98. public:
  99. virtual has_slots* getdest() const = 0;
  100. virtual void emit(arg1_t, arg2_t, arg3_t, arg4_t) = 0;
  101. virtual _connection_base4<arg1_t, arg2_t, arg3_t, arg4_t>* clone() = 0;
  102. virtual _connection_base4<arg1_t, arg2_t, arg3_t, arg4_t>* duplicate(has_slots* pnewdest) = 0;
  103. };
  104. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t,
  105. class arg5_t>
  106. class _connection_base5
  107. {
  108. public:
  109. virtual has_slots* getdest() const = 0;
  110. virtual void emit(arg1_t, arg2_t, arg3_t, arg4_t,
  111. arg5_t) = 0;
  112. virtual _connection_base5<arg1_t, arg2_t, arg3_t, arg4_t,
  113. arg5_t>* clone() = 0;
  114. virtual _connection_base5<arg1_t, arg2_t, arg3_t, arg4_t,
  115. arg5_t>* duplicate(has_slots* pnewdest) = 0;
  116. };
  117. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t,
  118. class arg5_t, class arg6_t>
  119. class _connection_base6
  120. {
  121. public:
  122. virtual has_slots* getdest() const = 0;
  123. virtual void emit(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t,
  124. arg6_t) = 0;
  125. virtual _connection_base6<arg1_t, arg2_t, arg3_t, arg4_t,
  126. arg5_t, arg6_t>* clone() = 0;
  127. virtual _connection_base6<arg1_t, arg2_t, arg3_t, arg4_t,
  128. arg5_t, arg6_t>* duplicate(has_slots* pnewdest) = 0;
  129. };
  130. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t,
  131. class arg5_t, class arg6_t, class arg7_t>
  132. class _connection_base7
  133. {
  134. public:
  135. virtual has_slots* getdest() const = 0;
  136. virtual void emit(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t,
  137. arg6_t, arg7_t) = 0;
  138. virtual _connection_base7<arg1_t, arg2_t, arg3_t, arg4_t,
  139. arg5_t, arg6_t, arg7_t>* clone() = 0;
  140. virtual _connection_base7<arg1_t, arg2_t, arg3_t, arg4_t,
  141. arg5_t, arg6_t, arg7_t>* duplicate(has_slots* pnewdest) = 0;
  142. };
  143. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t,
  144. class arg5_t, class arg6_t, class arg7_t, class arg8_t>
  145. class _connection_base8
  146. {
  147. public:
  148. virtual has_slots* getdest() const = 0;
  149. virtual void emit(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t,
  150. arg6_t, arg7_t, arg8_t) = 0;
  151. virtual _connection_base8<arg1_t, arg2_t, arg3_t, arg4_t,
  152. arg5_t, arg6_t, arg7_t, arg8_t>* clone() = 0;
  153. virtual _connection_base8<arg1_t, arg2_t, arg3_t, arg4_t,
  154. arg5_t, arg6_t, arg7_t, arg8_t>* duplicate(has_slots* pnewdest) = 0;
  155. };
  156. class _signal_base
  157. {
  158. public:
  159. virtual void slot_disconnect(has_slots* pslot) = 0;
  160. virtual void slot_duplicate(const has_slots* poldslot, has_slots* pnewslot) = 0;
  161. };
  162. class has_slots
  163. {
  164. private:
  165. // m_senders is a set i.e. no duplicates
  166. Vec<_signal_base *> m_senders;
  167. public:
  168. has_slots() { }
  169. has_slots(const has_slots& hs)
  170. {
  171. lock_block lock;
  172. for (size_t i = 0; i < hs.m_senders.Count(); i++) {
  173. _signal_base *s = hs.m_senders.At(i);
  174. s->slot_duplicate(&hs, this);
  175. m_senders.Append(s);
  176. }
  177. }
  178. void signal_connect(_signal_base* sender)
  179. {
  180. lock_block lock;
  181. // ensure set semantics (i.e. no duplicates)
  182. if (-1 == m_senders.Find(sender))
  183. m_senders.Append(sender);
  184. }
  185. void signal_disconnect(_signal_base* sender)
  186. {
  187. lock_block lock;
  188. m_senders.Remove(sender);
  189. }
  190. // TODO: does it have to be virtual or was it only needed
  191. /// to accomodate inheriting from mt_policy, which did have
  192. // virtual functions?
  193. virtual ~has_slots()
  194. {
  195. disconnect_all();
  196. }
  197. void disconnect_all()
  198. {
  199. lock_block lock;
  200. for (size_t i = 0; i < m_senders.Count(); i++) {
  201. _signal_base *s = m_senders.At(i);
  202. s->slot_disconnect(this);
  203. }
  204. m_senders.Reset();
  205. }
  206. };
  207. class _signal_base0 : public _signal_base
  208. {
  209. public:
  210. typedef std::list<_connection_base0 *> connections_list;
  211. _signal_base0() { }
  212. _signal_base0(const _signal_base0& s)
  213. : _signal_base(s)
  214. {
  215. lock_block lock;
  216. connections_list::const_iterator it = s.m_connected_slots.begin();
  217. connections_list::const_iterator itEnd = s.m_connected_slots.end();
  218. while (it != itEnd)
  219. {
  220. (*it)->getdest()->signal_connect(this);
  221. m_connected_slots.push_back((*it)->clone());
  222. ++it;
  223. }
  224. }
  225. ~_signal_base0()
  226. {
  227. disconnect_all();
  228. }
  229. void disconnect_all()
  230. {
  231. lock_block lock;
  232. connections_list::const_iterator it = m_connected_slots.begin();
  233. connections_list::const_iterator itEnd = m_connected_slots.end();
  234. while (it != itEnd)
  235. {
  236. (*it)->getdest()->signal_disconnect(this);
  237. delete *it;
  238. ++it;
  239. }
  240. m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
  241. }
  242. void disconnect(has_slots* pclass)
  243. {
  244. lock_block lock;
  245. connections_list::iterator it = m_connected_slots.begin();
  246. connections_list::iterator itEnd = m_connected_slots.end();
  247. while (it != itEnd)
  248. {
  249. if ((*it)->getdest() == pclass)
  250. {
  251. delete *it;
  252. m_connected_slots.erase(it);
  253. pclass->signal_disconnect(this);
  254. return;
  255. }
  256. ++it;
  257. }
  258. }
  259. void slot_disconnect(has_slots* pslot)
  260. {
  261. lock_block lock;
  262. connections_list::iterator it = m_connected_slots.begin();
  263. connections_list::iterator itEnd = m_connected_slots.end();
  264. while (it != itEnd)
  265. {
  266. connections_list::iterator itNext = it;
  267. ++itNext;
  268. if ((*it)->getdest() == pslot)
  269. {
  270. m_connected_slots.erase(it);
  271. }
  272. it = itNext;
  273. }
  274. }
  275. void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget)
  276. {
  277. lock_block lock;
  278. connections_list::iterator it = m_connected_slots.begin();
  279. connections_list::iterator itEnd = m_connected_slots.end();
  280. while (it != itEnd)
  281. {
  282. if ((*it)->getdest() == oldtarget)
  283. {
  284. m_connected_slots.push_back((*it)->duplicate(newtarget));
  285. }
  286. ++it;
  287. }
  288. }
  289. protected:
  290. connections_list m_connected_slots;
  291. };
  292. template<class arg1_t>
  293. class _signal_base1 : public _signal_base
  294. {
  295. public:
  296. typedef std::list<_connection_base1<arg1_t> *> connections_list;
  297. _signal_base1() { }
  298. _signal_base1(const _signal_base1<arg1_t>& s)
  299. : _signal_base(s)
  300. {
  301. lock_block lock;
  302. connections_list::const_iterator it = s.m_connected_slots.begin();
  303. connections_list::const_iterator itEnd = s.m_connected_slots.end();
  304. while (it != itEnd)
  305. {
  306. (*it)->getdest()->signal_connect(this);
  307. m_connected_slots.push_back((*it)->clone());
  308. ++it;
  309. }
  310. }
  311. void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget)
  312. {
  313. lock_block lock;
  314. connections_list::iterator it = m_connected_slots.begin();
  315. connections_list::iterator itEnd = m_connected_slots.end();
  316. while (it != itEnd)
  317. {
  318. if ((*it)->getdest() == oldtarget)
  319. {
  320. m_connected_slots.push_back((*it)->duplicate(newtarget));
  321. }
  322. ++it;
  323. }
  324. }
  325. ~_signal_base1()
  326. {
  327. disconnect_all();
  328. }
  329. void disconnect_all()
  330. {
  331. lock_block lock;
  332. connections_list::const_iterator it = m_connected_slots.begin();
  333. connections_list::const_iterator itEnd = m_connected_slots.end();
  334. while (it != itEnd)
  335. {
  336. (*it)->getdest()->signal_disconnect(this);
  337. delete *it;
  338. ++it;
  339. }
  340. m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
  341. }
  342. void disconnect(has_slots* pclass)
  343. {
  344. lock_block lock;
  345. connections_list::iterator it = m_connected_slots.begin();
  346. connections_list::iterator itEnd = m_connected_slots.end();
  347. while (it != itEnd)
  348. {
  349. if ((*it)->getdest() == pclass)
  350. {
  351. delete *it;
  352. m_connected_slots.erase(it);
  353. pclass->signal_disconnect(this);
  354. return;
  355. }
  356. ++it;
  357. }
  358. }
  359. void slot_disconnect(has_slots* pslot)
  360. {
  361. lock_block lock;
  362. connections_list::iterator it = m_connected_slots.begin();
  363. connections_list::iterator itEnd = m_connected_slots.end();
  364. while (it != itEnd)
  365. {
  366. connections_list::iterator itNext = it;
  367. ++itNext;
  368. if ((*it)->getdest() == pslot)
  369. m_connected_slots.erase(it);
  370. it = itNext;
  371. }
  372. }
  373. protected:
  374. connections_list m_connected_slots;
  375. };
  376. template<class arg1_t, class arg2_t>
  377. class _signal_base2 : public _signal_base
  378. {
  379. protected:
  380. typedef _connection_base2<arg1_t, arg2_t> conn_t;
  381. Vec<conn_t *> m_connections;
  382. public:
  383. _signal_base2() { }
  384. _signal_base2(const _signal_base2<arg1_t, arg2_t>& s)
  385. : _signal_base(s)
  386. {
  387. lock_block lock;
  388. for (conn_t** c = s.m_connections.IterStart(); c; c = s.m_connections.IterNext()) {
  389. (*c)->getdest()->signal_connect(this);
  390. m_connections.Append((*c)->clone());
  391. }
  392. }
  393. void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget)
  394. {
  395. lock_block lock;
  396. size_t end = m_connections.Count(); // cache because we modify m_connections
  397. for (size_t i = 0; i < end; i++) {
  398. conn_t *c = m_connections.At(i);
  399. if (c->getdest() == oldtarget)
  400. m_connections.Append(c->duplicate(newtarget));
  401. }
  402. }
  403. ~_signal_base2()
  404. {
  405. disconnect_all();
  406. }
  407. void disconnect_all()
  408. {
  409. lock_block lock;
  410. for (conn_t** c = m_connections.IterStart(); c; c = m_connections.IterNext()) {
  411. (*c)->getdest()->signal_disconnect(this);
  412. delete *c;
  413. }
  414. m_connections.Reset();
  415. }
  416. void disconnect(has_slots* pclass)
  417. {
  418. lock_block lock;
  419. for (conn_t** c = m_connections.IterStart(); c; c = m_connections.IterNext()) {
  420. if ((*c)->getdest() == pclass)
  421. {
  422. delete *c; // must delete before Remove()
  423. m_connections.Remove(*c);
  424. pclass->signal_disconnect(this);
  425. return;
  426. }
  427. }
  428. }
  429. void slot_disconnect(has_slots* pslot)
  430. {
  431. lock_block lock;
  432. size_t i = 0;
  433. while (i < m_connections.Count()) {
  434. if (m_connections.At(i)->getdest() == pslot)
  435. m_connections.RemoveAtFast(i);
  436. else
  437. i++;
  438. }
  439. }
  440. };
  441. template<class arg1_t, class arg2_t, class arg3_t>
  442. class _signal_base3 : public _signal_base
  443. {
  444. protected:
  445. typedef _connection_base3<arg1_t, arg2_t, arg3_t> conn_t;
  446. Vec<conn_t *> m_connections;
  447. public:
  448. _signal_base3() { }
  449. _signal_base3(const _signal_base3<arg1_t, arg2_t, arg3_t>& s)
  450. : _signal_base(s)
  451. {
  452. lock_block lock;
  453. for (conn_t** c = s.m_connections.IterStart(); c; c = s.m_connections.IterNext()) {
  454. (*c)->getdest()->signal_connect(this);
  455. m_connections.Append((*c)->clone());
  456. }
  457. }
  458. void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget)
  459. {
  460. lock_block lock;
  461. size_t end = m_connections.Count(); // cache because we modify m_connections
  462. for (size_t i = 0; i < end; i++) {
  463. conn_t *c = m_connections.At(i);
  464. if (c->getdest() == oldtarget)
  465. m_connections.Append(c->duplicate(newtarget));
  466. }
  467. }
  468. ~_signal_base3()
  469. {
  470. disconnect_all();
  471. }
  472. void disconnect_all()
  473. {
  474. lock_block lock;
  475. for (conn_t** c = m_connections.IterStart(); c; c = m_connections.IterNext()) {
  476. (*c)->getdest()->signal_disconnect(this);
  477. delete *c;
  478. }
  479. m_connections.Reset();
  480. }
  481. void disconnect(has_slots* pclass)
  482. {
  483. lock_block lock;
  484. for (conn_t** c = m_connections.IterStart(); c; c = m_connections.IterNext()) {
  485. if ((*c)->getdest() == pclass)
  486. {
  487. delete *c; // must delete before Remove()
  488. m_connections.Remove(*c);
  489. pclass->signal_disconnect(this);
  490. return;
  491. }
  492. }
  493. }
  494. void slot_disconnect(has_slots* pslot)
  495. {
  496. lock_block lock;
  497. size_t i = 0;
  498. while (i < m_connections.Count()) {
  499. if (m_connections.At(i)->getdest() == pslot)
  500. m_connections.RemoveAtFast(i);
  501. else
  502. i++;
  503. }
  504. }
  505. };
  506. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t>
  507. class _signal_base4 : public _signal_base
  508. {
  509. public:
  510. typedef std::list<_connection_base4<arg1_t, arg2_t, arg3_t,
  511. arg4_t> *> connections_list;
  512. _signal_base4() { }
  513. _signal_base4(const _signal_base4<arg1_t, arg2_t, arg3_t, arg4_t>& s)
  514. : _signal_base(s)
  515. {
  516. lock_block lock;
  517. connections_list::const_iterator it = s.m_connected_slots.begin();
  518. connections_list::const_iterator itEnd = s.m_connected_slots.end();
  519. while (it != itEnd)
  520. {
  521. (*it)->getdest()->signal_connect(this);
  522. m_connected_slots.push_back((*it)->clone());
  523. ++it;
  524. }
  525. }
  526. void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget)
  527. {
  528. lock_block lock;
  529. connections_list::iterator it = m_connected_slots.begin();
  530. connections_list::iterator itEnd = m_connected_slots.end();
  531. while (it != itEnd)
  532. {
  533. if ((*it)->getdest() == oldtarget)
  534. {
  535. m_connected_slots.push_back((*it)->duplicate(newtarget));
  536. }
  537. ++it;
  538. }
  539. }
  540. ~_signal_base4()
  541. {
  542. disconnect_all();
  543. }
  544. void disconnect_all()
  545. {
  546. lock_block lock;
  547. connections_list::const_iterator it = m_connected_slots.begin();
  548. connections_list::const_iterator itEnd = m_connected_slots.end();
  549. while (it != itEnd)
  550. {
  551. (*it)->getdest()->signal_disconnect(this);
  552. delete *it;
  553. ++it;
  554. }
  555. m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
  556. }
  557. void disconnect(has_slots* pclass)
  558. {
  559. lock_block lock;
  560. connections_list::iterator it = m_connected_slots.begin();
  561. connections_list::iterator itEnd = m_connected_slots.end();
  562. while (it != itEnd)
  563. {
  564. if ((*it)->getdest() == pclass)
  565. {
  566. delete *it;
  567. m_connected_slots.erase(it);
  568. pclass->signal_disconnect(this);
  569. return;
  570. }
  571. ++it;
  572. }
  573. }
  574. void slot_disconnect(has_slots* pslot)
  575. {
  576. lock_block lock;
  577. connections_list::iterator it = m_connected_slots.begin();
  578. connections_list::iterator itEnd = m_connected_slots.end();
  579. while (it != itEnd)
  580. {
  581. connections_list::iterator itNext = it;
  582. ++itNext;
  583. if ((*it)->getdest() == pslot)
  584. m_connected_slots.erase(it);
  585. it = itNext;
  586. }
  587. }
  588. protected:
  589. connections_list m_connected_slots;
  590. };
  591. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t,
  592. class arg5_t>
  593. class _signal_base5 : public _signal_base
  594. {
  595. public:
  596. typedef std::list<_connection_base5<arg1_t, arg2_t, arg3_t,
  597. arg4_t, arg5_t> *> connections_list;
  598. _signal_base5() { }
  599. _signal_base5(const _signal_base5<arg1_t, arg2_t, arg3_t, arg4_t,
  600. arg5_t>& s)
  601. : _signal_base(s)
  602. {
  603. lock_block lock;
  604. connections_list::const_iterator it = s.m_connected_slots.begin();
  605. connections_list::const_iterator itEnd = s.m_connected_slots.end();
  606. while (it != itEnd)
  607. {
  608. (*it)->getdest()->signal_connect(this);
  609. m_connected_slots.push_back((*it)->clone());
  610. ++it;
  611. }
  612. }
  613. void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget)
  614. {
  615. lock_block lock;
  616. connections_list::iterator it = m_connected_slots.begin();
  617. connections_list::iterator itEnd = m_connected_slots.end();
  618. while (it != itEnd)
  619. {
  620. if ((*it)->getdest() == oldtarget)
  621. {
  622. m_connected_slots.push_back((*it)->duplicate(newtarget));
  623. }
  624. ++it;
  625. }
  626. }
  627. ~_signal_base5()
  628. {
  629. disconnect_all();
  630. }
  631. void disconnect_all()
  632. {
  633. lock_block lock;
  634. connections_list::const_iterator it = m_connected_slots.begin();
  635. connections_list::const_iterator itEnd = m_connected_slots.end();
  636. while (it != itEnd)
  637. {
  638. (*it)->getdest()->signal_disconnect(this);
  639. delete *it;
  640. ++it;
  641. }
  642. m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
  643. }
  644. void disconnect(has_slots* pclass)
  645. {
  646. lock_block lock;
  647. connections_list::iterator it = m_connected_slots.begin();
  648. connections_list::iterator itEnd = m_connected_slots.end();
  649. while (it != itEnd)
  650. {
  651. if ((*it)->getdest() == pclass)
  652. {
  653. delete *it;
  654. m_connected_slots.erase(it);
  655. pclass->signal_disconnect(this);
  656. return;
  657. }
  658. ++it;
  659. }
  660. }
  661. void slot_disconnect(has_slots* pslot)
  662. {
  663. lock_block lock;
  664. connections_list::iterator it = m_connected_slots.begin();
  665. connections_list::iterator itEnd = m_connected_slots.end();
  666. while (it != itEnd)
  667. {
  668. connections_list::iterator itNext = it;
  669. ++itNext;
  670. if ((*it)->getdest() == pslot)
  671. m_connected_slots.erase(it);
  672. it = itNext;
  673. }
  674. }
  675. protected:
  676. connections_list m_connected_slots;
  677. };
  678. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t>
  679. class _signal_base6 : public _signal_base
  680. {
  681. public:
  682. typedef std::list<_connection_base6<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t> *> connections_list;
  683. _signal_base6() { }
  684. _signal_base6(const _signal_base6<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t>& s)
  685. : _signal_base(s)
  686. {
  687. lock_block lock;
  688. connections_list::const_iterator it = s.m_connected_slots.begin();
  689. connections_list::const_iterator itEnd = s.m_connected_slots.end();
  690. while (it != itEnd)
  691. {
  692. (*it)->getdest()->signal_connect(this);
  693. m_connected_slots.push_back((*it)->clone());
  694. ++it;
  695. }
  696. }
  697. void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget)
  698. {
  699. lock_block lock;
  700. connections_list::iterator it = m_connected_slots.begin();
  701. connections_list::iterator itEnd = m_connected_slots.end();
  702. while (it != itEnd)
  703. {
  704. if ((*it)->getdest() == oldtarget)
  705. {
  706. m_connected_slots.push_back((*it)->duplicate(newtarget));
  707. }
  708. ++it;
  709. }
  710. }
  711. ~_signal_base6()
  712. {
  713. disconnect_all();
  714. }
  715. void disconnect_all()
  716. {
  717. lock_block lock;
  718. connections_list::const_iterator it = m_connected_slots.begin();
  719. connections_list::const_iterator itEnd = m_connected_slots.end();
  720. while (it != itEnd)
  721. {
  722. (*it)->getdest()->signal_disconnect(this);
  723. delete *it;
  724. ++it;
  725. }
  726. m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
  727. }
  728. void disconnect(has_slots* pclass)
  729. {
  730. lock_block lock;
  731. connections_list::iterator it = m_connected_slots.begin();
  732. connections_list::iterator itEnd = m_connected_slots.end();
  733. while (it != itEnd)
  734. {
  735. if ((*it)->getdest() == pclass)
  736. {
  737. delete *it;
  738. m_connected_slots.erase(it);
  739. pclass->signal_disconnect(this);
  740. return;
  741. }
  742. ++it;
  743. }
  744. }
  745. void slot_disconnect(has_slots* pslot)
  746. {
  747. lock_block lock;
  748. connections_list::iterator it = m_connected_slots.begin();
  749. connections_list::iterator itEnd = m_connected_slots.end();
  750. while (it != itEnd)
  751. {
  752. connections_list::iterator itNext = it;
  753. ++itNext;
  754. if ((*it)->getdest() == pslot)
  755. m_connected_slots.erase(it);
  756. it = itNext;
  757. }
  758. }
  759. protected:
  760. connections_list m_connected_slots;
  761. };
  762. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t>
  763. class _signal_base7 : public _signal_base
  764. {
  765. public:
  766. typedef std::list<_connection_base7<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t> *> connections_list;
  767. _signal_base7() {}
  768. _signal_base7(const _signal_base7<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t>& s)
  769. : _signal_base(s)
  770. {
  771. lock_block lock;
  772. connections_list::const_iterator it = s.m_connected_slots.begin();
  773. connections_list::const_iterator itEnd = s.m_connected_slots.end();
  774. while (it != itEnd)
  775. {
  776. (*it)->getdest()->signal_connect(this);
  777. m_connected_slots.push_back((*it)->clone());
  778. ++it;
  779. }
  780. }
  781. void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget)
  782. {
  783. lock_block lock;
  784. connections_list::iterator it = m_connected_slots.begin();
  785. connections_list::iterator itEnd = m_connected_slots.end();
  786. while (it != itEnd)
  787. {
  788. if ((*it)->getdest() == oldtarget)
  789. m_connected_slots.push_back((*it)->duplicate(newtarget));
  790. ++it;
  791. }
  792. }
  793. ~_signal_base7()
  794. {
  795. disconnect_all();
  796. }
  797. void disconnect_all()
  798. {
  799. lock_block lock;
  800. connections_list::const_iterator it = m_connected_slots.begin();
  801. connections_list::const_iterator itEnd = m_connected_slots.end();
  802. while (it != itEnd)
  803. {
  804. (*it)->getdest()->signal_disconnect(this);
  805. delete *it;
  806. ++it;
  807. }
  808. m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
  809. }
  810. void disconnect(has_slots* pclass)
  811. {
  812. lock_block lock;
  813. connections_list::iterator it = m_connected_slots.begin();
  814. connections_list::iterator itEnd = m_connected_slots.end();
  815. while (it != itEnd)
  816. {
  817. if ((*it)->getdest() == pclass)
  818. {
  819. delete *it;
  820. m_connected_slots.erase(it);
  821. pclass->signal_disconnect(this);
  822. return;
  823. }
  824. ++it;
  825. }
  826. }
  827. void slot_disconnect(has_slots* pslot)
  828. {
  829. lock_block lock;
  830. connections_list::iterator it = m_connected_slots.begin();
  831. connections_list::iterator itEnd = m_connected_slots.end();
  832. while (it != itEnd)
  833. {
  834. connections_list::iterator itNext = it;
  835. ++itNext;
  836. if ((*it)->getdest() == pslot)
  837. m_connected_slots.erase(it);
  838. it = itNext;
  839. }
  840. }
  841. protected:
  842. connections_list m_connected_slots;
  843. };
  844. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t, class arg8_t>
  845. class _signal_base8 : public _signal_base
  846. {
  847. public:
  848. typedef std::list<_connection_base8<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t> *>
  849. connections_list;
  850. _signal_base8() { }
  851. _signal_base8(const _signal_base8<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t>& s)
  852. : _signal_base(s)
  853. {
  854. lock_block lock;
  855. connections_list::const_iterator it = s.m_connected_slots.begin();
  856. connections_list::const_iterator itEnd = s.m_connected_slots.end();
  857. while (it != itEnd)
  858. {
  859. (*it)->getdest()->signal_connect(this);
  860. m_connected_slots.push_back((*it)->clone());
  861. ++it;
  862. }
  863. }
  864. void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget)
  865. {
  866. lock_block lock;
  867. connections_list::iterator it = m_connected_slots.begin();
  868. connections_list::iterator itEnd = m_connected_slots.end();
  869. while (it != itEnd)
  870. {
  871. if ((*it)->getdest() == oldtarget)
  872. m_connected_slots.push_back((*it)->duplicate(newtarget));
  873. ++it;
  874. }
  875. }
  876. ~_signal_base8()
  877. {
  878. disconnect_all();
  879. }
  880. void disconnect_all()
  881. {
  882. lock_block lock;
  883. connections_list::const_iterator it = m_connected_slots.begin();
  884. connections_list::const_iterator itEnd = m_connected_slots.end();
  885. while (it != itEnd)
  886. {
  887. (*it)->getdest()->signal_disconnect(this);
  888. delete *it;
  889. ++it;
  890. }
  891. m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
  892. }
  893. void disconnect(has_slots* pclass)
  894. {
  895. lock_block lock;
  896. connections_list::iterator it = m_connected_slots.begin();
  897. connections_list::iterator itEnd = m_connected_slots.end();
  898. while (it != itEnd)
  899. {
  900. if ((*it)->getdest() == pclass)
  901. {
  902. delete *it;
  903. m_connected_slots.erase(it);
  904. pclass->signal_disconnect(this);
  905. return;
  906. }
  907. ++it;
  908. }
  909. }
  910. void slot_disconnect(has_slots* pslot)
  911. {
  912. lock_block lock;
  913. connections_list::iterator it = m_connected_slots.begin();
  914. connections_list::iterator itEnd = m_connected_slots.end();
  915. while (it != itEnd)
  916. {
  917. connections_list::iterator itNext = it;
  918. ++itNext;
  919. if ((*it)->getdest() == pslot)
  920. m_connected_slots.erase(it);
  921. it = itNext;
  922. }
  923. }
  924. protected:
  925. connections_list m_connected_slots;
  926. };
  927. template<class dest_type>
  928. class _connection0 : public _connection_base0
  929. {
  930. public:
  931. _connection0()
  932. {
  933. pobject = NULL;
  934. pmemfun = NULL;
  935. }
  936. _connection0(dest_type* pobject, void (dest_type::*pmemfun)())
  937. {
  938. m_pobject = pobject;
  939. m_pmemfun = pmemfun;
  940. }
  941. virtual _connection_base0* clone()
  942. {
  943. return new _connection0<dest_type>(*this);
  944. }
  945. virtual _connection_base0* duplicate(has_slots* pnewdest)
  946. {
  947. return new _connection0<dest_type>((dest_type *)pnewdest, m_pmemfun);
  948. }
  949. virtual void emit()
  950. {
  951. (m_pobject->*m_pmemfun)();
  952. }
  953. virtual has_slots* getdest() const
  954. {
  955. return m_pobject;
  956. }
  957. private:
  958. dest_type* m_pobject;
  959. void (dest_type::* m_pmemfun)();
  960. };
  961. template<class dest_type, class arg1_t>
  962. class _connection1 : public _connection_base1<arg1_t>
  963. {
  964. public:
  965. _connection1()
  966. {
  967. pobject = NULL;
  968. pmemfun = NULL;
  969. }
  970. _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_t))
  971. {
  972. m_pobject = pobject;
  973. m_pmemfun = pmemfun;
  974. }
  975. virtual _connection_base1<arg1_t>* clone()
  976. {
  977. return new _connection1<dest_type, arg1_t>(*this);
  978. }
  979. virtual _connection_base1<arg1_t>* duplicate(has_slots* pnewdest)
  980. {
  981. return new _connection1<dest_type, arg1_t>((dest_type *)pnewdest, m_pmemfun);
  982. }
  983. virtual void emit(arg1_t a1)
  984. {
  985. (m_pobject->*m_pmemfun)(a1);
  986. }
  987. virtual has_slots* getdest() const
  988. {
  989. return m_pobject;
  990. }
  991. private:
  992. dest_type* m_pobject;
  993. void (dest_type::* m_pmemfun)(arg1_t);
  994. };
  995. template<class dest_type, class arg1_t, class arg2_t>
  996. class _connection2 : public _connection_base2<arg1_t, arg2_t>
  997. {
  998. public:
  999. _connection2()
  1000. {
  1001. pobject = NULL;
  1002. pmemfun = NULL;
  1003. }
  1004. _connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_t,
  1005. arg2_t))
  1006. {
  1007. m_pobject = pobject;
  1008. m_pmemfun = pmemfun;
  1009. }
  1010. virtual _connection_base2<arg1_t, arg2_t>* clone()
  1011. {
  1012. return new _connection2<dest_type, arg1_t, arg2_t>(*this);
  1013. }
  1014. virtual _connection_base2<arg1_t, arg2_t>* duplicate(has_slots* pnewdest)
  1015. {
  1016. return new _connection2<dest_type, arg1_t, arg2_t>((dest_type *)pnewdest, m_pmemfun);
  1017. }
  1018. virtual void emit(arg1_t a1, arg2_t a2)
  1019. {
  1020. (m_pobject->*m_pmemfun)(a1, a2);
  1021. }
  1022. virtual has_slots* getdest() const
  1023. {
  1024. return m_pobject;
  1025. }
  1026. private:
  1027. dest_type* m_pobject;
  1028. void (dest_type::* m_pmemfun)(arg1_t, arg2_t);
  1029. };
  1030. template<class dest_type, class arg1_t, class arg2_t, class arg3_t>
  1031. class _connection3 : public _connection_base3<arg1_t, arg2_t, arg3_t>
  1032. {
  1033. public:
  1034. _connection3()
  1035. {
  1036. pobject = NULL;
  1037. pmemfun = NULL;
  1038. }
  1039. _connection3(dest_type* pobject, void (dest_type::*pmemfun)(arg1_t,
  1040. arg2_t, arg3_t))
  1041. {
  1042. m_pobject = pobject;
  1043. m_pmemfun = pmemfun;
  1044. }
  1045. virtual _connection_base3<arg1_t, arg2_t, arg3_t>* clone()
  1046. {
  1047. return new _connection3<dest_type, arg1_t, arg2_t, arg3_t>(*this);
  1048. }
  1049. virtual _connection_base3<arg1_t, arg2_t, arg3_t>* duplicate(has_slots* pnewdest)
  1050. {
  1051. return new _connection3<dest_type, arg1_t, arg2_t, arg3_t>((dest_type *)pnewdest, m_pmemfun);
  1052. }
  1053. virtual void emit(arg1_t a1, arg2_t a2, arg3_t a3)
  1054. {
  1055. (m_pobject->*m_pmemfun)(a1, a2, a3);
  1056. }
  1057. virtual has_slots* getdest() const
  1058. {
  1059. return m_pobject;
  1060. }
  1061. private:
  1062. dest_type* m_pobject;
  1063. void (dest_type::* m_pmemfun)(arg1_t, arg2_t, arg3_t);
  1064. };
  1065. template<class dest_type, class arg1_t, class arg2_t, class arg3_t, class arg4_t>
  1066. class _connection4 : public _connection_base4<arg1_t, arg2_t, arg3_t, arg4_t>
  1067. {
  1068. public:
  1069. _connection4()
  1070. {
  1071. pobject = NULL;
  1072. pmemfun = NULL;
  1073. }
  1074. _connection4(dest_type* pobject, void (dest_type::*pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t))
  1075. {
  1076. m_pobject = pobject;
  1077. m_pmemfun = pmemfun;
  1078. }
  1079. virtual _connection_base4<arg1_t, arg2_t, arg3_t, arg4_t>* clone()
  1080. {
  1081. return new _connection4<dest_type, arg1_t, arg2_t, arg3_t, arg4_t>(*this);
  1082. }
  1083. virtual _connection_base4<arg1_t, arg2_t, arg3_t, arg4_t>* duplicate(has_slots* pnewdest)
  1084. {
  1085. return new _connection4<dest_type, arg1_t, arg2_t, arg3_t, arg4_t>((dest_type *)pnewdest, m_pmemfun);
  1086. }
  1087. virtual void emit(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4)
  1088. {
  1089. (m_pobject->*m_pmemfun)(a1, a2, a3, a4);
  1090. }
  1091. virtual has_slots* getdest() const
  1092. {
  1093. return m_pobject;
  1094. }
  1095. private:
  1096. dest_type* m_pobject;
  1097. void (dest_type::* m_pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t);
  1098. };
  1099. template<class dest_type, class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t>
  1100. class _connection5 : public _connection_base5<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t>
  1101. {
  1102. public:
  1103. _connection5()
  1104. {
  1105. pobject = NULL;
  1106. pmemfun = NULL;
  1107. }
  1108. _connection5(dest_type* pobject, void (dest_type::*pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t))
  1109. {
  1110. m_pobject = pobject;
  1111. m_pmemfun = pmemfun;
  1112. }
  1113. virtual _connection_base5<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t>* clone()
  1114. {
  1115. return new _connection5<dest_type, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t>(*this);
  1116. }
  1117. virtual _connection_base5<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t>* duplicate(has_slots* pnewdest)
  1118. {
  1119. return new _connection5<dest_type, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t>((dest_type *)pnewdest, m_pmemfun);
  1120. }
  1121. virtual void emit(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4, arg5_t a5)
  1122. {
  1123. (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5);
  1124. }
  1125. virtual has_slots* getdest() const
  1126. {
  1127. return m_pobject;
  1128. }
  1129. private:
  1130. dest_type* m_pobject;
  1131. void (dest_type::* m_pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t);
  1132. };
  1133. template<class dest_type, class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t>
  1134. class _connection6 : public _connection_base6<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t>
  1135. {
  1136. public:
  1137. _connection6()
  1138. {
  1139. pobject = NULL;
  1140. pmemfun = NULL;
  1141. }
  1142. _connection6(dest_type* pobject, void (dest_type::*pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t))
  1143. {
  1144. m_pobject = pobject;
  1145. m_pmemfun = pmemfun;
  1146. }
  1147. virtual _connection_base6<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t>* clone()
  1148. {
  1149. return new _connection6<dest_type, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t>(*this);
  1150. }
  1151. virtual _connection_base6<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t>* duplicate(has_slots* pnewdest)
  1152. {
  1153. return new _connection6<dest_type, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t>((dest_type *)pnewdest, m_pmemfun);
  1154. }
  1155. virtual void emit(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4, arg5_t a5, arg6_t a6)
  1156. {
  1157. (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6);
  1158. }
  1159. virtual has_slots* getdest() const
  1160. {
  1161. return m_pobject;
  1162. }
  1163. private:
  1164. dest_type* m_pobject;
  1165. void (dest_type::* m_pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t);
  1166. };
  1167. template<class dest_type, class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t>
  1168. class _connection7 : public _connection_base7<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t>
  1169. {
  1170. public:
  1171. _connection7()
  1172. {
  1173. pobject = NULL;
  1174. pmemfun = NULL;
  1175. }
  1176. _connection7(dest_type* pobject, void (dest_type::*pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t))
  1177. {
  1178. m_pobject = pobject;
  1179. m_pmemfun = pmemfun;
  1180. }
  1181. virtual _connection_base7<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t>* clone()
  1182. {
  1183. return new _connection7<dest_type, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t>(*this);
  1184. }
  1185. virtual _connection_base7<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t>* duplicate(has_slots* pnewdest)
  1186. {
  1187. return new _connection7<dest_type, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t>((dest_type *)pnewdest, m_pmemfun);
  1188. }
  1189. virtual void emit(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4, arg5_t a5, arg6_t a6, arg7_t a7)
  1190. {
  1191. (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7);
  1192. }
  1193. virtual has_slots* getdest() const
  1194. {
  1195. return m_pobject;
  1196. }
  1197. private:
  1198. dest_type* m_pobject;
  1199. void (dest_type::* m_pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t);
  1200. };
  1201. template<class dest_type, class arg1_t, class arg2_t, class arg3_t, class arg4_t, class arg5_t, class arg6_t, class arg7_t, class arg8_t>
  1202. class _connection8 : public _connection_base8<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t>
  1203. {
  1204. public:
  1205. _connection8()
  1206. {
  1207. pobject = NULL;
  1208. pmemfun = NULL;
  1209. }
  1210. _connection8(dest_type* pobject, void (dest_type::*pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t))
  1211. {
  1212. m_pobject = pobject;
  1213. m_pmemfun = pmemfun;
  1214. }
  1215. virtual _connection_base8<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t>* clone()
  1216. {
  1217. return new _connection8<dest_type, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t>(*this);
  1218. }
  1219. virtual _connection_base8<arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t>* duplicate(has_slots* pnewdest)
  1220. {
  1221. return new _connection8<dest_type, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t>((dest_type *)pnewdest, m_pmemfun);
  1222. }
  1223. virtual void emit(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4, arg5_t a5, arg6_t a6, arg7_t a7, arg8_t a8)
  1224. {
  1225. (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7, a8);
  1226. }
  1227. virtual has_slots* getdest() const
  1228. {
  1229. return m_pobject;
  1230. }
  1231. private:
  1232. dest_type* m_pobject;
  1233. void (dest_type::* m_pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t);
  1234. };
  1235. class signal0 : public _signal_base0
  1236. {
  1237. public:
  1238. signal0() { }
  1239. signal0(const signal0& s)
  1240. : _signal_base0(s)
  1241. { }
  1242. template<class desttype>
  1243. void connect(desttype* pclass, void (desttype::*pmemfun)())
  1244. {
  1245. lock_block lock;
  1246. typedef _connection0<desttype> conn_t;
  1247. conn_t* conn = new conn_t(pclass, pmemfun);
  1248. m_connected_slots.push_back(conn);
  1249. pclass->signal_connect(this);
  1250. }
  1251. void emit()
  1252. {
  1253. lock_block lock;
  1254. connections_list::const_iterator itNext, it = m_connected_slots.begin();
  1255. connections_list::const_iterator itEnd = m_connected_slots.end();
  1256. while (it != itEnd)
  1257. {
  1258. itNext = it;
  1259. ++itNext;
  1260. (*it)->emit();
  1261. it = itNext;
  1262. }
  1263. }
  1264. void operator()()
  1265. {
  1266. emit();
  1267. }
  1268. };
  1269. template<class arg1_t>
  1270. class signal1 : public _signal_base1<arg1_t>
  1271. {
  1272. public:
  1273. signal1() { }
  1274. signal1(const signal1<arg1_t>& s)
  1275. : _signal_base1<arg1_t>(s)
  1276. { }
  1277. template<class desttype>
  1278. void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_t))
  1279. {
  1280. lock_block lock;
  1281. typedef _connection1<desttype, arg1_t> conn_t;
  1282. conn_t* conn = new conn_t(pclass, pmemfun);
  1283. m_connected_slots.push_back(conn);
  1284. pclass->signal_connect(this);
  1285. }
  1286. void emit(arg1_t a1)
  1287. {
  1288. lock_block lock;
  1289. connections_list::const_iterator itNext, it = m_connected_slots.begin();
  1290. connections_list::const_iterator itEnd = m_connected_slots.end();
  1291. while (it != itEnd)
  1292. {
  1293. itNext = it;
  1294. ++itNext;
  1295. (*it)->emit(a1);
  1296. it = itNext;
  1297. }
  1298. }
  1299. void operator()(arg1_t a1)
  1300. {
  1301. emit(a1);
  1302. }
  1303. };
  1304. template<class arg1_t, class arg2_t>
  1305. class signal2 : public _signal_base2<arg1_t, arg2_t>
  1306. {
  1307. public:
  1308. signal2() { }
  1309. signal2(const signal2<arg1_t, arg2_t>& s)
  1310. : _signal_base2<arg1_t, arg2_t>(s)
  1311. { }
  1312. template<class desttype>
  1313. void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_t, arg2_t))
  1314. {
  1315. lock_block lock;
  1316. typedef _connection2<desttype, arg1_t, arg2_t> conn_t;
  1317. conn_t* conn = new conn_t(pclass, pmemfun);
  1318. m_connections.Append(conn);
  1319. pclass->signal_connect(this);
  1320. }
  1321. void emit(arg1_t a1, arg2_t a2)
  1322. {
  1323. lock_block lock;
  1324. for (size_t i = 0; i < m_connections.Count(); i++) {
  1325. m_connections.At(i)->emit(a1, a2);
  1326. }
  1327. }
  1328. void operator()(arg1_t a1, arg2_t a2)
  1329. {
  1330. emit(a1, a2);
  1331. }
  1332. };
  1333. template<class arg1_t, class arg2_t, class arg3_t>
  1334. class signal3 : public _signal_base3<arg1_t, arg2_t, arg3_t>
  1335. {
  1336. public:
  1337. signal3() { }
  1338. signal3(const signal3<arg1_t, arg2_t, arg3_t>& s)
  1339. : _signal_base3<arg1_t, arg2_t, arg3_t>(s)
  1340. { }
  1341. template<class desttype>
  1342. void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_t, arg2_t, arg3_t))
  1343. {
  1344. typedef _connection3<desttype, arg1_t, arg2_t, arg3_t> conn_t;
  1345. lock_block lock;
  1346. conn_t* conn = new conn_t(pclass, pmemfun);
  1347. m_connections.Append(conn);
  1348. pclass->signal_connect(this);
  1349. }
  1350. void emit(arg1_t a1, arg2_t a2, arg3_t a3)
  1351. {
  1352. lock_block lock;
  1353. for (size_t i = 0; i < m_connections.Count(); i++) {
  1354. m_connections.At(i)->emit(a1, a2, a3);
  1355. }
  1356. }
  1357. void operator()(arg1_t a1, arg2_t a2, arg3_t a3)
  1358. {
  1359. emit(a1, a2, a3);
  1360. }
  1361. };
  1362. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t>
  1363. class signal4 : public _signal_base4<arg1_t, arg2_t, arg3_t,
  1364. arg4_t>
  1365. {
  1366. public:
  1367. signal4() { }
  1368. signal4(const signal4<arg1_t, arg2_t, arg3_t, arg4_t>& s)
  1369. : _signal_base4<arg1_t, arg2_t, arg3_t, arg4_t>(s)
  1370. { }
  1371. template<class desttype>
  1372. void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_t, arg2_t, arg3_t, arg4_t))
  1373. {
  1374. lock_block lock;
  1375. typedef _connection4<desttype, arg1_t, arg2_t, arg3_t, arg4_t> conn_t;
  1376. conn_t* conn = new conn_t(pclass, pmemfun);
  1377. m_connected_slots.push_back(conn);
  1378. pclass->signal_connect(this);
  1379. }
  1380. void emit(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4)
  1381. {
  1382. lock_block lock;
  1383. connections_list::const_iterator itNext, it = m_connected_slots.begin();
  1384. connections_list::const_iterator itEnd = m_connected_slots.end();
  1385. while (it != itEnd)
  1386. {
  1387. itNext = it;
  1388. ++itNext;
  1389. (*it)->emit(a1, a2, a3, a4);
  1390. it = itNext;
  1391. }
  1392. }
  1393. void operator()(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4)
  1394. {
  1395. emit(a1, a2, a3, a4);
  1396. }
  1397. };
  1398. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t,
  1399. class arg5_t>
  1400. class signal5 : public _signal_base5<arg1_t, arg2_t, arg3_t,
  1401. arg4_t, arg5_t>
  1402. {
  1403. public:
  1404. signal5() { }
  1405. signal5(const signal5<arg1_t, arg2_t, arg3_t, arg4_t,
  1406. arg5_t>& s)
  1407. : _signal_base5<arg1_t, arg2_t, arg3_t, arg4_t,
  1408. arg5_t>(s)
  1409. { }
  1410. template<class desttype>
  1411. void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_t,
  1412. arg2_t, arg3_t, arg4_t, arg5_t))
  1413. {
  1414. lock_block lock;
  1415. typedef _connection5<desttype, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t> conn_t;
  1416. conn_t* conn = new conn_t(pclass, pmemfun);
  1417. m_connected_slots.push_back(conn);
  1418. pclass->signal_connect(this);
  1419. }
  1420. void emit(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4,
  1421. arg5_t a5)
  1422. {
  1423. lock_block lock;
  1424. connections_list::const_iterator itNext, it = m_connected_slots.begin();
  1425. connections_list::const_iterator itEnd = m_connected_slots.end();
  1426. while (it != itEnd)
  1427. {
  1428. itNext = it;
  1429. ++itNext;
  1430. (*it)->emit(a1, a2, a3, a4, a5);
  1431. it = itNext;
  1432. }
  1433. }
  1434. void operator()(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4,
  1435. arg5_t a5)
  1436. {
  1437. emit(a1, a2, a3, a4, a5);
  1438. }
  1439. };
  1440. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t,
  1441. class arg5_t, class arg6_t>
  1442. class signal6 : public _signal_base6<arg1_t, arg2_t, arg3_t,
  1443. arg4_t, arg5_t, arg6_t>
  1444. {
  1445. public:
  1446. signal6() { }
  1447. signal6(const signal6<arg1_t, arg2_t, arg3_t, arg4_t,
  1448. arg5_t, arg6_t>& s)
  1449. : _signal_base6<arg1_t, arg2_t, arg3_t, arg4_t,
  1450. arg5_t, arg6_t>(s)
  1451. { }
  1452. template<class desttype>
  1453. void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_t,
  1454. arg2_t, arg3_t, arg4_t, arg5_t, arg6_t))
  1455. {
  1456. lock_block lock;
  1457. typedef _connection6<desttype, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t> conn_t;
  1458. conn_t* conn = new conn_t(pclass, pmemfun);
  1459. m_connected_slots.push_back(conn);
  1460. pclass->signal_connect(this);
  1461. }
  1462. void emit(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4,
  1463. arg5_t a5, arg6_t a6)
  1464. {
  1465. lock_block lock;
  1466. connections_list::const_iterator itNext, it = m_connected_slots.begin();
  1467. connections_list::const_iterator itEnd = m_connected_slots.end();
  1468. while (it != itEnd)
  1469. {
  1470. itNext = it;
  1471. ++itNext;
  1472. (*it)->emit(a1, a2, a3, a4, a5, a6);
  1473. it = itNext;
  1474. }
  1475. }
  1476. void operator()(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4,
  1477. arg5_t a5, arg6_t a6)
  1478. {
  1479. emit(a1, a2, a3, a4, a5, a6);
  1480. }
  1481. };
  1482. template<class arg1_t, class arg2_t, class arg3_t, class arg4_t,
  1483. class arg5_t, class arg6_t, class arg7_t>
  1484. class signal7 : public _signal_base7<arg1_t, arg2_t, arg3_t,
  1485. arg4_t, arg5_t, arg6_t, arg7_t>
  1486. {
  1487. public:
  1488. signal7() { }
  1489. signal7(const signal7<arg1_t, arg2_t, arg3_t, arg4_t,
  1490. arg5_t, arg6_t, arg7_t>& s)
  1491. : _signal_base7<arg1_t, arg2_t, arg3_t, arg4_t,
  1492. arg5_t, arg6_t, arg7_t>(s)
  1493. { }
  1494. template<class desttype>
  1495. void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_t,
  1496. arg2_t, arg3_t, arg4_t, arg5_t, arg6_t,
  1497. arg7_t))
  1498. {
  1499. lock_block lock;
  1500. typedef _connection7<desttype, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t> conn_t;
  1501. conn_t* conn = new conn_t(pclass, pmemfun);
  1502. m_connected_slots.push_back(conn);
  1503. pclass->signal_connect(this);
  1504. }
  1505. void emit(arg1_t a1, arg2_t a2, arg3_t a3, arg4_t a4, arg5_t a5, arg6_t a6, arg7_t a7)
  1506. {
  1507. lock_block lock;
  1508. connections_list::const_iterator itNext, it = m_connected_slots.begin();
  1509. connections_list::const_iterator itEnd = m_co