~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to libaqsistypes/refcount.h

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//------------------------------------------------------------------------------
 
2
/**
 
3
 *      @file   refcount.h
 
4
 *      @author Paul Gregory
 
5
 *      @brief  Declare a reference counting class.
 
6
 *
 
7
 *      Last change by:         $Author: pgregory $
 
8
 *      Last change date:       $Date: 2003/12/28 18:26:18 $
 
9
 */ 
 
10
//------------------------------------------------------------------------------
 
11
 
 
12
#ifndef ___refcount_Loaded___
 
13
#define ___refcount_Loaded___
 
14
 
 
15
#include        "aqsis.h"
 
16
#include        "sstring.h"
 
17
#include        <vector>
 
18
#include        <list>
 
19
 
 
20
/**
 
21
 * These are debug and non-debug versions of the macros ADDREF and RELEASEREF.
 
22
 *
 
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.
 
26
 * 
 
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.
 
31
 */
 
32
#ifdef _DEBUG
 
33
#define ADDREF(x) (x)->AddRef(__FILE__, __LINE__)
 
34
#define RELEASEREF(x) (x)->Release(__FILE__, __LINE__)
 
35
#else
 
36
#define ADDREF(x) (x)->AddRef()
 
37
#define RELEASEREF(x) (x)->Release()
 
38
#endif
 
39
 
 
40
#ifdef _DEBUG
 
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();
 
45
#else
 
46
extern "C" void report_refcounts();
 
47
#endif  // AQSIS_SYSTEM_WIN32
 
48
 
 
49
class RefCountRecord;
 
50
typedef std::vector<RefCountRecord*> RecordVector;
 
51
typedef std::vector<RefCountRecord*>::iterator RecordIterator;
 
52
typedef std::vector<RefCountRecord*>::const_iterator ConstRecordIterator;
 
53
#endif
 
54
 
 
55
/**
 
56
 * \class CqRefCount
 
57
 *
 
58
 * This class provides a reference counting form of memory management for
 
59
 * Aqsis.
 
60
 *
 
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.
 
65
 * 
 
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.
 
73
 */
 
74
class CqRefCount
 
75
{
 
76
 
 
77
#ifdef _DEBUG
 
78
 
 
79
public:
 
80
    /// These methods are the debug versions.
 
81
    CqRefCount();
 
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);
 
87
    void dump() const;
 
88
    /**
 
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
 
92
     * is defined.
 
93
     */
 
94
    virtual Aqsis::CqString className() const {
 
95
        return Aqsis::CqString("unknown");
 
96
    }
 
97
 
 
98
private:
 
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;
 
105
 
 
106
#else ///< #ifdef _DEBUG
 
107
 
 
108
    /// The methods below are inlined for use in a non-debug
 
109
    ///  compile.
 
110
public:
 
111
    /// Constructor
 
112
    CqRefCount() : m_cReferences( 0 )
 
113
    {}
 
114
 
 
115
    /// Copy Constructor, does not copy reference count.
 
116
    CqRefCount( const CqRefCount& From )
 
117
    {}
 
118
    virtual ~CqRefCount()
 
119
    {}
 
120
 
 
121
    TqInt       RefCount() const
 
122
    {
 
123
        return ( m_cReferences );
 
124
    }
 
125
    void        AddRef()
 
126
    {
 
127
        m_cReferences++;
 
128
    }
 
129
    void        Release()
 
130
    {
 
131
        m_cReferences--; if ( m_cReferences <= 0 ) delete( this );
 
132
    }
 
133
 
 
134
#endif ///< #ifdef _DEBUG
 
135
 
 
136
private:
 
137
    TqInt       m_cReferences;          ///< Count of references to this object.
 
138
};
 
139
 
 
140
 
 
141
#endif  //      ___refcount_Loaded___