Panda3D
pointerToBase.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 pointerToBase.I
10  * @author drose
11  * @date 2004-09-27
12  */
13 
14 /**
15  *
16  */
17 template<class T>
18 INLINE PointerToBase<T>::
19 PointerToBase(To *ptr) {
20  _void_ptr = (void *)ptr;
21  if (ptr != nullptr) {
22  ptr->ref();
23 #ifdef DO_MEMORY_USAGE
24  update_type(ptr);
25 #endif
26  }
27 }
28 
29 /**
30  *
31  */
32 template<class T>
33 INLINE PointerToBase<T>::
34 PointerToBase(const PointerToBase<T> &copy) {
35  _void_ptr = copy._void_ptr;
36  if (_void_ptr != nullptr) {
37  To *ptr = (To *)_void_ptr;
38  ptr->ref();
39  }
40 }
41 
42 /**
43  *
44  */
45 template<class T>
46 INLINE PointerToBase<T>::
47 PointerToBase(PointerToBase<T> &&from) noexcept {
48  _void_ptr = from._void_ptr;
49  from._void_ptr = nullptr;
50 }
51 
52 /**
53  *
54  */
55 template<class T>
56 template<class Y>
57 INLINE PointerToBase<T>::
58 PointerToBase(PointerToBase<Y> &&r) noexcept {
59  // If this next line gives an error, you are trying to convert a PointerTo
60  // from an incompatible type of another PointerTo.
61  To *ptr = (Y *)r._void_ptr;
62 
63  this->_void_ptr = ptr;
64  r._void_ptr = nullptr;
65 }
66 
67 /**
68  *
69  */
70 template<class T>
71 INLINE PointerToBase<T>::
73  if (_void_ptr != nullptr) {
74  unref_delete((To *)_void_ptr);
75  _void_ptr = nullptr;
76  }
77 }
78 
79 /**
80  * This version of reassign is called when a PointerTo is assigned to this
81  * PointerTo as an rvalue. In this case, we can steal the reference count
82  * from the other PointerTo, without needing to call ref() and unref()
83  * unnecessarily.
84  */
85 template<class T>
86 INLINE void PointerToBase<T>::
87 reassign(PointerToBase<T> &&from) noexcept {
88  // Protect against self-move-assignment.
89  if (from._void_ptr != this->_void_ptr) {
90  To *old_ptr = (To *)this->_void_ptr;
91 
92  this->_void_ptr = from._void_ptr;
93  from._void_ptr = nullptr;
94 
95  // Now delete the old pointer.
96  if (old_ptr != nullptr) {
97  unref_delete(old_ptr);
98  }
99  }
100 }
101 
102 /**
103  * Like above, but casts from a compatible pointer type.
104  */
105 template<class T>
106 template<class Y>
107 INLINE void PointerToBase<T>::
108 reassign(PointerToBase<Y> &&from) noexcept {
109  // Protect against self-move-assignment.
110  if (from._void_ptr != this->_void_ptr) {
111  To *old_ptr = (To *)this->_void_ptr;
112 
113  // If there is a compile error on this line, it means you tried to assign
114  // an incompatible type.
115  To *new_ptr = (Y *)from._void_ptr;
116 
117  this->_void_ptr = new_ptr;
118  from._void_ptr = nullptr;
119 
120  // Now delete the old pointer.
121  if (old_ptr != nullptr) {
122  unref_delete(old_ptr);
123  }
124  }
125 }
126 
127 /**
128  * This is the main work of the PointerTo family. When the pointer is
129  * reassigned, decrement the old reference count and increment the new one.
130  */
131 template<class T>
132 INLINE void PointerToBase<T>::
133 reassign(To *ptr) {
134  if (ptr != (To *)_void_ptr) {
135  // First save the old pointer; we won't delete it until we have assigned
136  // the new one. We do this just in case there are cascading effects from
137  // deleting this pointer that might inadvertently delete the new one.
138  // (Don't laugh--it's happened!)
139  To *old_ptr = (To *)_void_ptr;
140 
141  _void_ptr = (void *)ptr;
142  if (ptr != nullptr) {
143  ptr->ref();
144 #ifdef DO_MEMORY_USAGE
145  update_type(ptr);
146 #endif
147  }
148 
149  // Now delete the old pointer.
150  if (old_ptr != nullptr) {
151  unref_delete(old_ptr);
152  }
153  }
154 }
155 
156 /**
157  *
158  */
159 template<class T>
160 INLINE void PointerToBase<T>::
161 reassign(const PointerToBase<To> &copy) {
162  if (copy._void_ptr != _void_ptr) {
163  // First save the old pointer; we won't delete it until we have assigned
164  // the new one. We do this just in case there are cascading effects from
165  // deleting this pointer that might inadvertently delete the new one.
166  // (Don't laugh--it's happened!)
167  To *old_ptr = (To *)_void_ptr;
168  To *new_ptr = (To *)copy._void_ptr;
169 
170  _void_ptr = copy._void_ptr;
171  if (new_ptr != nullptr) {
172  new_ptr->ref();
173  }
174 
175  // Now delete the old pointer.
176  if (old_ptr != nullptr) {
177  unref_delete(old_ptr);
178  }
179  }
180 }
181 
182 /**
183  * Ensures that the MemoryUsage record for the pointer has the right type of
184  * object, if we know the type ourselves.
185  */
186 template<class T>
187 INLINE void PointerToBase<T>::
188 update_type(To *ptr) {
189 #ifdef DO_MEMORY_USAGE
191  TypeHandle type = get_type_handle(To);
192  if (type == TypeHandle::none()) {
193  do_init_type(To);
194  type = get_type_handle(To);
195  }
196  if (type != TypeHandle::none()) {
197  MemoryUsage::update_type(ptr, type);
198  }
199  }
200 #endif // DO_MEMORY_USAGE
201 }
202 
203 /**
204  * A convenient way to set the PointerTo object to NULL. (Assignment to a NULL
205  * pointer also works, of course.)
206  */
207 template<class T>
208 ALWAYS_INLINE void PointerToBase<T>::
209 clear() {
210  reassign(nullptr);
211 }
212 
213 /**
214  * A handy function to output PointerTo's as a hex pointer followed by a
215  * reference count.
216  */
217 template<class T>
218 INLINE void PointerToBase<T>::
219 output(std::ostream &out) const {
220  out << _void_ptr;
221  if (_void_ptr != nullptr) {
222  out << ":" << ((To *)_void_ptr)->get_ref_count();
223  }
224 }
void clear()
A convenient way to set the PointerTo object to NULL.
This is the base class for PointerTo and ConstPointerTo.
Definition: pointerToBase.h:29
void output(std::ostream &out) const
A handy function to output PointerTo's as a hex pointer followed by a reference count.
static void update_type(ReferenceCount *ptr, TypeHandle type)
Associates the indicated type with the given pointer.
Definition: memoryUsage.I:55
A file that contains a set of files.
Definition: multifile.h:37
static bool get_track_memory_usage()
Returns true if the user has Configured the variable 'track-memory-usage' to true,...
Definition: memoryUsage.I:20
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
void unref_delete(RefCountType *ptr)
This global helper function will unref the given ReferenceCount object, and if the reference count re...