Panda3D
Loading...
Searching...
No Matches
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 */
23INLINE NodeCachedReferenceCount::
24NodeCachedReferenceCount() {
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 */
36INLINE NodeCachedReferenceCount::
37NodeCachedReferenceCount(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 */
50INLINE void NodeCachedReferenceCount::
51operator = (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 */
70INLINE 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 */
107get_node_ref_count() const {
108#ifdef _DEBUG
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 */
123node_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 */
140node_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 */
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 */
167get_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 */
184INLINE void NodeCachedReferenceCount::
185node_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}
static bool dec(Integer &var)
Atomically decrements the indicated variable and returns true if the new value is nonzero,...
static void inc(Integer &var)
Atomically increments the indicated variable.
static Integer get(const Integer &var)
Atomically retrieves the snapshot value of the indicated variable.
This is a special extension to ReferenceCount that includes dual reference counts: the standard refer...
get_cache_ref_count
Returns the current reference count.
This class further specializes CachedTypedWritableReferenceCount to also add a node_ref_count,...
bool node_unref() const
Explicitly decrements the node reference count and the normal reference count simultaneously.
void node_ref() const
Explicitly increments the reference count.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
int get_node_ref_count() const
Returns the current reference count.
int get_referenced_bits() const
Returns the union of the values defined in the Referenced enum that represents the various things tha...
void ref() const
Explicitly increments the reference count.
virtual bool unref() const
Explicitly decrements the reference count.