1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: TestGarbageCollector.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 "vtkCallbackCommand.h"
17 #include "vtkDebugLeaks.h"
18 #include "vtkGarbageCollector.h"
19 #include "vtkObject.h"
20 #include "vtkSmartPointer.h"
21
22 // A class that simulates a reference loop and participates in garbage
23 // collection.
24 class vtkTestReferenceLoop: public vtkObject
25 {
26 public:
New()27 static vtkTestReferenceLoop* New() { return new vtkTestReferenceLoop; }
28 vtkTypeMacro(vtkTestReferenceLoop, vtkObject);
29
Register(vtkObjectBase * o)30 void Register(vtkObjectBase* o) { this->RegisterInternal(o, 1); }
UnRegister(vtkObjectBase * o)31 void UnRegister(vtkObjectBase* o) { this->UnRegisterInternal(o, 1); }
32
33 protected:
vtkTestReferenceLoop()34 vtkTestReferenceLoop()
35 {
36 this->Other = new vtkTestReferenceLoop(this);
37 #ifdef VTK_DEBUG_LEAKS
38 vtkDebugLeaks::ConstructClass("vtkTestReferenceLoop");
39 #endif
40 }
vtkTestReferenceLoop(vtkTestReferenceLoop * other)41 vtkTestReferenceLoop(vtkTestReferenceLoop* other)
42 {
43 this->Other = other;
44 this->Other->Register(this);
45 #ifdef VTK_DEBUG_LEAKS
46 vtkDebugLeaks::ConstructClass("vtkTestReferenceLoop");
47 #endif
48 }
~vtkTestReferenceLoop()49 ~vtkTestReferenceLoop()
50 {
51 if(this->Other)
52 {
53 this->Other->UnRegister(this);
54 this->Other = 0;
55 }
56 }
57
ReportReferences(vtkGarbageCollector * collector)58 void ReportReferences(vtkGarbageCollector* collector)
59 {
60 vtkGarbageCollectorReport(collector, this->Other, "Other");
61 }
62
63 vtkTestReferenceLoop* Other;
64
65 private:
66 vtkTestReferenceLoop(const vtkTestReferenceLoop&); // Not implemented.
67 void operator=(const vtkTestReferenceLoop&); // Not implemented.
68 };
69
70 // A callback that reports when it is called.
71 static int called = 0;
MyDeleteCallback(vtkObject *,unsigned long,void *,void *)72 static void MyDeleteCallback(vtkObject*, unsigned long, void*, void*)
73 {
74 called = 1;
75 }
76
77 // Main test function.
TestGarbageCollector(int,char * [])78 int TestGarbageCollector(int,char *[])
79 {
80 // Create a callback that reports when it is called.
81 vtkSmartPointer<vtkCallbackCommand> cc =
82 vtkSmartPointer<vtkCallbackCommand>::New();
83 cc->SetCallback(MyDeleteCallback);
84
85 // Create an object and delete it immediately. It should be
86 // immediately collected.
87 vtkTestReferenceLoop* obj = vtkTestReferenceLoop::New();
88 obj->AddObserver(vtkCommand::DeleteEvent, cc);
89 called = 0;
90 obj->Delete();
91 if(!called)
92 {
93 cerr << "Object not immediately collected." << endl;
94 return 1;
95 }
96
97 // Create an object, enable deferred collection, and delete it. It
98 // should not be collected yet.
99 obj = vtkTestReferenceLoop::New();
100 obj->AddObserver(vtkCommand::DeleteEvent, cc);
101 vtkGarbageCollector::DeferredCollectionPush();
102 called = 0;
103 obj->Delete();
104 if(called)
105 {
106 cerr << "Object collection not deferred." << endl;
107 return 1;
108 }
109
110 // Disable deferred collection. The object should be deleted now.
111 vtkGarbageCollector::DeferredCollectionPop();
112 if(!called)
113 {
114 cerr << "Deferred collection did not collect object." << endl;
115 return 1;
116 }
117
118 return 0;
119 }
120