00001 /*========================================================================= 00002 00003 Program: Medical Imaging & Interaction Toolkit 00004 Language: C++ 00005 Date: $Date$ 00006 Version: $Revision$ 00007 00008 Copyright (c) German Cancer Research Center, Division of Medical and 00009 Biological Informatics. All rights reserved. 00010 See MITKCopyright.txt or https://www.mitk.org/copyright.html for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 00018 #include "itkCommand.h" 00019 00020 namespace mitk 00021 { 00022 00023 //##Documentation 00024 //## @brief Keeps track of the reference count of an object even if 00025 //## it is destroyed. 00026 //## 00027 //## Example usage: 00028 //## \code 00029 //## SomeFilter* filter = GetSomeFilter(); 00030 //## ReferenceCountWatcher::Pointer filterWatcher; 00031 //## filterWatcher = new ReferenceCountWatcher(filter, "name of filter"); 00032 //## filterWatcher->GetReferenceCount(); 00033 //## \endcode 00034 //## @ingroup Testing 00035 class ReferenceCountWatcher : public itk::Object 00036 { 00037 public: 00038 typedef itk::SimpleMemberCommand<ReferenceCountWatcher> CommandType; 00039 00040 mitkClassMacro(ReferenceCountWatcher, itk::Object); 00041 00042 protected: 00043 //##Documentation 00044 //## @brief Object to be watched 00045 itk::Object* m_Object; 00046 00047 //##Documentation 00048 //## @brief Optional comment, e.g. for debugging output 00049 std::string m_Comment; 00050 00051 //##Documentation 00052 //## @brief If \a true, \a m_Object is no longer valid 00053 //## and the returned reference count will be 0. 00054 bool m_Deleted; 00055 00056 //##Documentation 00057 //## @brief itk::Command to get a notification when the object 00058 //## is deleted. 00059 CommandType::Pointer m_DeleteCommand; 00060 00061 public: 00062 //##Documentation 00063 //## @brief Constructor requiring object to be watched and allowing 00064 //## an optional comment. 00065 ReferenceCountWatcher(itk::Object* o, const char *comment="") : m_Object(o), m_Comment(comment), m_Deleted(false), m_ObserverTag(0) 00066 { 00067 m_DeleteCommand = CommandType::New(); 00068 m_DeleteCommand->SetCallbackFunction(this, &ReferenceCountWatcher::DeleteObserver); 00069 if(m_Object!=NULL) 00070 m_ObserverTag = m_Object->AddObserver(itk::DeleteEvent(), m_DeleteCommand); 00071 m_ReferenceCountLock.Lock(); 00072 m_ReferenceCount = 0; 00073 m_ReferenceCountLock.Unlock(); 00074 } 00075 //##Documentation 00076 //## @brief Destructor: remove observer 00077 ~ReferenceCountWatcher() 00078 { 00079 if((m_Deleted == false) && (m_Object != NULL)) 00080 { 00081 m_Object->RemoveObserver(m_ObserverTag); 00082 } 00083 } 00084 //##Documentation 00085 //## @brief Return the reference count of the watched object or 00086 //## 0 if it has been destroyed 00087 int GetReferenceCount() const 00088 { 00089 if(m_Object == NULL) return -1; 00090 if(m_Deleted) return 0; 00091 return m_Object->GetReferenceCount(); 00092 } 00093 00094 //##Documentation 00095 //## @brief Return the optional string comment 00096 itkGetStringMacro(Comment); 00097 protected: 00098 //##Documentation 00099 //## @brief Callback called on itk::DeleteEvent() of wathched object. 00100 void DeleteObserver() 00101 { 00102 m_Deleted = true; 00103 } 00104 unsigned long m_ObserverTag; 00105 }; 00106 00107 }