[vtk-developers] [Paraview-developers] Moving vtkMemberFunctionCommand to VTK
Utkarsh Ayachit
utkarsh.ayachit at kitware.com
Mon Oct 4 12:29:45 EDT 2010
Folks,
Attached is an possible implementation for the same.
Any comments?
Utkarsh
On Mon, Sep 27, 2010 at 9:14 AM, Utkarsh Ayachit
<utkarsh.ayachit at kitware.com> wrote:
> Not a bad idea at all. Internally, we can still do what we do
> currently to avoid making any dramatic changes. But, API-wise will
> make our lives much easier. Let's hope some of the VTK veterans
> comment :).
>
> Utkarsh
>
> On Sun, Sep 26, 2010 at 7:04 PM, David Doria <daviddoria at gmail.com> wrote:
>> On Fri, Sep 24, 2010 at 12:38 PM, Utkarsh Ayachit
>> <utkarsh.ayachit at kitware.com> wrote:
>>>
>>> Couple of suggestions:
>>>
>>> 1> I think we should change the API to be:
>>>
>>> SetCallback(ClassT* ...) rather than SetCallback(ClassT& ..)
>>>
>>> That makes the mode more VTK-like when reading:
>>>
>>> I'd prefer:
>>>
>>> obs->SetCallback(this, &vtkMySelf::CallbackHandler);
>>>
>>> to the current implementation i.e.:
>>>
>>> obs->SetCallback(*this, &vtkMySelf::CallbackHandler);
>>>
>>> 2> We should use vtkWeakPointer for the Object ptr, to avoid dangling
>>> pointers.
>>>
>>> 3> The documentation needs to be fixed. Currently there are errors in
>>> it, the usage described does not really match the real usage :).
>>>
>>> 4> Another possibility is simply moving the code to vtkCommand.h.
>>>
>>> Like David said, let's wait a week to see if people respond, otherwise
>>> I will make those changes and move the header to VTK/Common.
>>>
>>> Utkarsh
>>>
>>
>> Is there a way to skip the adapter all together? That is, rather than:
>> adapter = vtkMemberFunctionCommand<CustomStyle>::New();
>> adapter->SetCallback(*this, &CustomStyle::CatchWidgetEvent);
>> tracer->AddObserver(vtkCommand::EndInteractionEvent, this->Adapter);
>> could we just do something like:
>> tracer->AddClassObserver(vtkCommand::EndInteractionEvent, CatchWidgetEvent);
>> and have it automatically deal with the 'this' pointer and the name of the
>> class?
>> David
>
-------------- next part --------------
commit 22aace7564a8b1b1cf44c99f52be45f96d956078
Author: Utkarsh Ayachit <utkarsh.ayachit at kitware.com>
Date: Mon Oct 4 12:27:01 2010 -0400
Added API to vtkObject to directly add class member as a event callback.
Added new API to vtkObject to add a class' member function as a callback to
call when a event is triggered.
diff --git a/Common/vtkObject.cxx b/Common/vtkObject.cxx
index 34cc181..7617a08 100644
--- a/Common/vtkObject.cxx
+++ b/Common/vtkObject.cxx
@@ -18,6 +18,7 @@
#include "vtkDebugLeaks.h"
#include "vtkGarbageCollector.h"
#include "vtkTimeStamp.h"
+#include "vtkWeakPointer.h"
#include <vtkstd/map>
@@ -673,6 +674,79 @@ void vtkSubjectHelper::PrintSelf(ostream& os, vtkIndent indent)
}
}
+
+//----------------------------------------------------------------------------
+namespace
+{
+ template<class T>
+ class VTK_EXPORT vtkClassMemberCallbackHelper : public vtkCommand
+ {
+ typedef vtkClassMemberCallbackHelper<T> ThisT;
+
+ public:
+ typedef vtkCommand Superclass;
+
+ virtual const char* GetClassNameInternal() const { return "vtkClassMemberCallbackHelper"; }
+
+ static ThisT* SafeDownCast(vtkObjectBase* o)
+ {
+ return dynamic_cast<ThisT*>(o);
+ }
+
+ static ThisT* New()
+ {
+ return new ThisT();
+ }
+
+ // Description:
+ // Set which class instance and member function will be called when a VTK
+ // event is received.
+ void SetCallback(T& object, void (T::*method)())
+ {
+ this->Object = &object;
+ this->Method = method;
+ }
+
+ void SetCallback(T& object,
+ void (T::*method2)(vtkObject*, unsigned long, void*))
+ {
+ this->Object = &object;
+ this->Method2 = method2;
+ }
+
+ virtual void Execute(vtkObject* caller, unsigned long event, void* calldata)
+ {
+ if (this->Object && this->Method)
+ {
+ (this->Object->*this->Method)();
+ }
+ if (this->Object && this->Method2)
+ {
+ (this->Object->*this->Method2)(caller, event, calldata);
+ }
+ }
+ private:
+ vtkClassMemberCallbackHelper()
+ {
+ this->Object = 0;
+ this->Method = 0;
+ this->Method2 = 0;
+ }
+
+ ~vtkClassMemberCallbackHelper()
+ {
+ }
+
+ vtkWeakPointer<T> Object;
+ void (T::*Method)();
+ void (T::*Method2)(
+ vtkObject* caller, unsigned long event, void* calldata);
+
+ vtkClassMemberCallbackHelper(const vtkClassMemberCallbackHelper&); // Not implemented
+ void operator=(const vtkClassMemberCallbackHelper&); // Not implemented
+ };
+}
+
//--------------------------------vtkObject observer-----------------------
unsigned long vtkObject::AddObserver(unsigned long event, vtkCommand *cmd, float p)
{
@@ -684,6 +758,33 @@ unsigned long vtkObject::AddObserver(unsigned long event, vtkCommand *cmd, float
}
//----------------------------------------------------------------------------
+template <class T>
+unsigned long vtkObject::AddObserver(unsigned long event,
+ T* observer, void (T::*callback)(), float priority)
+{
+ vtkClassMemberCallbackHelper<T> helper =
+ vtkClassMemberCallbackHelper<T>::New();
+ helper->SetCallback(*observer, callback);
+ unsigned long id = this->AddObserver(event, helper, priority);
+ helper->Delete();
+ return id;
+}
+
+//----------------------------------------------------------------------------
+template <class T>
+unsigned long vtkObject::AddObserver(unsigned long event,
+ T* observer, void (T::*callback)(vtkObject*, unsigned long, void*),
+ float priority)
+{
+ vtkClassMemberCallbackHelper<T> helper =
+ vtkClassMemberCallbackHelper<T>::New();
+ helper->SetCallback(*observer, callback);
+ unsigned long id = this->AddObserver(event, helper, priority);
+ helper->Delete();
+ return id;
+}
+
+//----------------------------------------------------------------------------
unsigned long vtkObject::AddObserver(const char *event,vtkCommand *cmd, float p)
{
return this->AddObserver(vtkCommand::GetEventIdFromString(event), cmd, p);
diff --git a/Common/vtkObject.h b/Common/vtkObject.h
index 3e15587..bb09192 100644
--- a/Common/vtkObject.h
+++ b/Common/vtkObject.h
@@ -125,6 +125,14 @@ public:
float priority=0.0f);
unsigned long AddObserver(const char *event, vtkCommand *,
float priority=0.0f);
+
+ template <class T>
+ unsigned long AddObserver(unsigned long event,
+ T* observer, void (T::*callback)(), float priority=0.0f);
+ template <class T>
+ unsigned long AddObserver(unsigned long event,
+ T* observer, void (T::*callback)(vtkObject*, unsigned long, void*),
+ float priority=0.0f);
vtkCommand *GetCommand(unsigned long tag);
void RemoveObserver(vtkCommand*);
void RemoveObservers(unsigned long event, vtkCommand *);
More information about the vtk-developers
mailing list