1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkObjectBase.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15
16 #include "vtkObjectBase.h"
17 #include "vtkDebugLeaks.h"
18 #include "vtkGarbageCollector.h"
19 #include "vtkWeakPointerBase.h"
20
21 #include <sstream>
22
23 #define vtkBaseDebugMacro(x)
24
25 class vtkObjectBaseToGarbageCollectorFriendship
26 {
27 public:
GiveReference(vtkObjectBase * obj)28 static int GiveReference(vtkObjectBase* obj)
29 {
30 return vtkGarbageCollector::GiveReference(obj);
31 }
TakeReference(vtkObjectBase * obj)32 static int TakeReference(vtkObjectBase* obj)
33 {
34 return vtkGarbageCollector::TakeReference(obj);
35 }
36 };
37
38 class vtkObjectBaseToWeakPointerBaseFriendship
39 {
40 public:
ClearPointer(vtkWeakPointerBase * p)41 static void ClearPointer(vtkWeakPointerBase *p)
42 {
43 p->Object = nullptr;
44 }
45 };
46
47 // avoid dll boundary problems
48 #ifdef _WIN32
operator new(size_t nSize)49 void* vtkObjectBase::operator new(size_t nSize)
50 {
51 void* p=malloc(nSize);
52 return p;
53 }
54
operator delete(void * p)55 void vtkObjectBase::operator delete( void *p )
56 {
57 free(p);
58 }
59 #endif
60
61 // ------------------------------------vtkObjectBase----------------------
62 // This operator allows all subclasses of vtkObjectBase to be printed via <<.
63 // It in turn invokes the Print method, which in turn will invoke the
64 // PrintSelf method that all objects should define, if they have anything
65 // interesting to print out.
operator <<(ostream & os,vtkObjectBase & o)66 ostream& operator<<(ostream& os, vtkObjectBase& o)
67 {
68 o.Print(os);
69 return os;
70 }
71
72 // Create an object with Debug turned off and modified time initialized
73 // to zero.
vtkObjectBase()74 vtkObjectBase::vtkObjectBase()
75 {
76 this->ReferenceCount = 1;
77 this->WeakPointers = nullptr;
78 #ifdef VTK_DEBUG_LEAKS
79 vtkDebugLeaks::ConstructingObject(this);
80 #endif
81 }
82
~vtkObjectBase()83 vtkObjectBase::~vtkObjectBase()
84 {
85 #ifdef VTK_DEBUG_LEAKS
86 vtkDebugLeaks::DestructingObject(this);
87 #endif
88
89 // warn user if reference counting is on and the object is being referenced
90 // by another object
91 if ( this->ReferenceCount > 0)
92 {
93 vtkGenericWarningMacro(<< "Trying to delete object with non-zero reference count.");
94 }
95 }
96
97 //----------------------------------------------------------------------------
InitializeObjectBase()98 void vtkObjectBase::InitializeObjectBase()
99 {
100 #ifdef VTK_DEBUG_LEAKS
101 vtkDebugLeaks::ConstructClass(this->GetClassName());
102 #endif // VTK_DEBUG_LEAKS
103 }
104
105 //----------------------------------------------------------------------------
106 #ifdef VTK_WORKAROUND_WINDOWS_MANGLE
107 # undef GetClassName
108 // Define possible mangled names.
GetClassNameA() const109 const char* vtkObjectBase::GetClassNameA() const
110 {
111 return this->GetClassNameInternal();
112 }
GetClassNameW() const113 const char* vtkObjectBase::GetClassNameW() const
114 {
115 return this->GetClassNameInternal();
116 }
117 #endif
GetClassName() const118 const char* vtkObjectBase::GetClassName() const
119 {
120 return this->GetClassNameInternal();
121 }
122
IsTypeOf(const char * name)123 vtkTypeBool vtkObjectBase::IsTypeOf(const char *name)
124 {
125 if ( !strcmp("vtkObjectBase",name) )
126 {
127 return 1;
128 }
129 return 0;
130 }
131
IsA(const char * type)132 vtkTypeBool vtkObjectBase::IsA(const char *type)
133 {
134 return this->vtkObjectBase::IsTypeOf(type);
135 }
136
137 // Delete a vtk object. This method should always be used to delete an object
138 // when the new operator was used to create it. Using the C++ delete method
139 // will not work with reference counting.
Delete()140 void vtkObjectBase::Delete()
141 {
142 this->UnRegister(static_cast<vtkObjectBase *>(nullptr));
143 }
144
FastDelete()145 void vtkObjectBase::FastDelete()
146 {
147 // Remove the reference without doing a collection check even if
148 // this object normally participates in garbage collection.
149 this->UnRegisterInternal(nullptr, 0);
150 }
151
Print(ostream & os)152 void vtkObjectBase::Print(ostream& os)
153 {
154 vtkIndent indent;
155
156 this->PrintHeader(os,vtkIndent(0));
157 this->PrintSelf(os, indent.GetNextIndent());
158 this->PrintTrailer(os,vtkIndent(0));
159 }
160
PrintHeader(ostream & os,vtkIndent indent)161 void vtkObjectBase::PrintHeader(ostream& os, vtkIndent indent)
162 {
163 os << indent << this->GetClassName() << " (" << this << ")\n";
164 }
165
166 // Chaining method to print an object's instance variables, as well as
167 // its superclasses.
PrintSelf(ostream & os,vtkIndent indent)168 void vtkObjectBase::PrintSelf(ostream& os, vtkIndent indent)
169 {
170 os << indent << "Reference Count: " << this->ReferenceCount << "\n";
171 }
172
PrintTrailer(ostream & os,vtkIndent indent)173 void vtkObjectBase::PrintTrailer(ostream& os, vtkIndent indent)
174 {
175 os << indent << "\n";
176 }
177
178 // Description:
179 // Sets the reference count (use with care)
SetReferenceCount(int ref)180 void vtkObjectBase::SetReferenceCount(int ref)
181 {
182 this->ReferenceCount = ref;
183 vtkBaseDebugMacro(<< "Reference Count set to " << this->ReferenceCount);
184 }
185
186 //----------------------------------------------------------------------------
Register(vtkObjectBase * o)187 void vtkObjectBase::Register(vtkObjectBase* o)
188 {
189 // Do not participate in garbage collection by default.
190 this->RegisterInternal(o, 0);
191 }
192
193 //----------------------------------------------------------------------------
UnRegister(vtkObjectBase * o)194 void vtkObjectBase::UnRegister(vtkObjectBase* o)
195 {
196 // Do not participate in garbage collection by default.
197 this->UnRegisterInternal(o, 0);
198 }
199
200 //----------------------------------------------------------------------------
RegisterInternal(vtkObjectBase *,vtkTypeBool check)201 void vtkObjectBase::RegisterInternal(vtkObjectBase*, vtkTypeBool check)
202 {
203 // If a reference is available from the garbage collector, use it.
204 // Otherwise create a new reference by incrementing the reference
205 // count.
206 if(!(check &&
207 vtkObjectBaseToGarbageCollectorFriendship::TakeReference(this)))
208 {
209 this->ReferenceCount++;
210 }
211 }
212
213 //----------------------------------------------------------------------------
UnRegisterInternal(vtkObjectBase *,vtkTypeBool check)214 void vtkObjectBase::UnRegisterInternal(vtkObjectBase*, vtkTypeBool check)
215 {
216 // If the garbage collector accepts a reference, do not decrement
217 // the count.
218 if(check && this->ReferenceCount > 1 &&
219 vtkObjectBaseToGarbageCollectorFriendship::GiveReference(this))
220 {
221 return;
222 }
223
224 // Decrement the reference count, delete object if count goes to zero.
225 if(--this->ReferenceCount <= 0)
226 {
227 // Clear all weak pointers to the object before deleting it.
228 if (this->WeakPointers)
229 {
230 vtkWeakPointerBase **p = this->WeakPointers;
231 while (*p)
232 {
233 vtkObjectBaseToWeakPointerBaseFriendship::ClearPointer(*p++);
234 }
235 delete [] this->WeakPointers;
236 }
237 #ifdef VTK_DEBUG_LEAKS
238 vtkDebugLeaks::DestructClass(this->GetClassName());
239 #endif
240 delete this;
241 }
242 else if(check)
243 {
244 // The garbage collector did not accept the reference, but the
245 // object still exists and is participating in garbage collection.
246 // This means either that delayed garbage collection is disabled
247 // or the collector has decided it is time to do a check.
248 vtkGarbageCollector::Collect(this);
249 }
250 }
251
252 //----------------------------------------------------------------------------
ReportReferences(vtkGarbageCollector *)253 void vtkObjectBase::ReportReferences(vtkGarbageCollector*)
254 {
255 // vtkObjectBase has no references to report.
256 }
257