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  */
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  */
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::
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  */
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 }
This class further specializes CachedTypedWritableReferenceCount to also add a node_ref_count,...
This is a special extension to ReferenceCount that includes dual reference counts: the standard refer...
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
void node_ref() const
Explicitly increments the reference count.
static void inc(Integer &var)
Atomically increments the indicated variable.
static bool dec(Integer &var)
Atomically decrements the indicated variable and returns true if the new value is nonzero,...
static Integer get(const Integer &var)
Atomically retrieves the snapshot value of the indicated variable.
bool node_unref() const
Explicitly decrements the node reference count and the normal reference count simultaneously.
void ref() const
Explicitly increments the reference count.
get_cache_ref_count
Returns the current reference count.
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...
virtual bool unref() const
Explicitly decrements the reference count.