/*========================================================================= Program: Visualization Toolkit Module: vtkObject.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkObject * @brief abstract base class for most VTK objects * * vtkObject is the base class for most objects in the visualization * toolkit. vtkObject provides methods for tracking modification time, * debugging, printing, and event callbacks. Most objects created * within the VTK framework should be a subclass of vtkObject or one * of its children. The few exceptions tend to be very small helper * classes that usually never get instantiated or situations where * multiple inheritance gets in the way. vtkObject also performs * reference counting: objects that are reference counted exist as * long as another object uses them. Once the last reference to a * reference counted object is removed, the object will spontaneously * destruct. * * @warning * Note: in VTK objects should always be created with the New() method * and deleted with the Delete() method. VTK objects cannot be * allocated off the stack (i.e., automatic objects) because the * constructor is a protected method. * * @sa * vtkCommand vtkTimeStamp */ #ifndef vtkObject_h #define vtkObject_h #include "vtkCommonCoreModule.h" // For export macro #include "vtkObjectBase.h" #include "vtkSetGet.h" #include "vtkTimeStamp.h" #include "vtkWeakPointerBase.h" // needed for vtkWeakPointer class vtkSubjectHelper; class vtkCommand; class VTKCOMMONCORE_EXPORT vtkObject : public vtkObjectBase { public: vtkBaseTypeMacro(vtkObject, vtkObjectBase); /** * Create an object with Debug turned off, modified time initialized * to zero, and reference counting on. */ static vtkObject* New(); #ifdef _WIN32 // avoid dll boundary problems void* operator new(size_t tSize); void operator delete(void* p); #endif /** * Turn debugging output on. */ virtual void DebugOn(); /** * Turn debugging output off. */ virtual void DebugOff(); /** * Get the value of the debug flag. */ bool GetDebug(); /** * Set the value of the debug flag. A true value turns debugging on. */ void SetDebug(bool debugFlag); /** * This method is called when vtkErrorMacro executes. It allows * the debugger to break on error. */ static void BreakOnError(); /** * Update the modification time for this object. Many filters rely on * the modification time to determine if they need to recompute their * data. The modification time is a unique monotonically increasing * unsigned long integer. */ virtual void Modified(); /** * Return this object's modified time. */ virtual vtkMTimeType GetMTime(); /** * Methods invoked by print to print information about the object * including superclasses. Typically not called by the user (use * Print() instead) but used in the hierarchical print process to * combine the output of several classes. */ void PrintSelf(ostream& os, vtkIndent indent) override; //@{ /** * This is a global flag that controls whether any debug, warning * or error messages are displayed. */ static void SetGlobalWarningDisplay(int val); static void GlobalWarningDisplayOn() { vtkObject::SetGlobalWarningDisplay(1); } static void GlobalWarningDisplayOff() { vtkObject::SetGlobalWarningDisplay(0); } static int GetGlobalWarningDisplay(); //@} //@{ /** * Allow people to add/remove/invoke observers (callbacks) to any VTK * object. This is an implementation of the subject/observer design * pattern. An observer is added by specifying an event to respond to * and a vtkCommand to execute. It returns an unsigned long tag which * can be used later to remove the event or retrieve the command. * When events are invoked, the observers are called in the order they * were added. If a priority value is specified, then the higher * priority commands are called first. A command may set an abort * flag to stop processing of the event. (See vtkCommand.h for more * information.) */ unsigned long AddObserver(unsigned long event, vtkCommand*, float priority = 0.0f); unsigned long AddObserver(const char* event, vtkCommand*, float priority = 0.0f); vtkCommand* GetCommand(unsigned long tag); void RemoveObserver(vtkCommand*); void RemoveObservers(unsigned long event, vtkCommand*); void RemoveObservers(const char* event, vtkCommand*); vtkTypeBool HasObserver(unsigned long event, vtkCommand*); vtkTypeBool HasObserver(const char* event, vtkCommand*); //@} void RemoveObserver(unsigned long tag); void RemoveObservers(unsigned long event); void RemoveObservers(const char* event); void RemoveAllObservers(); // remove every last one of them vtkTypeBool HasObserver(unsigned long event); vtkTypeBool HasObserver(const char* event); //@{ /** * Overloads to AddObserver that allow developers to add class member * functions as callbacks for events. The callback function can * be one of these two types: * \code * void foo(void);\n * void foo(vtkObject*, unsigned long, void*); * \endcode * If the callback is a member of a vtkObjectBase-derived object, * then the callback will automatically be disabled if the object * destructs (but the observer will not automatically be removed). * If the callback is a member of any other type of object, then * the observer must be removed before the object destructs or else * its dead pointer will be used the next time the event occurs. * Typical usage of these functions is as follows: * \code * SomeClassOfMine* observer = SomeClassOfMine::New();\n * to_observe->AddObserver(event, observer, \&SomeClassOfMine::SomeMethod); * \endcode * Note that this does not affect the reference count of a * vtkObjectBase-derived \c observer, which can be safely deleted * with the observer still in place. For non-vtkObjectBase observers, * the observer should never be deleted before it is removed. * Return value is a tag that can be used to remove the observer. */ template unsigned long AddObserver( unsigned long event, U observer, void (T::*callback)(), float priority = 0.0f) { vtkClassMemberCallback* callable = new vtkClassMemberCallback(observer, callback); // callable is deleted when the observer is cleaned up (look at // vtkObjectCommandInternal) return this->AddTemplatedObserver(event, callable, priority); } template unsigned long AddObserver(unsigned long event, U observer, void (T::*callback)(vtkObject*, unsigned long, void*), float priority = 0.0f) { vtkClassMemberCallback* callable = new vtkClassMemberCallback(observer, callback); // callable is deleted when the observer is cleaned up (look at // vtkObjectCommandInternal) return this->AddTemplatedObserver(event, callable, priority); } //@} //@{ /** * Allow user to set the AbortFlagOn() with the return value of the callback * method. */ template unsigned long AddObserver(unsigned long event, U observer, bool (T::*callback)(vtkObject*, unsigned long, void*), float priority = 0.0f) { vtkClassMemberCallback* callable = new vtkClassMemberCallback(observer, callback); // callable is deleted when the observer is cleaned up (look at // vtkObjectCommandInternal) return this->AddTemplatedObserver(event, callable, priority); } //@} //@{ /** * This method invokes an event and return whether the event was * aborted or not. If the event was aborted, the return value is 1, * otherwise it is 0. */ int InvokeEvent(unsigned long event, void* callData); int InvokeEvent(const char* event, void* callData); //@} int InvokeEvent(unsigned long event) { return this->InvokeEvent(event, nullptr); } int InvokeEvent(const char* event) { return this->InvokeEvent(event, nullptr); } protected: vtkObject(); ~vtkObject() override; // See vtkObjectBase.h. void RegisterInternal(vtkObjectBase*, vtkTypeBool check) override; void UnRegisterInternal(vtkObjectBase*, vtkTypeBool check) override; bool Debug; // Enable debug messages vtkTimeStamp MTime; // Keep track of modification time vtkSubjectHelper* SubjectHelper; // List of observers on this object //@{ /** * These methods allow a command to exclusively grab all events. (This * method is typically used by widgets to grab events once an event * sequence begins.) These methods are provided in support of the * public methods found in the class vtkInteractorObserver. Note that * these methods are designed to support vtkInteractorObservers since * they use two separate vtkCommands to watch for mouse and keypress events. */ void InternalGrabFocus(vtkCommand* mouseEvents, vtkCommand* keypressEvents = nullptr); void InternalReleaseFocus(); //@} private: vtkObject(const vtkObject&) = delete; void operator=(const vtkObject&) = delete; /** * Following classes (vtkClassMemberCallbackBase, * vtkClassMemberCallback, and vtkClassMemberHanderPointer) * along with vtkObjectCommandInternal are for supporting * templated AddObserver() overloads that allow developers * to add event callbacks that are class member functions. */ class vtkClassMemberCallbackBase { public: //@{ /** * Called when the event is invoked */ virtual bool operator()(vtkObject*, unsigned long, void*) = 0; virtual ~vtkClassMemberCallbackBase() {} //@} }; //@{ /** * This is a weak pointer for vtkObjectBase and a regular * void pointer for everything else */ template class vtkClassMemberHandlerPointer { public: void operator=(vtkObjectBase* o) { // The cast is needed in case "o" has multi-inheritance, // to offset the pointer to get the vtkObjectBase. if ((this->VoidPointer = dynamic_cast(o)) == nullptr) { // fallback to just using its vtkObjectBase as-is. this->VoidPointer = o; } this->WeakPointer = o; this->UseWeakPointer = true; } void operator=(void* o) { this->VoidPointer = o; this->WeakPointer = nullptr; this->UseWeakPointer = false; } T* GetPointer() { if (this->UseWeakPointer && !this->WeakPointer.GetPointer()) { return nullptr; } return static_cast(this->VoidPointer); } private: vtkWeakPointerBase WeakPointer; void* VoidPointer; bool UseWeakPointer; }; //@} //@{ /** * Templated member callback. */ template class vtkClassMemberCallback : public vtkClassMemberCallbackBase { vtkClassMemberHandlerPointer Handler; void (T::*Method1)(); void (T::*Method2)(vtkObject*, unsigned long, void*); bool (T::*Method3)(vtkObject*, unsigned long, void*); public: vtkClassMemberCallback(T* handler, void (T::*method)()) { this->Handler = handler; this->Method1 = method; this->Method2 = nullptr; this->Method3 = nullptr; } vtkClassMemberCallback(T* handler, void (T::*method)(vtkObject*, unsigned long, void*)) { this->Handler = handler; this->Method1 = nullptr; this->Method2 = method; this->Method3 = nullptr; } vtkClassMemberCallback(T* handler, bool (T::*method)(vtkObject*, unsigned long, void*)) { this->Handler = handler; this->Method1 = nullptr; this->Method2 = nullptr; this->Method3 = method; } ~vtkClassMemberCallback() override {} // Called when the event is invoked bool operator()(vtkObject* caller, unsigned long event, void* calldata) override { T* handler = this->Handler.GetPointer(); if (handler) { if (this->Method1) { (handler->*this->Method1)(); } else if (this->Method2) { (handler->*this->Method2)(caller, event, calldata); } else if (this->Method3) { return (handler->*this->Method3)(caller, event, calldata); } } return false; } }; //@} //@{ /** * Called by templated variants of AddObserver. */ unsigned long AddTemplatedObserver( unsigned long event, vtkClassMemberCallbackBase* callable, float priority); // Friend to access AddTemplatedObserver(). friend class vtkObjectCommandInternal; //@} }; #endif // VTK-HeaderTest-Exclude: vtkObject.h