|
@@ -22,7 +22,9 @@
|
|
|
#include <QCoreApplication>
|
|
|
#include <QDebug>
|
|
|
#include <QList>
|
|
|
-#include <QTimer>
|
|
|
+
|
|
|
+// CTK includes
|
|
|
+#include <ctkCallback.h>
|
|
|
|
|
|
// CTKVTK includes
|
|
|
#include "ctkVTKConnection.h"
|
|
@@ -43,18 +45,42 @@ namespace
|
|
|
{
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
+int total_event_count;
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void spy(void* data)
|
|
|
+{
|
|
|
+ Q_UNUSED(data);
|
|
|
+ ++total_event_count;
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
void doit(vtkObject* vtkNotUsed(obj), unsigned long vtkNotUsed(event),
|
|
|
void* client_data, void* vtkNotUsed(param))
|
|
|
{
|
|
|
- QTimer* t = reinterpret_cast<QTimer*>(client_data);
|
|
|
- t->stop();
|
|
|
+ ctkCallback* t = reinterpret_cast<ctkCallback*>(client_data);
|
|
|
+ t->invoke();
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void displayDartMeasurement(const char* name, double value)
|
|
|
+{
|
|
|
+ std::cout << "<DartMeasurement name=\""<< name <<"\" "
|
|
|
+ << "type=\"numeric/double\">"
|
|
|
+ << value << "</DartMeasurement>" << std::endl;
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
-double computeConnectionTiming(const QString& connectionDescription,
|
|
|
- int eventCount,
|
|
|
- int objectCount, vtkObject* obj)
|
|
|
+// This function will trigger a ModifiedEvent <eventCount> times
|
|
|
+// where <objectCount> objects listen that same event.
|
|
|
+bool computeConnectionTiming(const char* name,
|
|
|
+ int eventCount,
|
|
|
+ int objectCount, vtkObject* obj,
|
|
|
+ double & elapsedTime)
|
|
|
{
|
|
|
+ elapsedTime = 0;
|
|
|
+ total_event_count = 0;
|
|
|
+
|
|
|
vtkNew<vtkTimerLog> timerLog;
|
|
|
timerLog->StartTimer();
|
|
|
for (int i = 0; i < eventCount; ++i)
|
|
@@ -63,12 +89,31 @@ double computeConnectionTiming(const QString& connectionDescription,
|
|
|
}
|
|
|
timerLog->StopTimer();
|
|
|
|
|
|
- double elapsedTime = timerLog->GetElapsedTime();
|
|
|
- qDebug()
|
|
|
- << qPrintable(connectionDescription.leftJustified(30, ' ')) << ":"
|
|
|
- << "1 event invoked" << eventCount << "times and listened by" << objectCount
|
|
|
- << "objects: " << elapsedTime << "seconds";
|
|
|
- return elapsedTime;
|
|
|
+ int expected_total_event_count = eventCount * objectCount;
|
|
|
+ if (total_event_count != expected_total_event_count)
|
|
|
+ {
|
|
|
+ std::cerr << "Problem with " << name << "\n"
|
|
|
+ << "\tcurrent total_event_count:" << total_event_count << "\n"
|
|
|
+ << "\texpected total_event_count:" << expected_total_event_count
|
|
|
+ << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ elapsedTime = timerLog->GetElapsedTime();
|
|
|
+
|
|
|
+ QString measurementName = QString("time-%1-%2-%3").arg(name).arg(eventCount).arg(objectCount);
|
|
|
+ displayDartMeasurement(qPrintable(measurementName), elapsedTime);
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+bool computeConnectionTiming(const char* name,
|
|
|
+ int eventCount,
|
|
|
+ int objectCount, vtkObject* obj)
|
|
|
+{
|
|
|
+ double elapsedTime = 0;
|
|
|
+ return computeConnectionTiming(name, eventCount, objectCount, obj, elapsedTime);
|
|
|
}
|
|
|
|
|
|
} // end of anonymous namespace
|
|
@@ -78,84 +123,96 @@ int ctkVTKConnectionTest1( int argc, char * argv [] )
|
|
|
{
|
|
|
QCoreApplication app(argc, argv);
|
|
|
|
|
|
+ total_event_count = 0;
|
|
|
int objects = 1000;
|
|
|
int events = 100;
|
|
|
|
|
|
- vtkObject* obj = vtkObject::New();
|
|
|
+ vtkObject* obj1 = vtkObject::New();
|
|
|
vtkObject* obj2 = vtkObject::New();
|
|
|
vtkObject* obj3 = vtkObject::New();
|
|
|
vtkObject* obj4 = vtkObject::New();
|
|
|
vtkObject* obj5 = vtkObject::New();
|
|
|
|
|
|
- int connection1_observeDeletion = 0;
|
|
|
- // NA for connection2
|
|
|
+ // NA for connection1
|
|
|
+ int connection2_observeDeletion = 0;
|
|
|
int connection3_observeDeletion = 1;
|
|
|
int connection4_observeDeletion = 0;
|
|
|
int connection5_observeDeletion = 1;
|
|
|
|
|
|
QObject* topObject = new QObject(0);
|
|
|
- // It could be here any kind of Qt object, QTimer has a no op slot so use it
|
|
|
- QTimer* slotObject = new QTimer(topObject);
|
|
|
+ ctkCallback* slotObject = new ctkCallback(spy, topObject);
|
|
|
|
|
|
for (int i = 0; i < objects; ++i)
|
|
|
{
|
|
|
- // connection1
|
|
|
- ctkVTKConnection* connection1 = new ctkVTKConnection(topObject);
|
|
|
- connection1->observeDeletion(connection1_observeDeletion);
|
|
|
- connection1->setup(obj, vtkCommand::ModifiedEvent,
|
|
|
- slotObject, SLOT(stop()));
|
|
|
-
|
|
|
- // connection2: regular callback
|
|
|
+ // connection1: regular callback
|
|
|
vtkCallbackCommand* callback = vtkCallbackCommand::New();
|
|
|
callback->SetClientData(slotObject);
|
|
|
callback->SetCallback(doit);
|
|
|
-
|
|
|
- obj2->AddObserver(vtkCommand::ModifiedEvent, callback);
|
|
|
+ obj1->AddObserver(vtkCommand::ModifiedEvent, callback);
|
|
|
callback->Delete();
|
|
|
|
|
|
+ // connection2
|
|
|
+ ctkVTKConnection* connection2 = new ctkVTKConnection(topObject);
|
|
|
+ connection2->observeDeletion(connection2_observeDeletion);
|
|
|
+ connection2->setup(obj2, vtkCommand::ModifiedEvent,
|
|
|
+ slotObject, SLOT(invoke()));
|
|
|
+
|
|
|
// connection3
|
|
|
ctkVTKConnection* connection3 = new ctkVTKConnection(topObject);
|
|
|
connection3->observeDeletion(connection3_observeDeletion);
|
|
|
connection3->setup(obj3, vtkCommand::ModifiedEvent,
|
|
|
- slotObject, SLOT(stop()));
|
|
|
+ slotObject, SLOT(invoke()));
|
|
|
|
|
|
// connection4
|
|
|
ctkVTKConnection* connection4 = new ctkVTKConnection(topObject);
|
|
|
connection4->observeDeletion(connection4_observeDeletion);
|
|
|
connection4->setup(obj4, vtkCommand::ModifiedEvent,
|
|
|
- new QTimer(topObject), SLOT(stop()));
|
|
|
+ new ctkCallback(spy, topObject), SLOT(invoke()));
|
|
|
|
|
|
// connection5
|
|
|
ctkVTKConnection* connection5 = new ctkVTKConnection(topObject);
|
|
|
connection5->observeDeletion(connection5_observeDeletion);
|
|
|
connection5->setup(obj5, vtkCommand::ModifiedEvent,
|
|
|
- slotObject, SLOT(stop()));
|
|
|
+ new ctkCallback(spy, topObject), SLOT(invoke()));
|
|
|
}
|
|
|
|
|
|
- // Compute timing for connection1
|
|
|
- QString connection1_description =
|
|
|
- QString("connection1 / %1").arg(connection1_observeDeletion);
|
|
|
- double time_connection1 = computeConnectionTiming(connection1_description, events , objects, obj);
|
|
|
+ // Compute timing for connection1: Callback only
|
|
|
+ double time_connection1 = 0;
|
|
|
+ if (!computeConnectionTiming("connection1", events , objects, obj1, time_connection1))
|
|
|
+ {
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
|
|
|
- // Compute timing for connection2: Callback only
|
|
|
- QString connection2_description =
|
|
|
- QString("connection2 / vtkCallback");
|
|
|
- double time_connection2 = computeConnectionTiming(connection2_description, events , objects, obj2);
|
|
|
+ // Compute timing for connection2
|
|
|
+ // observeDeletion = 0
|
|
|
+ double time_connection2 = 0;
|
|
|
+ if (!computeConnectionTiming("connection2", events , objects, obj2, time_connection2))
|
|
|
+ {
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
|
|
|
// Compute timing for connection3
|
|
|
- QString connection3_description =
|
|
|
- QString("connection3 / %1").arg(connection3_observeDeletion);
|
|
|
- computeConnectionTiming(connection3_description, events , objects, obj3);
|
|
|
+ // observeDeletion = 1
|
|
|
+ if (!computeConnectionTiming("connection3", events , objects, obj3))
|
|
|
+ {
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
|
|
|
- // Compute timing for connection4
|
|
|
- QString connection4_description =
|
|
|
- QString("connection4 / %1 / 1-1").arg(connection4_observeDeletion);
|
|
|
- computeConnectionTiming(connection4_description, events , objects, obj4);
|
|
|
+ // Compute timing for connection4 - 1-1
|
|
|
+ // observeDeletion = 0
|
|
|
+ if (!computeConnectionTiming("connection4", events , objects, obj4))
|
|
|
+ {
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
|
|
|
- double ratio = time_connection1 / time_connection2;
|
|
|
- qDebug().nospace() << "Ratio [ time_connection1 / time_connection2 ]: " << ratio;
|
|
|
+ // Compute timing for connection5 - 1-1
|
|
|
+ // observeDeletion = 1
|
|
|
+ if (!computeConnectionTiming("connection5", events , objects, obj4))
|
|
|
+ {
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
|
|
|
- obj->Delete();
|
|
|
+ obj1->Delete();
|
|
|
obj2->Delete();
|
|
|
obj3->Delete();
|
|
|
|
|
@@ -164,6 +221,10 @@ int ctkVTKConnectionTest1( int argc, char * argv [] )
|
|
|
obj4->Delete();
|
|
|
obj5->Delete();
|
|
|
|
|
|
+ {
|
|
|
+ const char* measurementName = "time_connection2-over-time_connection1";
|
|
|
+ double ratio = time_connection2 / time_connection1;
|
|
|
+ displayDartMeasurement(measurementName, ratio);
|
|
|
#ifdef QT_NO_DEBUG // In Debug mode, the ratio can be over 2 !
|
|
|
// Ideally a ratio ~= 1.
|
|
|
if (ratio > 1.2)
|
|
@@ -171,5 +232,6 @@ int ctkVTKConnectionTest1( int argc, char * argv [] )
|
|
|
return EXIT_FAILURE;
|
|
|
}
|
|
|
#endif
|
|
|
+ }
|
|
|
return EXIT_SUCCESS;
|
|
|
}
|