evtconnection.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: tests/weakref/evtconnection.cpp
  3. // Purpose: wxWeakRef<T> unit test
  4. // Author: Arne Steinarson
  5. // Created: 2008-01-10
  6. // Copyright: (c) 2007 Arne Steinarson
  7. ///////////////////////////////////////////////////////////////////////////////
  8. // ----------------------------------------------------------------------------
  9. // headers
  10. // ----------------------------------------------------------------------------
  11. #include "testprec.h"
  12. #ifdef __BORLANDC__
  13. #pragma hdrstop
  14. #endif
  15. #ifndef WX_PRECOMP
  16. #include "wx/wx.h"
  17. #endif // WX_PRECOMP
  18. #include "wx/event.h"
  19. #include "wx/weakref.h"
  20. static int gs_value = 0; // Increased by 1 by first object and 0x10000 by 2nd object
  21. static wxObject *gs_psrc1;
  22. static wxObject *gs_psrc2;
  23. // We need some event types
  24. const wxEventType wxEVT_TEST = wxNewEventType(),
  25. wxEVT_TEST1 = wxNewEventType(),
  26. wxEVT_TEST2 = wxNewEventType();
  27. class wxTestEvent : public wxEvent
  28. {
  29. public:
  30. wxTestEvent(wxEventType type = wxEVT_TEST) : wxEvent(0, type) { }
  31. virtual wxEvent *Clone() const { return new wxTestEvent(GetEventType()); }
  32. };
  33. class wxTestSink : public wxEvtHandler
  34. {
  35. public:
  36. void OnTestEvent(wxEvent& evt)
  37. {
  38. if ( evt.GetEventObject() == gs_psrc1 )
  39. gs_value += 1;
  40. else if ( evt.GetEventObject() == gs_psrc2 )
  41. gs_value += 0x10000;
  42. }
  43. void OnTestEvent1(wxEvent& )
  44. {
  45. gs_value += 0x00100;
  46. }
  47. void OnTestEvent2(wxEvent&)
  48. {
  49. gs_value += 0x01000000;
  50. }
  51. };
  52. // --------------------------------------------------------------------------
  53. // test class
  54. // --------------------------------------------------------------------------
  55. class EvtConnectionTestCase : public CppUnit::TestCase
  56. {
  57. public:
  58. EvtConnectionTestCase() {}
  59. private:
  60. CPPUNIT_TEST_SUITE( EvtConnectionTestCase );
  61. CPPUNIT_TEST( SinkTest );
  62. CPPUNIT_TEST( SourceDestroyTest );
  63. CPPUNIT_TEST( MultiConnectionTest );
  64. CPPUNIT_TEST_SUITE_END();
  65. void SinkTest();
  66. void SourceDestroyTest();
  67. void MultiConnectionTest();
  68. DECLARE_NO_COPY_CLASS(EvtConnectionTestCase)
  69. };
  70. // register in the unnamed registry so that these tests are run by default
  71. CPPUNIT_TEST_SUITE_REGISTRATION( EvtConnectionTestCase );
  72. // also include in its own registry so that these tests can be run alone
  73. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtConnectionTestCase, "EvtConnectionTestCase" );
  74. // Helpers
  75. void DoConnect( wxEvtHandler& eh1, wxEvtHandler& eh2, wxTestSink& ts ){
  76. eh1.Connect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
  77. NULL, &ts);
  78. eh2.Connect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
  79. NULL, &ts);
  80. }
  81. void DoDisconnect( wxEvtHandler& eh1, wxEvtHandler& eh2, wxTestSink& ts ){
  82. eh1.Disconnect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
  83. NULL, &ts);
  84. eh2.Disconnect(wxEVT_TEST, (wxObjectEventFunction) &wxTestSink::OnTestEvent,
  85. NULL, &ts);
  86. }
  87. void EvtConnectionTestCase::SinkTest()
  88. {
  89. // Let the sink be destroyed before the sources
  90. // An event used below
  91. wxTestEvent evt;
  92. // Connect two event handlers to one sink
  93. wxEvtHandler eh1, eh2;
  94. gs_psrc1 = &eh1;
  95. gs_psrc2 = &eh2;
  96. {
  97. wxTestSink ts;
  98. CPPUNIT_ASSERT( !ts.GetFirst() );
  99. DoConnect(eh1, eh2, ts);
  100. DoDisconnect(eh1, eh2, ts);
  101. DoConnect(eh1, eh2, ts);
  102. // Fire events
  103. evt.SetEventObject(&eh1);
  104. eh1.ProcessEvent(evt);
  105. evt.SetEventObject(&eh2);
  106. eh2.ProcessEvent(evt);
  107. // Make sure they were processed correctly
  108. CPPUNIT_ASSERT_EQUAL( 0x00010001, gs_value );
  109. }
  110. // Fire events again, should be no sink connected now
  111. gs_value = 0;
  112. evt.SetEventObject(&eh1);
  113. eh1.ProcessEvent( evt );
  114. evt.SetEventObject(&eh2);
  115. eh2.ProcessEvent( evt );
  116. // Make sure no processing happened
  117. CPPUNIT_ASSERT_EQUAL( 0, gs_value );
  118. }
  119. void EvtConnectionTestCase::SourceDestroyTest()
  120. {
  121. // Let the sources be destroyed before the sink
  122. wxTestSink ts;
  123. wxTestEvent evt;
  124. {
  125. wxEvtHandler eh1;
  126. {
  127. CPPUNIT_ASSERT( !ts.GetFirst() );
  128. // Connect two event handlers to one sink
  129. wxEvtHandler eh2;
  130. gs_psrc1 = &eh1;
  131. gs_psrc2 = &eh2;
  132. DoConnect( eh1, eh2, ts );
  133. // Fire events
  134. gs_value = 0;
  135. evt.SetEventObject(&eh1);
  136. eh1.ProcessEvent( evt );
  137. evt.SetEventObject(&eh2);
  138. eh2.ProcessEvent( evt );
  139. // Make sure they were processed correctly
  140. CPPUNIT_ASSERT_EQUAL( 0x00010001, gs_value );
  141. }
  142. gs_value = 0;
  143. evt.SetEventObject(&eh1);
  144. eh1.ProcessEvent( evt );
  145. // Make sure still connected
  146. CPPUNIT_ASSERT_EQUAL( 0x00000001, gs_value );
  147. }
  148. CPPUNIT_ASSERT( !ts.GetFirst() );
  149. }
  150. void EvtConnectionTestCase::MultiConnectionTest()
  151. {
  152. // events used below
  153. wxTestEvent evt;
  154. wxTestEvent evt1(wxEVT_TEST1);
  155. wxTestEvent evt2(wxEVT_TEST2);
  156. // One source
  157. wxEvtHandler eh1;
  158. evt.SetEventObject(&eh1);
  159. gs_psrc1 = NULL;
  160. gs_psrc2 = &eh1;
  161. {
  162. // ...and one sink
  163. wxTestSink ts;
  164. eh1.Connect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
  165. NULL, &ts);
  166. eh1.Connect(wxEVT_TEST1, (wxObjectEventFunction)&wxTestSink::OnTestEvent1,
  167. NULL, &ts);
  168. eh1.Connect(wxEVT_TEST2, (wxObjectEventFunction)&wxTestSink::OnTestEvent2,
  169. NULL, &ts);
  170. // Generate events
  171. gs_value = 0;
  172. eh1.ProcessEvent(evt);
  173. eh1.ProcessEvent(evt1);
  174. eh1.ProcessEvent(evt2);
  175. CPPUNIT_ASSERT( gs_value==0x01010100 );
  176. {
  177. // Declare weak references to the objects (using same list)
  178. wxEvtHandlerRef re(&eh1), rs(&ts);
  179. }
  180. // And now destroyed
  181. eh1.Disconnect(wxEVT_TEST, (wxObjectEventFunction)&wxTestSink::OnTestEvent,
  182. NULL, &ts);
  183. eh1.ProcessEvent(evt);
  184. eh1.ProcessEvent(evt1);
  185. eh1.ProcessEvent(evt2);
  186. CPPUNIT_ASSERT_EQUAL( 0x02010200, gs_value );
  187. }
  188. // No connection should be left now
  189. gs_value = 0;
  190. eh1.ProcessEvent(evt);
  191. eh1.ProcessEvent(evt1);
  192. eh1.ProcessEvent(evt2);
  193. // Nothing should have been done
  194. CPPUNIT_ASSERT_EQUAL( 0, gs_value );
  195. }