1
//------------------------------------------------------------------------------
5
* @brief Declare a reference counting class.
7
* Last change by: $Author: pgregory $
8
* Last change date: $Date: 2003/12/28 18:26:18 $
10
//------------------------------------------------------------------------------
12
#ifndef ___refcount_Loaded___
13
#define ___refcount_Loaded___
21
* These are debug and non-debug versions of the macros ADDREF and RELEASEREF.
23
* ADDREF increments the reference count of a pointer to a CqRefCount-derived
24
* class, while RELEASEREF decrements the reference count, causing the object
25
* to be freed when the reference count is less than or equal to zero.
27
* The non-debug versions simply call AddRef() and Release() methods on the
28
* object (which is assumed to be a pointer to a CqRefCount-derived class).
29
* The debug versions include the file name and line where the macro was
30
* called, to enable this information to be tracked for debugging purposes.
33
#define ADDREF(x) (x)->AddRef(__FILE__, __LINE__)
34
#define RELEASEREF(x) (x)->Release(__FILE__, __LINE__)
36
#define ADDREF(x) (x)->AddRef()
37
#define RELEASEREF(x) (x)->Release()
41
// report_refcounts() should be called at the end of rendering, at such a
42
// time when all reference-counted objects should have been released.
43
#ifdef AQSIS_SYSTEM_WIN32
44
extern "C" __declspec(dllexport) void report_refcounts();
46
extern "C" void report_refcounts();
47
#endif // AQSIS_SYSTEM_WIN32
50
typedef std::vector<RefCountRecord*> RecordVector;
51
typedef std::vector<RefCountRecord*>::iterator RecordIterator;
52
typedef std::vector<RefCountRecord*>::const_iterator ConstRecordIterator;
58
* This class provides a reference counting form of memory management for
61
* This class is implemented in two different ways. One way is a debug
62
* version, which keeps track of AddRef() and Release() calls so that bugs
63
* can be tracked easily. The second version is a much faster, minimal
64
* implementation that is used for non-debug builds.
66
* The basic idea with this class is that derived classes will have the
67
* AddRef() function called whenever a new object needs access to the
68
* derived class. Calling AddRef() effectively marks the derived class as
69
* "in use", and prevents it from being de-allocated. When the object no
70
* longer needs the derived class, it will call Release(). Finally, when
71
* the last class has called Release(), the reference counter realises
72
* that nobody needs it anymore and automatically deletes itself.
80
/// These methods are the debug versions.
82
CqRefCount( const CqRefCount& From );
83
virtual ~CqRefCount();
84
TqInt RefCount() const;
85
void AddRef(const TqChar* file, TqInt line);
86
void Release(const TqChar* file, TqInt line);
89
* Returns the name of the class. This function can be
90
* overridden in sub-classes to provide better debugging
91
* information. Remember to only include it if _DEBUG
94
virtual Aqsis::CqString className() const {
95
return Aqsis::CqString("unknown");
99
/// Record of reference counting events for this
100
/// particular instance of CqRefCount.
101
RecordVector m_records;
102
/// Flag that, when true, indicates that the instance had
103
/// ADDREF called at least once.
104
TqBool m_addRefCalled;
106
#else ///< #ifdef _DEBUG
108
/// The methods below are inlined for use in a non-debug
112
CqRefCount() : m_cReferences( 0 )
115
/// Copy Constructor, does not copy reference count.
116
CqRefCount( const CqRefCount& From )
118
virtual ~CqRefCount()
121
TqInt RefCount() const
123
return ( m_cReferences );
131
m_cReferences--; if ( m_cReferences <= 0 ) delete( this );
134
#endif ///< #ifdef _DEBUG
137
TqInt m_cReferences; ///< Count of references to this object.
141
#endif // ___refcount_Loaded___