00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 template<class Base>
00016 TypeHandle RefCountProxy<Base>::_type_handle;
00017
00018 template<class Base>
00019 TypeHandle RefCountObj<Base>::_type_handle;
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 INLINE ReferenceCount::
00035 ReferenceCount() {
00036 _weak_list = (WeakReferenceList *)NULL;
00037 _ref_count = 0;
00038 #ifdef DO_MEMORY_USAGE
00039 MemoryUsage::record_pointer(this);
00040 #endif
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 INLINE ReferenceCount::
00054 ReferenceCount(const ReferenceCount &) {
00055 _weak_list = (WeakReferenceList *)NULL;
00056 _ref_count = 0;
00057 #ifdef DO_MEMORY_USAGE
00058 MemoryUsage::record_pointer(this);
00059 #endif
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 INLINE void ReferenceCount::
00076 operator = (const ReferenceCount &) {
00077 nassertv(this != NULL);
00078
00079
00080
00081
00082
00083
00084
00085
00086 nassertv(_ref_count != deleted_ref_count);
00087 }
00088
00089
00090
00091
00092
00093
00094 ReferenceCount::
00095 ~ReferenceCount() {
00096 TAU_PROFILE("ReferenceCount::~ReferenceCount()", " ", TAU_USER);
00097 nassertv(this != NULL);
00098
00099
00100
00101
00102
00103
00104
00105
00106 nassertv(_ref_count != deleted_ref_count);
00107
00108
00109
00110
00111
00112 nassertv(_ref_count <= local_ref_count);
00113
00114
00115
00116
00117 nassertv(_ref_count >= 0);
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 nassertv(_ref_count == 0 || _ref_count == local_ref_count);
00130
00131
00132 if (_weak_list != (WeakReferenceList *)NULL) {
00133 delete (WeakReferenceList *)_weak_list;
00134 _weak_list = (WeakReferenceList *)NULL;
00135 }
00136
00137 #ifndef NDEBUG
00138
00139
00140
00141 _ref_count = deleted_ref_count;
00142 #endif
00143
00144 #ifdef DO_MEMORY_USAGE
00145 MemoryUsage::remove_pointer(this);
00146 #endif
00147 }
00148
00149
00150
00151
00152
00153
00154 INLINE int ReferenceCount::
00155 get_ref_count() const {
00156 #ifdef _DEBUG
00157 test_ref_count_integrity();
00158 #endif
00159 return AtomicAdjust::get(_ref_count);
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 INLINE void ReferenceCount::
00179 ref() const {
00180 TAU_PROFILE("void ReferenceCount::ref()", " ", TAU_USER);
00181 #ifdef _DEBUG
00182 nassertv(test_ref_count_integrity());
00183 #endif
00184
00185 AtomicAdjust::inc(((ReferenceCount *)this)->_ref_count);
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 INLINE bool ReferenceCount::
00214 unref() const {
00215 TAU_PROFILE("void ReferenceCount::unref()", " ", TAU_USER);
00216 #ifdef _DEBUG
00217 nassertr(test_ref_count_integrity(), 0);
00218
00219
00220
00221
00222 nassertr(_ref_count > 0, 0);
00223 #endif
00224 return AtomicAdjust::dec(((ReferenceCount *)this)->_ref_count);
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 INLINE bool ReferenceCount::
00236 test_ref_count_integrity() const {
00237 #ifndef NDEBUG
00238 return do_test_ref_count_integrity();
00239 #else
00240 return true;
00241 #endif
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251 INLINE bool ReferenceCount::
00252 test_ref_count_nonzero() const {
00253 #ifndef NDEBUG
00254 return do_test_ref_count_nonzero();
00255 #else
00256 return true;
00257 #endif
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 INLINE void ReferenceCount::
00276 local_object() {
00277
00278
00279 nassertv(_ref_count == 0);
00280
00281 _ref_count = local_ref_count;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 INLINE bool ReferenceCount::
00294 has_weak_list() const {
00295 return _weak_list != (WeakReferenceList *)NULL;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 INLINE WeakReferenceList *ReferenceCount::
00307 get_weak_list() const {
00308 if (AtomicAdjust::get_ptr(_weak_list) == (WeakReferenceList *)NULL) {
00309 ((ReferenceCount *)this)->create_weak_list();
00310 }
00311 return (WeakReferenceList *)AtomicAdjust::get_ptr(_weak_list);
00312 }
00313
00314
00315
00316
00317
00318
00319
00320 INLINE void ReferenceCount::
00321 weak_ref(WeakPointerToVoid *ptv) {
00322 TAU_PROFILE("void ReferenceCount::weak_ref()", " ", TAU_USER);
00323 get_weak_list()->add_reference(ptv);
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333 INLINE void ReferenceCount::
00334 weak_unref(WeakPointerToVoid *ptv) {
00335 TAU_PROFILE("void ReferenceCount::weak_unref()", " ", TAU_USER);
00336 nassertv(has_weak_list());
00337 ((WeakReferenceList *)_weak_list)->clear_reference(ptv);
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 template<class RefCountType>
00351 INLINE void
00352 unref_delete(RefCountType *ptr) {
00353 TAU_PROFILE("void unref_delete(RefCountType *)", " ", TAU_USER);
00354
00355
00356
00357
00358
00359
00360 if (!ptr->unref()) {
00361
00362 delete ptr;
00363 }
00364 }
00365
00366
00367
00368
00369
00370
00371 template<class Base>
00372 INLINE RefCountProxy<Base>::
00373 RefCountProxy() {
00374 }
00375
00376
00377
00378
00379
00380
00381 template<class Base>
00382 INLINE RefCountProxy<Base>::
00383 RefCountProxy(const Base ©) : _base(copy) {
00384 }
00385
00386
00387
00388
00389
00390
00391 template<class Base>
00392 INLINE RefCountProxy<Base>::
00393 operator Base &() {
00394 return _base;
00395 }
00396
00397
00398
00399
00400
00401
00402 template<class Base>
00403 INLINE RefCountProxy<Base>::
00404 operator const Base &() const {
00405 return _base;
00406 }
00407
00408
00409
00410
00411
00412
00413 template<class Base>
00414 void RefCountProxy<Base>::
00415 init_type() {
00416 do_init_type(Base);
00417 register_type(_type_handle,
00418 "RefCountProxy<" + get_type_handle(Base).get_name() + ">",
00419 get_type_handle(Base));
00420 }
00421
00422
00423
00424
00425
00426
00427
00428 template<class Base>
00429 INLINE RefCountObj<Base>::
00430 RefCountObj() {
00431 }
00432
00433
00434
00435
00436
00437
00438 template<class Base>
00439 INLINE RefCountObj<Base>::
00440 RefCountObj(const Base ©) : Base(copy) {
00441 }
00442
00443
00444
00445
00446
00447
00448
00449 template<class Base>
00450 void RefCountObj<Base>::
00451 init_type() {
00452 #if defined(HAVE_RTTI) && !defined(__EDG__)
00453
00454 string base_name = typeid(Base).name();
00455 #else
00456 string base_name = "unknown";
00457 #endif
00458
00459 TypeHandle base_type = register_dynamic_type(base_name);
00460
00461 ReferenceCount::init_type();
00462 _type_handle =
00463 register_dynamic_type("RefCountObj<" + base_name + ">",
00464 base_type, ReferenceCount::get_class_type());
00465 }