Panda3D

nodeCachedReferenceCount.I
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file nodeCachedReferenceCount.I
10 * @author drose
11 * @date 2005-05-07
12 */
13
14 /**
15 * The ReferenceCount constructor is protected because you almost never want
16 * to create just a ReferenceCount object by itself, and it's probably a
17 * mistake if you try.
18 *
19 * ReferenceCount doesn't store any useful information in its own right; its
20 * only purpose is to add reference-counting to some other class via
21 * inheritance.
22 */
23 INLINE NodeCachedReferenceCount::
24 NodeCachedReferenceCount() {
25 _node_ref_count = 0;
26 }
27
28 /**
29 * The copies of reference-counted objects do not themselves inherit the
30 * reference count!
31 *
32 * This copy constructor is protected because you almost never want to create
33 * just a ReferenceCount object by itself, and it's probably a mistake if you
34 * try.
35 */
36 INLINE NodeCachedReferenceCount::
37 NodeCachedReferenceCount(const NodeCachedReferenceCount &copy) : CachedTypedWritableReferenceCount(copy) {
38 _node_ref_count = 0;
39 }
40
41 /**
42 * The copies of reference-counted objects do not themselves inherit the
43 * reference count!
44 *
45 * This copy assignment operator is protected because you almost never want to
46 * copy just a ReferenceCount object by itself, and it's probably a mistake if
47 * you try. Instead, this should only be called from a derived class that
48 * implements this operator and then calls up the inheritance chain.
49 */
50 INLINE void NodeCachedReferenceCount::
51 operator = (const NodeCachedReferenceCount &copy) {
52 // If this assertion fails, our own pointer was recently deleted. Possibly
53 // you used a real pointer instead of a PointerTo at some point, and the
54 // object was deleted when the PointerTo went out of scope. Maybe you tried
55 // to create an automatic (local variable) instance of a class that derives
56 // from ReferenceCount. Or maybe your headers are out of sync, and you need
57 // to make clean in direct or some higher tree.
58 nassertv(_node_ref_count != -100);
59
60 CachedTypedWritableReferenceCount::operator = (copy);
61 }
62
63 /**
64 * The ReferenceCount destructor is protected to discourage users from
65 * accidentally trying to delete a ReferenceCount pointer directly. This is
66 * almost always a bad idea, since the destructor is not virtual, and you've
67 * almost certainly got some pointer to something that inherits from
68 * ReferenceCount, not just a plain old ReferenceCount object.
69 */
70 INLINE NodeCachedReferenceCount::
71 ~NodeCachedReferenceCount() {
72 // If this assertion fails, we're trying to delete an object that was just
73 // deleted. Possibly you used a real pointer instead of a PointerTo at some
74 // point, and the object was deleted when the PointerTo went out of scope.
75 // Maybe you tried to create an automatic (local variable) instance of a
76 // class that derives from ReferenceCount. Or maybe your headers are out of
77 // sync, and you need to make clean in direct or some higher tree.
78 nassertv(_node_ref_count != -100);
79
80 // If this assertion fails, the reference counts are all screwed up
81 // altogether. Maybe some errant code stomped all over memory somewhere.
82 nassertv(_node_ref_count >= 0);
83
84 // If this assertion fails, someone tried to delete this object while its
85 // reference count was still positive. Maybe you tried to point a PointerTo
86 // at a static object (a local variable, instead of one allocated via new)?
87 // The test below against 0x7f is supposed to check for that, but it's a
88 // pretty hokey test.
89
90 // Another possibility is you inadvertently omitted a copy constructor for a
91 // ReferenceCount object, and then bitwise copied a dynamically allocated
92 // value--reference count and all--onto a locally allocated one.
93 nassertv(_node_ref_count == 0);
94
95 #ifndef NDEBUG
96 // Ok, all clear to delete. Now set the reference count to -100, so we'll
97 // have a better chance of noticing if we happen to have a stray pointer to
98 // it still out there.
99 _node_ref_count = -100;
100 #endif
101 }
102
103 /**
104 * Returns the current reference count.
105 */
106 INLINE int NodeCachedReferenceCount::
107 get_node_ref_count() const {
108 #ifdef _DEBUG
109 test_ref_count_integrity();
110 #endif
111 return (int)AtomicAdjust::get(_node_ref_count);
112 }
113
114 /**
115 * Explicitly increments the reference count.
116 *
117 * This function is const, even though it changes the object, because
118 * generally fiddling with an object's reference count isn't considered part
119 * of fiddling with the object. An object might be const in other ways, but
120 * we still need to accurately count the number of references to it.
121 */
122 INLINE void NodeCachedReferenceCount::
123 node_ref() const {
124 #ifdef _DEBUG
125 nassertv(test_ref_count_integrity());
126 #endif
127
128 ref();
129 AtomicAdjust::inc(((NodeCachedReferenceCount *)this)->_node_ref_count);
130 }
131
132 /**
133 * Explicitly decrements the node reference count and the normal reference
134 * count simultaneously.
135 *
136 * The return value is true if the new reference count is nonzero, false if it
137 * is zero.
138 */
139 INLINE bool NodeCachedReferenceCount::
140 node_unref() const {
141 node_unref_only();
142 return unref();
143 }
144
145 /**
146 * Does some easy checks to make sure that the reference count isn't
147 * completely bogus.
148 */
149 INLINE bool NodeCachedReferenceCount::
150 test_ref_count_integrity() const {
151 #ifndef NDEBUG
152 return do_test_ref_count_integrity();
153 #else
154 return true;
155 #endif
156 }
157
158 /**
159 * Returns the union of the values defined in the Referenced enum that
160 * represents the various things that appear to be holding a pointer to this
161 * object.
162 *
163 * If R_node is included, at least one node is holding a pointer; if R_cache
164 * is included, at least one cache element is.
165 */
166 INLINE int NodeCachedReferenceCount::
167 get_referenced_bits() const {
168 int result = 0;
169 if (get_node_ref_count() != 0) {
170 result |= R_node;
171 }
172 if (get_cache_ref_count() != 0) {
173 result |= R_cache;
174 }
175
176 return result;
177 }
178
179 /**
180 * Decrements the node reference count without affecting the normal reference
181 * count. Intended to be called by derived classes only, presumably to
182 * reimplement node_unref().
183 */
184 INLINE void NodeCachedReferenceCount::
185 node_unref_only() const {
186 #ifdef _DEBUG
187 nassertv(test_ref_count_integrity());
188 #endif
189
190 // If this assertion fails, you tried to unref an object with a zero
191 // reference count. Are you using ref() and unref() directly? Are you sure
192 // you can't use PointerTo's?
193 nassertv(_node_ref_count > 0);
194
195 AtomicAdjust::dec(((NodeCachedReferenceCount *)this)->_node_ref_count);
196 }
AtomicAdjustDummyImpl::dec
static bool dec(Integer &var)
Atomically decrements the indicated variable and returns true if the new value is nonzero,...
Definition: atomicAdjustDummyImpl.I:27
AtomicAdjustDummyImpl::inc
static void inc(Integer &var)
Atomically increments the indicated variable.
Definition: atomicAdjustDummyImpl.I:18
AtomicAdjustDummyImpl::get
static Integer get(const Integer &var)
Atomically retrieves the snapshot value of the indicated variable.
Definition: atomicAdjustDummyImpl.I:59
CachedTypedWritableReferenceCount
This is a special extension to ReferenceCount that includes dual reference counts: the standard refer...
Definition: cachedTypedWritableReferenceCount.h:34
CachedTypedWritableReferenceCount::get_cache_ref_count
get_cache_ref_count
Returns the current reference count.
Definition: cachedTypedWritableReferenceCount.h:47
NodeCachedReferenceCount
This class further specializes CachedTypedWritableReferenceCount to also add a node_ref_count,...
Definition: nodeCachedReferenceCount.h:49
NodeCachedReferenceCount::node_unref
bool node_unref() const
Explicitly decrements the node reference count and the normal reference count simultaneously.
Definition: nodeCachedReferenceCount.I:140
NodeCachedReferenceCount::node_ref
void node_ref() const
Explicitly increments the reference count.
Definition: nodeCachedReferenceCount.I:123
NodeCachedReferenceCount::test_ref_count_integrity
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
Definition: nodeCachedReferenceCount.I:150
NodeCachedReferenceCount::get_node_ref_count
int get_node_ref_count() const
Returns the current reference count.
Definition: nodeCachedReferenceCount.I:107
NodeCachedReferenceCount::get_referenced_bits
int get_referenced_bits() const
Returns the union of the values defined in the Referenced enum that represents the various things tha...
Definition: nodeCachedReferenceCount.I:167
ReferenceCount::ref
void ref() const
Explicitly increments the reference count.
Definition: referenceCount.I:151
ReferenceCount::unref
virtual bool unref() const
Explicitly decrements the reference count.
Definition: referenceCount.I:179