ctkVTKConnectionTest1.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0.txt
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QCoreApplication>
  16. #include <QDebug>
  17. #include <QList>
  18. // CTK includes
  19. #include <ctkCallback.h>
  20. // CTKVTK includes
  21. #include "ctkVTKConnection.h"
  22. // VTK includes
  23. #include <vtkCallbackCommand.h>
  24. #include <vtkCommand.h>
  25. #include <vtkNew.h>
  26. #include <vtkObject.h>
  27. #include <vtkSmartPointer.h>
  28. #include <vtkTimerLog.h>
  29. // STD includes
  30. #include <cstdlib>
  31. #include <iostream>
  32. namespace
  33. {
  34. //-----------------------------------------------------------------------------
  35. int total_event_count;
  36. //-----------------------------------------------------------------------------
  37. void spy(void* data)
  38. {
  39. Q_UNUSED(data);
  40. ++total_event_count;
  41. }
  42. //-----------------------------------------------------------------------------
  43. void doit(vtkObject* vtkNotUsed(obj), unsigned long vtkNotUsed(event),
  44. void* client_data, void* vtkNotUsed(param))
  45. {
  46. ctkCallback* t = reinterpret_cast<ctkCallback*>(client_data);
  47. t->invoke();
  48. }
  49. //-----------------------------------------------------------------------------
  50. void displayDartMeasurement(const char* name, double value)
  51. {
  52. std::cout << "<DartMeasurement name=\""<< name <<"\" "
  53. << "type=\"numeric/double\">"
  54. << value << "</DartMeasurement>" << std::endl;
  55. }
  56. //-----------------------------------------------------------------------------
  57. // This function will trigger a ModifiedEvent <eventCount> times
  58. // where <objectCount> objects listen that same event.
  59. bool computeConnectionTiming(const char* name,
  60. int eventCount,
  61. int objectCount, vtkObject* obj,
  62. double & elapsedTime)
  63. {
  64. elapsedTime = 0;
  65. total_event_count = 0;
  66. vtkNew<vtkTimerLog> timerLog;
  67. timerLog->StartTimer();
  68. for (int i = 0; i < eventCount; ++i)
  69. {
  70. obj->Modified();
  71. }
  72. timerLog->StopTimer();
  73. int expected_total_event_count = eventCount * objectCount;
  74. if (total_event_count != expected_total_event_count)
  75. {
  76. std::cerr << "Problem with " << name << "\n"
  77. << "\tcurrent total_event_count:" << total_event_count << "\n"
  78. << "\texpected total_event_count:" << expected_total_event_count
  79. << std::endl;
  80. return false;
  81. }
  82. elapsedTime = timerLog->GetElapsedTime();
  83. QString measurementName = QString("time-%1-%2-%3").arg(name).arg(eventCount).arg(objectCount);
  84. displayDartMeasurement(qPrintable(measurementName), elapsedTime);
  85. return true;
  86. }
  87. //-----------------------------------------------------------------------------
  88. bool computeConnectionTiming(const char* name,
  89. int eventCount,
  90. int objectCount, vtkObject* obj)
  91. {
  92. double elapsedTime = 0;
  93. return computeConnectionTiming(name, eventCount, objectCount, obj, elapsedTime);
  94. }
  95. } // end of anonymous namespace
  96. //-----------------------------------------------------------------------------
  97. int ctkVTKConnectionTest1( int argc, char * argv [] )
  98. {
  99. QCoreApplication app(argc, argv);
  100. total_event_count = 0;
  101. int objects = 1000;
  102. int events = 100;
  103. vtkObject* obj1 = vtkObject::New();
  104. vtkObject* obj2 = vtkObject::New();
  105. vtkObject* obj3 = vtkObject::New();
  106. vtkObject* obj4 = vtkObject::New();
  107. vtkObject* obj5 = vtkObject::New();
  108. // NA for connection1
  109. int connection2_observeDeletion = 0;
  110. int connection3_observeDeletion = 1;
  111. int connection4_observeDeletion = 0;
  112. int connection5_observeDeletion = 1;
  113. QObject* topObject = new QObject(0);
  114. ctkCallback* slotObject = new ctkCallback(spy, topObject);
  115. for (int i = 0; i < objects; ++i)
  116. {
  117. // connection1: regular callback
  118. vtkCallbackCommand* callback = vtkCallbackCommand::New();
  119. callback->SetClientData(slotObject);
  120. callback->SetCallback(doit);
  121. obj1->AddObserver(vtkCommand::ModifiedEvent, callback);
  122. callback->Delete();
  123. // connection2
  124. ctkVTKConnection* connection2 = new ctkVTKConnection(topObject);
  125. connection2->observeDeletion(connection2_observeDeletion);
  126. connection2->setup(obj2, vtkCommand::ModifiedEvent,
  127. slotObject, SLOT(invoke()));
  128. // connection3
  129. ctkVTKConnection* connection3 = new ctkVTKConnection(topObject);
  130. connection3->observeDeletion(connection3_observeDeletion);
  131. connection3->setup(obj3, vtkCommand::ModifiedEvent,
  132. slotObject, SLOT(invoke()));
  133. // connection4
  134. ctkVTKConnection* connection4 = new ctkVTKConnection(topObject);
  135. connection4->observeDeletion(connection4_observeDeletion);
  136. connection4->setup(obj4, vtkCommand::ModifiedEvent,
  137. new ctkCallback(spy, topObject), SLOT(invoke()));
  138. // connection5
  139. ctkVTKConnection* connection5 = new ctkVTKConnection(topObject);
  140. connection5->observeDeletion(connection5_observeDeletion);
  141. connection5->setup(obj5, vtkCommand::ModifiedEvent,
  142. new ctkCallback(spy, topObject), SLOT(invoke()));
  143. }
  144. // Compute timing for connection1: Callback only
  145. double time_connection1 = 0;
  146. if (!computeConnectionTiming("connection1", events , objects, obj1, time_connection1))
  147. {
  148. return EXIT_FAILURE;
  149. }
  150. // Compute timing for connection2
  151. // observeDeletion = 0
  152. double time_connection2 = 0;
  153. if (!computeConnectionTiming("connection2", events , objects, obj2, time_connection2))
  154. {
  155. return EXIT_FAILURE;
  156. }
  157. // Compute timing for connection3
  158. // observeDeletion = 1
  159. if (!computeConnectionTiming("connection3", events , objects, obj3))
  160. {
  161. return EXIT_FAILURE;
  162. }
  163. // Compute timing for connection4 - 1-1
  164. // observeDeletion = 0
  165. if (!computeConnectionTiming("connection4", events , objects, obj4))
  166. {
  167. return EXIT_FAILURE;
  168. }
  169. // Compute timing for connection5 - 1-1
  170. // observeDeletion = 1
  171. if (!computeConnectionTiming("connection5", events , objects, obj4))
  172. {
  173. return EXIT_FAILURE;
  174. }
  175. obj1->Delete();
  176. obj2->Delete();
  177. obj3->Delete();
  178. delete topObject;
  179. obj4->Delete();
  180. obj5->Delete();
  181. {
  182. const char* measurementName = "time_connection2-over-time_connection1";
  183. double ratio = time_connection2 / time_connection1;
  184. displayDartMeasurement(measurementName, ratio);
  185. #ifdef QT_NO_DEBUG // In Debug mode, the ratio can be over 2 !
  186. // Ideally a ratio ~= 1.
  187. if (ratio > 1.2)
  188. {
  189. return EXIT_FAILURE;
  190. }
  191. #endif
  192. }
  193. return EXIT_SUCCESS;
  194. }