summaryrefslogtreecommitdiff
path: root/thirdparty/thekla_atlas/nvcore/RefCounted.h
blob: b8d68edee3ce1c1148af8a96a6104facc85ee589 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// This code is in the public domain -- Ignacio Castaño <castano@gmail.com>

#ifndef NV_CORE_REFCOUNTED_H
#define NV_CORE_REFCOUNTED_H

#include "nvcore.h"
#include "Debug.h"

#define NV_DECLARE_PTR(Class) \
    template <class T> class SmartPtr; \
    typedef SmartPtr<class Class> Class ## Ptr; \
    typedef SmartPtr<const class Class> Class ## ConstPtr


namespace nv
{
    /// Weak proxy.
    class WeakProxy
    {
        NV_FORBID_COPY(WeakProxy);
    public:
	    /// Ctor.
	    WeakProxy(void * ptr) : m_count(0), m_ptr(ptr) { }

        /// Dtor.
        ~WeakProxy()
        {
            nvCheck( m_count == 0 );
        }

        /// Increase reference count.
        uint addRef() const
        {
            m_count++;
            return m_count;
        }

        /// Decrease reference count and remove when 0.
        uint release() const
        {
            nvCheck( m_count > 0 );

            m_count--;
            if( m_count == 0 ) {
                delete this;
                return 0;
            }
            return m_count;
        }

	    /// WeakPtr's call this to determine if their pointer is valid or not.
	    bool isAlive() const {
		    return m_ptr != NULL;
	    }

	    /// Only the actual object should call this.
	    void notifyObjectDied() {
		    m_ptr = NULL;
	    }

        /// Return proxy pointer.
        void * ptr() const {
            return m_ptr;
        }

    private:
        mutable int m_count;
	    void * m_ptr;
    };


    /// Reference counted base class to be used with SmartPtr and WeakPtr.
    class RefCounted
    {
        NV_FORBID_COPY(RefCounted);
    public:

        /// Ctor.
        RefCounted() : m_count(0), m_weak_proxy(NULL)
        {
        }

        /// Virtual dtor.
        virtual ~RefCounted()
        {
            nvCheck( m_count == 0 );
            releaseWeakProxy();
        }


        /// Increase reference count.
        uint addRef() const
        {
            m_count++;
            return m_count;
        }


        /// Decrease reference count and remove when 0.
        uint release() const
        {
            nvCheck( m_count > 0 );

            m_count--;
            if( m_count == 0 ) {
                delete this;
                return 0;
            }
            return m_count;
        }

        /// Get weak proxy.
        WeakProxy * getWeakProxy() const
        {
            if (m_weak_proxy == NULL) {
                m_weak_proxy = new WeakProxy((void *)this);
                m_weak_proxy->addRef();
            }
            return m_weak_proxy;
        }

        /// Release the weak proxy.	
        void releaseWeakProxy() const
        {
            if (m_weak_proxy != NULL) {
                m_weak_proxy->notifyObjectDied();
                m_weak_proxy->release();
                m_weak_proxy = NULL;
            }
        }

        /// Get reference count.
        int refCount() const
        {
            return m_count;
        }


    private:

        mutable int m_count;
        mutable WeakProxy * m_weak_proxy;

    };

} // nv namespace


#endif // NV_CORE_REFCOUNTED_H