/*========================================================================= Program: Visualization Toolkit Module: vtkObjectBase.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 vtkObjectBase * @brief abstract base class for most VTK objects * * vtkObjectBase is the base class for all reference counted classes * in the VTK. These classes include vtkCommand classes, vtkInformationKey * classes, and vtkObject classes. * * vtkObjectBase 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. * * Constructor and destructor of the subclasses of vtkObjectBase * should be protected, so that only New() and UnRegister() actually * call them. Debug leaks can be used to see if there are any objects * left with nonzero reference count. * * @warning * Note: Objects of subclasses of vtkObjectBase should always be * created with the New() method and deleted with the Delete() * method. They cannot be allocated off the stack (i.e., automatic * objects) because the constructor is a protected method. * * @sa * vtkObject vtkCommand vtkInformationKey */ #ifndef vtkObjectBase_h #define vtkObjectBase_h // Semantics around vtkDebugLeaks usage has changed. Now just call // vtkObjectBase::InitializeObjectBase() after creating an object with New(). // The object factory methods take care of this automatically. #define VTK_HAS_INITIALIZE_OBJECT_BASE #include "vtkCommonCoreModule.h" // For export macro #include "vtkFeatures.h" // for VTK_USE_MEMKIND #include "vtkIndent.h" #include "vtkSystemIncludes.h" #include "vtkType.h" #include // For std::atomic #include class vtkGarbageCollector; class vtkGarbageCollectorToObjectBaseFriendship; class vtkWeakPointerBase; class vtkWeakPointerBaseToObjectBaseFriendship; // typedefs for malloc and free compatible replacement functions typedef void* (*vtkMallocingFunction)(size_t); typedef void* (*vtkReallocingFunction)(void*, size_t); typedef void (*vtkFreeingFunction)(void*); class VTKCOMMONCORE_EXPORT vtkObjectBase { /** * Return the class name as a string. This method is overridden * in all subclasses of vtkObjectBase with the vtkTypeMacro found * in vtkSetGet.h. */ virtual const char* GetClassNameInternal() const { return "vtkObjectBase"; } public: #ifdef VTK_WORKAROUND_WINDOWS_MANGLE // Avoid windows name mangling. #define GetClassNameA GetClassName #define GetClassNameW GetClassName #endif /** * Return the class name as a string. */ const char* GetClassName() const; /** * The object description printed in messages and PrintSelf * output. To be used only for reporting purposes. */ virtual std::string GetObjectDescription() const; #ifdef VTK_WORKAROUND_WINDOWS_MANGLE #undef GetClassNameW #undef GetClassNameA // Define possible mangled names. const char* GetClassNameA() const; const char* GetClassNameW() const; #endif /** * Return 1 if this class type is the same type of (or a subclass of) * the named class. Returns 0 otherwise. This method works in * combination with vtkTypeMacro found in vtkSetGet.h. */ static vtkTypeBool IsTypeOf(const char* name); /** * Return 1 if this class is the same type of (or a subclass of) * the named class. Returns 0 otherwise. This method works in * combination with vtkTypeMacro found in vtkSetGet.h. */ virtual vtkTypeBool IsA(const char* name); /** * Given a the name of a base class of this class type, return the distance * of inheritance between this class type and the named class (how many * generations of inheritance are there between this class and the named * class). If the named class is not in this class's inheritance tree, return * a negative value. Valid responses will always be nonnegative. This method * works in combination with vtkTypeMacro found in vtkSetGet.h. */ static vtkIdType GetNumberOfGenerationsFromBaseType(const char* name); /** * Given the name of a base class of this class type, return the distance * of inheritance between this class type and the named class (how many * generations of inheritance are there between this class and the named * class). If the named class is not in this class's inheritance tree, return * a negative value. Valid responses will always be nonnegative. This method * works in combination with vtkTypeMacro found in vtkSetGet.h. */ virtual vtkIdType GetNumberOfGenerationsFromBase(const char* name); /** * Delete a VTK object. This method should always be used to delete * an object when the New() method was used to create it. Using the * C++ delete method will not work with reference counting. */ virtual void Delete(); /** * Delete a reference to this object. This version will not invoke * garbage collection and can potentially leak the object if it is * part of a reference loop. Use this method only when it is known * that the object has another reference and would not be collected * if a full garbage collection check were done. */ virtual void FastDelete(); /** * Create an object with Debug turned off, modified time initialized * to zero, and reference counting on. */ static vtkObjectBase* New() { vtkObjectBase* o = new vtkObjectBase; o->InitializeObjectBase(); return o; } // Called by implementations of vtkObject::New(). Centralized location for // vtkDebugLeaks registration. void InitializeObjectBase(); #if defined(_WIN32) || defined(VTK_USE_MEMKIND) // Take control of allocation to avoid dll boundary problems or to use memkind. void* operator new(size_t tSize); void operator delete(void* p); #endif /** * Print an object to an ostream. This is the method to call * when you wish to see print the internal state of an object. */ void Print(ostream& os); ///@{ /** * 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. */ virtual void PrintSelf(ostream& os, vtkIndent indent); virtual void PrintHeader(ostream& os, vtkIndent indent); virtual void PrintTrailer(ostream& os, vtkIndent indent); ///@} /** * Increase the reference count (mark as used by another object). */ // XXX(virtual): VTK_DEPRECATED_IN_9_2_0("Override `UsesGarbageCollector()` instead") virtual void Register(vtkObjectBase* o); /** * Decrease the reference count (release by another object). This * has the same effect as invoking Delete() (i.e., it reduces the * reference count by 1). */ // XXX(virtual): VTK_DEPRECATED_IN_9_2_0("Override `UsesGarbageCollector()` instead") virtual void UnRegister(vtkObjectBase* o); /// @{ /** * Indicate whether the class uses `vtkGarbageCollector` or not. * * Most classes will not need to do this, but if the class participates in a * strongly-connected reference count cycle, participation can resolve these * cycles. * * If overriding this method to return true, the `ReportReferences` method * should be overridden to report references that may be in cycles. */ virtual bool UsesGarbageCollector() const { return false; } /// @} /** * Return the current reference count of this object. */ int GetReferenceCount() { return this->ReferenceCount; } /** * Sets the reference count. (This is very dangerous, use with care.) */ void SetReferenceCount(int); /** * The name of a directory, ideally mounted -o dax, to memory map an * extended memory space within. * This must be called before any objects are constructed in the extended space. * It can not be changed once setup. */ static void SetMemkindDirectory(const char* directoryname); ///@{ /** * A global state flag that controls whether vtkObjects are * constructed in the usual way (the default) or within the extended * memory space. */ static bool GetUsingMemkind(); ///@} /** * A class to help modify and restore the global UsingMemkind state, like * SetUsingMemkind(newValue), but safer. Declare it on the stack in a function where you want to * make a temporary change. When the function returns it will restore the original value. */ class VTKCOMMONCORE_EXPORT vtkMemkindRAII { #ifdef VTK_USE_MEMKIND bool OriginalValue; #endif public: vtkMemkindRAII(bool newValue); ~vtkMemkindRAII(); vtkMemkindRAII(vtkMemkindRAII const&) = default; private: void Save(bool newValue); void Restore(); }; /** * A local state flag that remembers whether this object lives in * the normal or extended memory space. */ bool GetIsInMemkind() const; protected: vtkObjectBase(); virtual ~vtkObjectBase(); std::atomic ReferenceCount; vtkWeakPointerBase** WeakPointers; // Internal Register/UnRegister implementation that accounts for // possible garbage collection participation. The second argument // indicates whether to participate in garbage collection. virtual void RegisterInternal(vtkObjectBase*, vtkTypeBool check); virtual void UnRegisterInternal(vtkObjectBase*, vtkTypeBool check); // See vtkGarbageCollector.h: virtual void ReportReferences(vtkGarbageCollector*); // Call this to call from either malloc or memkind_malloc depending on current UsingMemkind static vtkMallocingFunction GetCurrentMallocFunction(); // Call this to call from either realloc or memkind_realloc depending on current UsingMemkind static vtkReallocingFunction GetCurrentReallocFunction(); // Call this to call from either free or memkind_free depending on instance's IsInMemkind static vtkFreeingFunction GetCurrentFreeFunction(); // Call this to unconditionally call memkind_free static vtkFreeingFunction GetAlternateFreeFunction(); virtual void ObjectFinalize(); private: friend VTKCOMMONCORE_EXPORT ostream& operator<<(ostream& os, vtkObjectBase& o); friend class vtkGarbageCollectorToObjectBaseFriendship; friend class vtkWeakPointerBaseToObjectBaseFriendship; friend class vtkMemkindRAII; friend class vtkTDSCMemkindRAII; static void SetUsingMemkind(bool); bool IsInMemkind; void SetIsInMemkind(bool); ///@{ /** * Some classes need to clear the reference counts manually due to the way * they work. */ friend class vtkInformationKey; friend class vtkGarbageCollector; void ClearReferenceCounts(); ///@} friend class vtkDebugLeaks; virtual const char* GetDebugClassName() const; protected: vtkObjectBase(const vtkObjectBase&) {} void operator=(const vtkObjectBase&) {} }; #endif // VTK-HeaderTest-Exclude: vtkObjectBase.h