Ver código fonte

ctkCallback now accepts callback data

By default, the data passed to the associated function will be a pointer
to the ctkCallback itself. Using property/setProperty it's then
possible to associate data to the callback itself.

It's also possible to set a custom data structure using setCallbackData.

Note that this commit is breaking backward compatibility. Existing code
will have to add an extra "void*" parameter to the function associated to
the callback.
Jean-Christophe Fillion-Robin 14 anos atrás
pai
commit
74e9fd86c0

+ 45 - 9
Libs/Core/Testing/Cpp/ctkCallbackTest1.cpp

@@ -21,6 +21,7 @@
 // Qt includes
 #include <QCoreApplication>
 #include <QTimer>
+#include <QVariant>
 
 // CTK includes
 #include "ctkCallback.h"
@@ -32,15 +33,25 @@
 namespace
 {
 bool Done1;
-void doSomething1()
+ctkCallback * Callback1;
+void doSomething1(void* data)
 {
-  Done1 = true;
+  Done1 = (Callback1 == data);
 }
 
 bool Done2;
-void doSomething2()
+ctkCallback * Callback2;
+void doSomething2(void* data)
 {
-  Done2 = true;
+  ctkCallback * callback = reinterpret_cast<ctkCallback*>(data);
+  Done2 = (Callback2 == data && callback->property("foo").toInt() == 7);
+}
+
+bool Done3;
+void* CallbackData3;
+void doSomething3(void* data)
+{
+  Done3 = (CallbackData3 == data);
 }
 
 } // end of anomymous namespace
@@ -53,8 +64,20 @@ int ctkCallbackTest1(int argc, char * argv [] )
 
   Done1 = false;
   Done2 = false;
+  Done3 = false;
 
+  //-----------------------------------------------------------------------------
+  ctkCallback callback;
+  if (callback.callbackData() != &callback)
+    {
+    std::cerr << "Line " << __LINE__ << " - Problem vith ctkCallback constructor" << std::endl;
+    return EXIT_FAILURE;
+    }
+  QTimer::singleShot(0, &callback, SLOT(invoke()));
+  
+  //-----------------------------------------------------------------------------
   ctkCallback callback1;
+  Callback1 = &callback1;
   if (callback1.callback() != 0)
     {
     std::cerr << "Line " << __LINE__ << " - Problem vith ctkCallback constructor"
@@ -71,19 +94,26 @@ int ctkCallbackTest1(int argc, char * argv [] )
   
   QTimer::singleShot(0, &callback1, SLOT(invoke()));
   
+  //-----------------------------------------------------------------------------
   ctkCallback callback2(doSomething2);
+  callback2.setProperty("foo", QVariant(7));
+  Callback2 = &callback2;
   if (callback2.callback() != doSomething2)
     {
     std::cerr << "Line " << __LINE__ << " - Problem vith ctkCallback constructor" << std::endl;
     return EXIT_FAILURE;
     }
-    
+  
   QTimer::singleShot(0, &callback2, SLOT(invoke()));
+
+  //-----------------------------------------------------------------------------
+  QObject dummyData;
+  CallbackData3 = &dummyData;
+  ctkCallback callback3(doSomething3);
+  callback3.setCallbackData(&dummyData);
+  QTimer::singleShot(0, &callback3, SLOT(invoke()));
   
-  ctkCallback callback3;
   
-  QTimer::singleShot(0, &callback3, SLOT(invoke()));
-
   QTimer::singleShot(0, &app, SLOT(quit()));
 
   int status = app.exec();
@@ -97,11 +127,17 @@ int ctkCallbackTest1(int argc, char * argv [] )
     std::cerr << "Line " << __LINE__ << " - Probem with ctkCallback" << std::endl;
     return EXIT_FAILURE;
     }
-    
+
   if (!Done2)
     {
     std::cerr << "Line " << __LINE__ << " - Probem with ctkCallback::setCallback" << std::endl;
     return EXIT_FAILURE;
     }
+
+  if (!Done3)
+    {
+    std::cerr << "Line " << __LINE__ << " - Probem with ctkCallback::setCallback" << std::endl;
+    return EXIT_FAILURE;
+    }
   return EXIT_SUCCESS;
 }

+ 18 - 4
Libs/Core/ctkCallback.cpp

@@ -27,12 +27,14 @@
 // --------------------------------------------------------------------------
 ctkCallback::ctkCallback(QObject * parentObject) : QObject(parentObject)
 {
+  this->CallbackData = this;
   this->setCallback(0);
 }
 
 // --------------------------------------------------------------------------
-ctkCallback::ctkCallback(void (*newCallback)(), QObject * parentObject) : QObject(parentObject)
+ctkCallback::ctkCallback(void (*newCallback)(void * data), QObject * parentObject) : QObject(parentObject)
 {
+  this->CallbackData = this;
   this->setCallback(newCallback);
 }
 
@@ -42,25 +44,37 @@ ctkCallback::~ctkCallback()
 }
 
 // --------------------------------------------------------------------------
-void (*ctkCallback::callback()const)()
+void (*ctkCallback::callback()const)(void*)
 {
   return this->Callback;
 }
   
 // --------------------------------------------------------------------------
-void ctkCallback::setCallback(void (*newCallback)())
+void ctkCallback::setCallback(void (*newCallback)(void * data))
 {
   this->Callback = newCallback;
 }
 
 // --------------------------------------------------------------------------
+void * ctkCallback::callbackData()const
+{
+  return this->CallbackData;
+}
+
+// --------------------------------------------------------------------------
+void ctkCallback::setCallbackData(void * data)
+{
+  this->CallbackData = data;
+}
+
+// --------------------------------------------------------------------------
 void ctkCallback::invoke()
 {
   if (!this->Callback)
     {
     return;
     }
-  (*this->Callback)();
+  (*this->Callback)(this->CallbackData);
 }
 
 

+ 12 - 4
Libs/Core/ctkCallback.h

@@ -34,20 +34,28 @@ class CTK_CORE_EXPORT ctkCallback : public QObject
 public:
 
   ctkCallback(QObject * parentObject = 0);
-  ctkCallback(void (*callback)(), QObject * parentObject = 0);
+  ctkCallback(void (*callback)(void * data), QObject * parentObject = 0);
   virtual ~ctkCallback();
 
   /// Returns the current pointer function
-  void (*callback()const)();
+  void (*callback()const)(void*);
   /// Sets a pointer function to call when invoke() is called.
-  void setCallback(void (*callback)());
+  void setCallback(void (*callback)(void * data));
+  
+  /// Returns the current callback data.
+  /// \note By default ctkCallback itself will be passed has callback data
+  /// \sa setCallbackData
+  void * callbackData()const;
+  /// Set callback data
+  void setCallbackData(void * data);
   
 public slots:
   /// Internally calls the pointer function \a callback.
   virtual void invoke();
   
 private:
-  void (*Callback)();
+  void (*Callback)(void * data);
+  void * CallbackData;
 };
 
 #endif