Panda3D
Loading...
Searching...
No Matches
cachedTypedWritableReferenceCount.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 cachedTypedWritableReferenceCount.I
10 * @author drose
11 * @date 2005-01-25
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 CachedTypedWritableReferenceCount::
24CachedTypedWritableReferenceCount() {
25 _cache_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 CachedTypedWritableReferenceCount::
37CachedTypedWritableReferenceCount(const CachedTypedWritableReferenceCount &copy) : TypedWritableReferenceCount(copy) {
38 _cache_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 CachedTypedWritableReferenceCount::
51operator = (const CachedTypedWritableReferenceCount &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(_cache_ref_count != -100);
59
60 TypedWritableReferenceCount::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 CachedTypedWritableReferenceCount::
71~CachedTypedWritableReferenceCount() {
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(_cache_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(_cache_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(_cache_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 _cache_ref_count = -100;
100#endif
101}
102
103/**
104 * Returns the current reference count.
105 */
107get_cache_ref_count() const {
108#ifdef _DEBUG
110#endif
111 return (int)AtomicAdjust::get(_cache_ref_count);
112}
113
114/**
115 * Explicitly increments the cache reference count and the normal reference
116 * count simultaneously.
117 */
119cache_ref() const {
120#ifdef _DEBUG
121 nassertv(test_ref_count_integrity());
122#endif
123
124 ref();
125 AtomicAdjust::inc(_cache_ref_count);
126}
127
128/**
129 * Explicitly decrements the cache reference count and the normal reference
130 * count simultaneously.
131 *
132 * The return value is true if the new reference count is nonzero, false if it
133 * is zero.
134 */
136cache_unref() const {
137#ifdef _DEBUG
138 nassertr(test_ref_count_integrity(), 0);
139#endif
140
141 // If this assertion fails, you tried to unref an object with a zero
142 // reference count. Are you using ref() and unref() directly? Are you sure
143 // you can't use PointerTo's?
144 nassertr(_cache_ref_count > 0, 0);
145
146 AtomicAdjust::dec(_cache_ref_count);
147 return ReferenceCount::unref();
148}
149
150/**
151 * Does some easy checks to make sure that the reference count isn't
152 * completely bogus.
153 */
156#ifndef NDEBUG
157 return do_test_ref_count_integrity();
158#else
159 return true;
160#endif
161}
162
163/**
164 * Decrements the cache reference count without affecting the normal reference
165 * count. Don't use this.
166 */
168cache_ref_only() const {
169#ifdef _DEBUG
170 nassertv(test_ref_count_integrity());
171#endif
172
173 AtomicAdjust::inc(_cache_ref_count);
174}
175
176/**
177 * Decrements the cache reference count without affecting the normal reference
178 * count. Intended to be called by derived classes only, presumably to
179 * reimplement cache_unref().
180 */
181INLINE void CachedTypedWritableReferenceCount::
182cache_unref_only() const {
183#ifdef _DEBUG
184 nassertv(test_ref_count_integrity());
185#endif
186
187 // If this assertion fails, you tried to unref an object with a zero
188 // reference count. Are you using ref() and unref() directly? Are you sure
189 // you can't use PointerTo's?
190 nassertv(_cache_ref_count > 0);
191
192 AtomicAdjust::dec(_cache_ref_count);
193}
194
195/**
196 * This global helper function will unref the given ReferenceCount object, and
197 * if the reference count reaches zero, automatically delete it. It can't be
198 * a member function because it's usually a bad idea to delete an object from
199 * within its own member function. It's a template function so the destructor
200 * doesn't have to be virtual.
201 */
202template<class RefCountType>
203INLINE void
204cache_unref_delete(RefCountType *ptr) {
205 if (!ptr->cache_unref()) {
206 delete ptr;
207 }
208}
void cache_unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...
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...
void cache_ref() const
Explicitly increments the cache reference count and the normal reference count simultaneously.
bool cache_unref() const
Explicitly decrements the cache reference count and the normal reference count simultaneously.
get_cache_ref_count
Returns the current reference count.
void cache_ref_only() const
Decrements the cache reference count without affecting the normal reference count.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
void ref() const
Explicitly increments the reference count.
virtual bool unref() const
Explicitly decrements the reference count.
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.