Panda3D
|
00001 // Filename: copyOnWritePointer.I 00002 // Created by: drose (09Apr07) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: CopyOnWritePointer::Constructor 00018 // Access: Public 00019 // Description: 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE CopyOnWritePointer:: 00022 CopyOnWritePointer(CopyOnWriteObject *object) : 00023 _object(object) 00024 { 00025 if (_object != (CopyOnWriteObject *)NULL) { 00026 _object->cache_ref(); 00027 } 00028 } 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: CopyOnWritePointer::Copy Constructor 00032 // Access: Public 00033 // Description: 00034 //////////////////////////////////////////////////////////////////// 00035 INLINE CopyOnWritePointer:: 00036 CopyOnWritePointer(const CopyOnWritePointer ©) : 00037 _object(copy._object) 00038 { 00039 if (_object != (CopyOnWriteObject *)NULL) { 00040 _object->cache_ref(); 00041 } 00042 } 00043 00044 //////////////////////////////////////////////////////////////////// 00045 // Function: CopyOnWritePointer::Copy Assignment Operator 00046 // Access: Public 00047 // Description: 00048 //////////////////////////////////////////////////////////////////// 00049 INLINE void CopyOnWritePointer:: 00050 operator = (const CopyOnWritePointer ©) { 00051 operator = (copy._object); 00052 } 00053 00054 //////////////////////////////////////////////////////////////////// 00055 // Function: CopyOnWritePointer::Assignment Operator 00056 // Access: Public 00057 // Description: 00058 //////////////////////////////////////////////////////////////////// 00059 INLINE void CopyOnWritePointer:: 00060 operator = (CopyOnWriteObject *object) { 00061 if (_object != object) { 00062 if (_object != (CopyOnWriteObject *)NULL) { 00063 cache_unref_delete(_object); 00064 } 00065 _object = object; 00066 if (_object != (CopyOnWriteObject *)NULL) { 00067 _object->cache_ref(); 00068 } 00069 } 00070 } 00071 00072 //////////////////////////////////////////////////////////////////// 00073 // Function: CopyOnWritePointer::Destructor 00074 // Access: Public 00075 // Description: 00076 //////////////////////////////////////////////////////////////////// 00077 INLINE CopyOnWritePointer:: 00078 ~CopyOnWritePointer() { 00079 if (_object != (CopyOnWriteObject *)NULL) { 00080 cache_unref_delete(_object); 00081 } 00082 } 00083 00084 //////////////////////////////////////////////////////////////////// 00085 // Function: CopyOnWritePointer::operator == 00086 // Access: Public 00087 // Description: 00088 //////////////////////////////////////////////////////////////////// 00089 INLINE bool CopyOnWritePointer:: 00090 operator == (const CopyOnWritePointer &other) const { 00091 return _object == other._object; 00092 } 00093 00094 //////////////////////////////////////////////////////////////////// 00095 // Function: CopyOnWritePointer::operator != 00096 // Access: Public 00097 // Description: 00098 //////////////////////////////////////////////////////////////////// 00099 INLINE bool CopyOnWritePointer:: 00100 operator != (const CopyOnWritePointer &other) const { 00101 return _object != other._object; 00102 } 00103 00104 //////////////////////////////////////////////////////////////////// 00105 // Function: CopyOnWritePointer::operator < 00106 // Access: Public 00107 // Description: 00108 //////////////////////////////////////////////////////////////////// 00109 INLINE bool CopyOnWritePointer:: 00110 operator < (const CopyOnWritePointer &other) const { 00111 return _object < other._object; 00112 } 00113 00114 #ifndef COW_THREADED 00115 //////////////////////////////////////////////////////////////////// 00116 // Function: CopyOnWritePointer::get_read_pointer 00117 // Access: Public 00118 // Description: Returns a pointer locked for read. Until this 00119 // pointer dereferences, calls to get_write_pointer() 00120 // will force a copy. 00121 // 00122 // This flavor of the method is written for the 00123 // non-threaded case. 00124 //////////////////////////////////////////////////////////////////// 00125 INLINE const CopyOnWriteObject *CopyOnWritePointer:: 00126 get_read_pointer() const { 00127 return _object; 00128 } 00129 #endif // COW_THREADED 00130 00131 #ifndef COW_THREADED 00132 //////////////////////////////////////////////////////////////////// 00133 // Function: CopyOnWritePointer::get_write_pointer 00134 // Access: Public 00135 // Description: Returns a pointer locked for write. If another 00136 // thread or threads already hold the pointer locked for 00137 // read, then this will force a copy. 00138 // 00139 // Until this pointer dereferences, calls to 00140 // get_read_pointer() or get_write_pointer() will block. 00141 // 00142 // This flavor of the method is written for the 00143 // non-threaded case. 00144 //////////////////////////////////////////////////////////////////// 00145 INLINE CopyOnWriteObject *CopyOnWritePointer:: 00146 get_write_pointer() { 00147 if (_object == (CopyOnWriteObject *)NULL) { 00148 return NULL; 00149 } 00150 if (_object->get_cache_ref_count() > 1) { 00151 PT(CopyOnWriteObject) new_object = _object->make_cow_copy(); 00152 cache_unref_delete(_object); 00153 _object = new_object; 00154 _object->cache_ref(); 00155 } 00156 return _object; 00157 } 00158 #endif // COW_THREADED 00159 00160 //////////////////////////////////////////////////////////////////// 00161 // Function: CopyOnWritePointer::get_unsafe_pointer 00162 // Access: Public 00163 // Description: Returns an unlocked pointer that you can write to. 00164 // This should only be used in very narrow circumstances 00165 // in which you know that no other thread may be 00166 // accessing the pointer at the same time. 00167 //////////////////////////////////////////////////////////////////// 00168 INLINE CopyOnWriteObject *CopyOnWritePointer:: 00169 get_unsafe_pointer() { 00170 return _object; 00171 } 00172 00173 //////////////////////////////////////////////////////////////////// 00174 // Function: CopyOnWritePointer::is_null 00175 // Access: Public 00176 // Description: Returns true if the CopyOnWritePointer contains a 00177 // NULL pointer, false otherwise. 00178 //////////////////////////////////////////////////////////////////// 00179 bool CopyOnWritePointer:: 00180 is_null() const { 00181 return (_object == (CopyOnWriteObject *)NULL); 00182 } 00183 00184 //////////////////////////////////////////////////////////////////// 00185 // Function: CopyOnWritePointer::clear 00186 // Access: Public 00187 // Description: Sets the pointer to NULL. 00188 //////////////////////////////////////////////////////////////////// 00189 void CopyOnWritePointer:: 00190 clear() { 00191 if (_object != (CopyOnWriteObject *)NULL) { 00192 cache_unref_delete(_object); 00193 } 00194 _object = NULL; 00195 } 00196 00197 //////////////////////////////////////////////////////////////////// 00198 // Function: CopyOnWritePointer::test_ref_count_integrity 00199 // Access: Published 00200 // Description: Does some easy checks to make sure that the reference 00201 // count isn't completely bogus. Returns true if ok, 00202 // false otherwise. 00203 //////////////////////////////////////////////////////////////////// 00204 INLINE bool CopyOnWritePointer:: 00205 test_ref_count_integrity() const { 00206 nassertr(_object != (CopyOnWriteObject *)NULL, false); 00207 return _object->test_ref_count_integrity(); 00208 } 00209 00210 //////////////////////////////////////////////////////////////////// 00211 // Function: CopyOnWritePointer::test_ref_count_nonzero 00212 // Access: Published 00213 // Description: Does some easy checks to make sure that the reference 00214 // count isn't zero, or completely bogus. Returns true 00215 // if ok, false otherwise. 00216 //////////////////////////////////////////////////////////////////// 00217 INLINE bool CopyOnWritePointer:: 00218 test_ref_count_nonzero() const { 00219 nassertr(_object != (CopyOnWriteObject *)NULL, false); 00220 return _object->test_ref_count_nonzero(); 00221 } 00222 00223 #ifndef CPPPARSER 00224 //////////////////////////////////////////////////////////////////// 00225 // Function: CopyOnWritePointerTo::Constructor 00226 // Access: Public 00227 // Description: 00228 //////////////////////////////////////////////////////////////////// 00229 template<class T> 00230 INLINE CopyOnWritePointerTo<T>:: 00231 CopyOnWritePointerTo(To *object) : CopyOnWritePointer(object) { 00232 } 00233 #endif // CPPPARSER 00234 00235 #ifndef CPPPARSER 00236 //////////////////////////////////////////////////////////////////// 00237 // Function: CopyOnWritePointerTo::Copy Constructor 00238 // Access: Public 00239 // Description: 00240 //////////////////////////////////////////////////////////////////// 00241 template<class T> 00242 INLINE CopyOnWritePointerTo<T>:: 00243 CopyOnWritePointerTo(const CopyOnWritePointerTo<T> ©) : 00244 CopyOnWritePointer(copy) 00245 { 00246 } 00247 #endif // CPPPARSER 00248 00249 #ifndef CPPPARSER 00250 //////////////////////////////////////////////////////////////////// 00251 // Function: CopyOnWritePointerTo::Copy Assignment Operator 00252 // Access: Public 00253 // Description: 00254 //////////////////////////////////////////////////////////////////// 00255 template<class T> 00256 INLINE void CopyOnWritePointerTo<T>:: 00257 operator = (const CopyOnWritePointerTo<T> ©) { 00258 CopyOnWritePointer::operator = (copy); 00259 } 00260 #endif // CPPPARSER 00261 00262 #ifndef CPPPARSER 00263 //////////////////////////////////////////////////////////////////// 00264 // Function: CopyOnWritePointer::Assignment Operator 00265 // Access: Public 00266 // Description: 00267 //////////////////////////////////////////////////////////////////// 00268 template<class T> 00269 INLINE void CopyOnWritePointerTo<T>:: 00270 operator = (To *object) { 00271 CopyOnWritePointer::operator = (object); 00272 } 00273 #endif // CPPPARSER 00274 00275 #ifndef CPPPARSER 00276 #ifdef COW_THREADED 00277 //////////////////////////////////////////////////////////////////// 00278 // Function: CopyOnWritePointerTo::get_read_pointer 00279 // Access: Public 00280 // Description: See CopyOnWritePointer::get_read_pointer(). 00281 //////////////////////////////////////////////////////////////////// 00282 template<class T> 00283 INLINE CPT(TYPENAME CopyOnWritePointerTo<T>::To) CopyOnWritePointerTo<T>:: 00284 get_read_pointer() const { 00285 return (const To *)(CopyOnWritePointer::get_read_pointer().p()); 00286 } 00287 #else // COW_THREADED 00288 //////////////////////////////////////////////////////////////////// 00289 // Function: CopyOnWritePointerTo::get_read_pointer 00290 // Access: Public 00291 // Description: See CopyOnWritePointer::get_read_pointer(). 00292 //////////////////////////////////////////////////////////////////// 00293 template<class T> 00294 INLINE const TYPENAME CopyOnWritePointerTo<T>::To *CopyOnWritePointerTo<T>:: 00295 get_read_pointer() const { 00296 return (const To *)CopyOnWritePointer::get_read_pointer(); 00297 } 00298 #endif // COW_THREADED 00299 #endif // CPPPARSER 00300 00301 #ifndef CPPPARSER 00302 #ifdef COW_THREADED 00303 //////////////////////////////////////////////////////////////////// 00304 // Function: CopyOnWritePointerTo::get_write_pointer 00305 // Access: Public 00306 // Description: See CopyOnWritePointer::get_write_pointer(). 00307 //////////////////////////////////////////////////////////////////// 00308 template<class T> 00309 INLINE PT(TYPENAME CopyOnWritePointerTo<T>::To) CopyOnWritePointerTo<T>:: 00310 get_write_pointer() { 00311 return (To *)(CopyOnWritePointer::get_write_pointer().p()); 00312 } 00313 #else // COW_THREADED 00314 //////////////////////////////////////////////////////////////////// 00315 // Function: CopyOnWritePointerTo::get_write_pointer 00316 // Access: Public 00317 // Description: See CopyOnWritePointer::get_write_pointer(). 00318 //////////////////////////////////////////////////////////////////// 00319 template<class T> 00320 INLINE TYPENAME CopyOnWritePointerTo<T>::To *CopyOnWritePointerTo<T>:: 00321 get_write_pointer() { 00322 return (To *)CopyOnWritePointer::get_write_pointer(); 00323 } 00324 #endif // COW_THREADED 00325 #endif // CPPPARSER 00326 00327 #ifndef CPPPARSER 00328 //////////////////////////////////////////////////////////////////// 00329 // Function: CopyOnWritePointerTo::get_unsafe_pointer 00330 // Access: Public 00331 // Description: See CopyOnWritePointer::get_unsafe_pointer(). 00332 //////////////////////////////////////////////////////////////////// 00333 template<class T> 00334 INLINE TYPENAME CopyOnWritePointerTo<T>::To *CopyOnWritePointerTo<T>:: 00335 get_unsafe_pointer() { 00336 return (To *)(CopyOnWritePointer::get_unsafe_pointer()); 00337 } 00338 #endif // CPPPARSER