00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __GZ_REFERENCE_H__
00022 #define __GZ_REFERENCE_H__
00023
00032 #include "gzMemory.h"
00033 #include "gzTemplates.h"
00034 #include "gzDebug.h"
00035 #include "gzType.h"
00036
00037
00038 enum gzCopyMode
00039 {
00040 GZ_CLONE_NO_SHARE = (0),
00041 GZ_CLONE_SHARE_ALL = 0xFFFFFFFFUL,
00042 };
00043
00044 GZ_USE_BIT_LOGIC(gzCopyMode);
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00061
00116 class GZ_BASE_EXPORT gzReference : public gzSharedMemory , public gzTypeInterface
00117 {
00118 public:
00119 GZ_DECLARE_TYPE_INTERFACE;
00120
00122 gzReference();
00123
00125 gzReference(const gzReference ©);
00126
00128 gzReference &operator=(const gzReference ©);
00129
00131 virtual ~gzReference();
00132
00134
00137 virtual gzReference* clone() const;
00138
00139 public:
00140
00141
00142
00143
00144
00146
00149 const gzCopyMode & getCopyMode() const { return m_copyMode; }
00150
00152
00153 virtual gzVoid setCopyMode(const gzCopyMode & mode) { m_copyMode=mode; }
00154
00156
00159 virtual gzBool useDeepCopy() { return m_copyMode==GZ_CLONE_NO_SHARE; }
00160
00162
00164 virtual gzVoid ref();
00165
00167
00169 virtual gzVoid unref();
00170
00172
00174 virtual gzUInt unrefNoDelete();
00175
00177
00180 virtual gzBool checkDelete();
00181
00183 virtual gzUInt getRef() const { return _refCount; }
00184
00185 protected:
00186
00187 gzUInt _refCount;
00188
00189 private:
00190
00191
00192
00193 static gzVoid throwFatalException( const char * str1 , const char * str2 = NULL);
00194
00195 gzCopyMode m_copyMode;
00196 };
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 inline gzReference::gzReference():_refCount(0),m_copyMode(GZ_CLONE_NO_SHARE)
00218 {
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 inline gzReference::gzReference(const gzReference ©):_refCount(0),m_copyMode(copy.m_copyMode)
00240 {}
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 inline gzReference & gzReference::operator=(const gzReference ©)
00261 {
00262 m_copyMode=copy.m_copyMode;
00263 return *this;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 inline gzReference::~gzReference()
00285 {
00286 if(_refCount)
00287 {
00288 throwFatalException("REFERENCE MISMATCH ! Deleted referenced object with nonzero reference count");
00289 }
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 inline gzReference* gzReference::clone() const
00312 {
00313 throwFatalException("Unimplemented clone called for type '%s'",(const char *)getTypeName());
00314 return NULL;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 inline gzVoid gzReference::ref()
00336 {
00337 ++_refCount;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 inline gzBool gzReference::checkDelete()
00359 {
00360 if(!_refCount)
00361 {
00362 delete this;
00363 return TRUE;
00364 }
00365 return FALSE;
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 inline gzVoid gzReference::unref()
00387 {
00388 if(_refCount)
00389 {
00390 if(!(--_refCount))
00391 delete this;
00392 }
00393 else
00394 {
00395 throwFatalException("REFERENCE MISMATCH ! Unref an object with zero reference count.");
00396 }
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 inline gzUInt gzReference::unrefNoDelete()
00418 {
00419 if(_refCount)
00420 {
00421 --_refCount;
00422 }
00423 else
00424 {
00425 throwFatalException("REFRENCE MISMATCH ! Unref an object with zero reference count.");
00426 }
00427 return _refCount;
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00447 template <class T> class gzRefPointer
00448 {
00449 public:
00450 gzRefPointer();
00451 gzRefPointer( const gzRefPointer<T> ©);
00452 gzRefPointer &operator=(const gzRefPointer<T> ©);
00453 gzRefPointer( T *pointer);
00454
00455 virtual ~gzRefPointer();
00456
00457 gzVoid set(T *pointer);
00458
00459 T * get() const { return m_pointer; }
00460
00461 operator T *() const { return m_pointer; }
00462
00463 T * operator ->() const { return m_pointer; }
00464
00465 virtual gzVoid setCopyMode(gzCopyMode mode)
00466 {
00467 if(m_pointer)
00468 m_pointer->setCopyMode(mode);
00469 }
00470
00471 private:
00472 T *m_pointer;
00473 };
00474
00475
00476
00477 template <class T> inline gzRefPointer<T>::gzRefPointer():m_pointer(NULL)
00478 {
00479 }
00480
00481
00482
00483 template <class T> inline gzRefPointer<T>::gzRefPointer( const gzRefPointer<T> ©)
00484 {
00485 if(copy.m_pointer)
00486 {
00487 if(copy.m_pointer->useDeepCopy())
00488 m_pointer=(T *)copy.m_pointer->clone();
00489 else
00490 m_pointer=copy.m_pointer;
00491 }
00492 else
00493 m_pointer=NULL;
00494
00495 if(m_pointer)
00496 m_pointer->ref();
00497 }
00498
00499
00500
00501 template <class T> inline gzRefPointer<T>::gzRefPointer( T *pointer)
00502 {
00503 m_pointer=pointer;
00504
00505 if(m_pointer)
00506 m_pointer->ref();
00507 }
00508
00509
00510
00511
00512 template <class T> inline gzRefPointer<T> & gzRefPointer<T>::operator =(const gzRefPointer<T> ©)
00513 {
00514 if(copy.m_pointer==m_pointer)
00515 return *this;
00516
00517 if(copy.m_pointer)
00518 copy.m_pointer->ref();
00519
00520 if(m_pointer)
00521 m_pointer->unref();
00522
00523 m_pointer=copy.m_pointer;
00524
00525 return *this;
00526 }
00527
00528
00529
00530 template <class T> inline gzVoid gzRefPointer<T>::set(T *pointer)
00531 {
00532 if(pointer==m_pointer)
00533 return;
00534
00535 if(pointer)
00536 pointer->ref();
00537
00538 if(m_pointer)
00539 m_pointer->unref();
00540
00541 m_pointer=pointer;
00542 }
00543
00544
00545
00546 template <class T> inline gzRefPointer<T>::~gzRefPointer()
00547 {
00548 if(m_pointer)
00549 m_pointer->unref();
00550 }
00551
00552 #define GZ_DECLARE_REFPTR(x) typedef gzRefPointer<x> x##Ptr
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00569 template <class T> class gzRefList : public gzList<T>
00570 {
00571 public:
00572
00573 gzRefList(gzBool reuseLinks=FALSE):gzList<T>(reuseLinks),m_useDelayedRemove(FALSE){};
00574
00575
00576
00578 gzRefList( const gzRefList<T> © ):m_useDelayedRemove(FALSE){ gzList<T>::operator=((const gzList<T> &)copy); }
00579
00581 gzRefList<T> &operator=(const gzRefList<T> © ) { gzList<T>::operator=((const gzList<T> &)copy); return *this; }
00582
00584 gzRefList( const gzList<T> © ):m_useDelayedRemove(FALSE){ operator=((const gzList<T> &)copy); }
00585
00587 gzRefList<T> &operator=(const gzList<T> © )
00588 {
00589 if(©==this)
00590 return *this;
00591
00592 clear();
00593
00594 typename gzList<T>::LinkItem *link=copy.m_link;
00595
00596 gzList<T>::m_link=0;
00597 gzList<T>::m_last=0;
00598
00599 while(link)
00600 {
00601 typename gzList<T>::LinkItem *newlink=gzList<T>::allocLink();
00602
00603 newlink->item=link->item;
00604
00605 onInsert(newlink->item);
00606
00607 newlink->sortval=link->sortval;
00608
00609 newlink->next=0;
00610
00611 if(gzList<T>::m_last)
00612 gzList<T>::m_last->next=newlink;
00613 else
00614 gzList<T>::m_link=newlink;
00615
00616 gzList<T>::m_last=newlink;
00617
00618 link=link->next;
00619 }
00620 gzList<T>::m_entries=copy.m_entries;
00621
00622 return *this;
00623 }
00624
00625 virtual ~gzRefList()
00626 {
00627 clear();
00628 }
00629
00630 gzVoid useDelayedRemove(gzBool on)
00631 {
00632 m_useDelayedRemove=on;
00633 }
00634
00635 virtual gzVoid onInsert(T *item ) const
00636 {
00637 if(item)
00638 item->ref();
00639 }
00640
00641 virtual gzVoid onRemove(T *item ) const
00642 {
00643 if(m_useDelayedRemove)
00644 ((gzRefList<T> *)this)->m_delayedRemove.set(item);
00645
00646 if(item)
00647 item->unref();
00648 }
00649
00650 virtual T *cloneEntry(T *item ) const
00651 {
00652 if(item)
00653 {
00654 if(item->useDeepCopy())
00655 return (T *)item->clone();
00656 else
00657 return item;
00658 }
00659 else
00660 return NULL;
00661 }
00662 virtual gzVoid setCopyMode(gzCopyMode mode)
00663 {
00664 T *entry;
00665
00666 gzListIterator<T> iterator(*this);
00667
00668 while(entry=iterator())
00669 {
00670 entry->setCopyMode(mode);
00671 }
00672 }
00673
00674 virtual gzVoid clear()
00675 {
00676 gzList<T>::clear();
00677 cleanDelayedRemove();
00678 }
00679
00680 gzVoid cleanDelayedRemove()
00681 {
00682 m_delayedRemove=NULL;
00683 }
00684
00685
00686 private:
00687
00688 gzRefPointer<T> m_delayedRemove;
00689
00690 gzBool m_useDelayedRemove;
00691
00692 };
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00709 template <class T> class gzRefDList : public gzDList<T>
00710 {
00711 public:
00712
00713 gzRefDList():m_useDelayedRemove(FALSE){};
00714 gzRefDList( const gzRefDList © ):m_useDelayedRemove(FALSE){ gzDList<T>::operator=((const gzDList<T> &)copy); }
00715 gzRefDList( const gzRefList<T> © ):m_useDelayedRemove(FALSE){ gzDList<T>::operator=((const gzList<T> &)copy); }
00716
00717 virtual ~gzRefDList()
00718 {
00719 clear();
00720 }
00721
00722 gzVoid useDelayedRemove(gzBool on)
00723 {
00724 m_useDelayedRemove=on;
00725 }
00726
00727 virtual gzVoid onInsert(T *item ) const
00728 {
00729 if(item)
00730 item->ref();
00731 }
00732
00733 virtual gzVoid onRemove(T *item ) const
00734 {
00735 if(m_useDelayedRemove)
00736 ((gzRefDList<T> *)this)->m_delayedRemove.set(item);
00737
00738 if(item)
00739 item->unref();
00740 }
00741
00742 virtual T *cloneEntry(T *item ) const
00743 {
00744 if(item)
00745 {
00746 if(item->useDeepCopy())
00747 return (T *)item->clone();
00748 else
00749 return item;
00750 }
00751 else
00752 return NULL;
00753 }
00754 virtual gzVoid setCopyMode(gzCopyMode mode)
00755 {
00756 T *entry;
00757
00758 gzDListIterator<T> iterator(*this);
00759
00760 while(entry=iterator())
00761 {
00762 entry->setCopyMode(mode);
00763 }
00764 }
00765
00766 virtual gzVoid clear()
00767 {
00768 gzDList<T>::clear();
00769 cleanDelayedRemove();
00770 }
00771
00772 gzVoid cleanDelayedRemove()
00773 {
00774 m_delayedRemove=NULL;
00775 }
00776
00777 private:
00778
00779 gzRefPointer<T> m_delayedRemove;
00780
00781 gzBool m_useDelayedRemove;
00782
00783 };
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00800 template <class T1 , class T2> class gzRefDict : public gzDict<T1,T2>
00801 {
00802 public:
00803 gzRefDict(unsigned long size=10,gzBool useAutoResize=FALSE):gzDict<T1,T2>(size,useAutoResize),m_useDelayedRemove(FALSE){};
00804
00805 gzRefDict( const gzRefDict © ):gzDict<T1,T2>(0),m_useDelayedRemove(FALSE) { gzDict<T1,T2>::operator=((const gzDict<T1,T2> &)copy); }
00806
00807 virtual ~gzRefDict()
00808 {
00809 clear();
00810 }
00811
00812 gzVoid onInsert(const T1 & , T2 *item) const { if(item)item->ref();};
00813
00814 gzVoid onRemove(const T1 & , T2 *item) const
00815 {
00816 if(m_useDelayedRemove)
00817 ((gzRefDict<T1,T2> *)this)->m_delayedRemove.set(item);
00818
00819 if(item)item->unref();
00820 }
00821
00822 virtual gzDictEntry<T1,T2> *cloneEntry( gzDictEntry<T1,T2> *item) const
00823 {
00824 if(item)
00825 {
00826 if(item->getData()->useDeepCopy())
00827 return allocEntry(item->getKey(),(T2 *)item->getData()->clone(),item->getKey().hash());
00828 else
00829 return allocEntry(item->getKey(),item->getData(),item->getKey().hash());
00830 }
00831 else
00832 return NULL;
00833 }
00834
00835 virtual gzVoid setCopyMode(gzCopyMode mode)
00836 {
00837 gzDictEntry<T1,T2> *entry;
00838 gzDictIterator<T1,T2> iterator(*this);
00839
00840 while(entry=iterator())
00841 {
00842 if(entry->getData())
00843 entry->getData()->setCopyMode(mode);
00844 }
00845 }
00846
00847 gzVoid cleanDelayedRemove()
00848 {
00849 m_delayedRemove=NULL;
00850 }
00851
00852 gzVoid useDelayedRemove(gzBool on)
00853 {
00854 m_useDelayedRemove=on;
00855 }
00856
00857 virtual gzVoid clear()
00858 {
00859 gzDict<T1,T2>::clear();
00860 cleanDelayedRemove();
00861 }
00862
00863
00864 private:
00865
00866 gzRefPointer<T2> m_delayedRemove;
00867
00868 gzBool m_useDelayedRemove;
00869 };
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00887 template <class T1 , class T2=gzReference > class gzRefData : public T1 , public gzReference
00888 {
00889 public:
00890
00891 gzRefData(){};
00892
00893 gzRefData( const T1 & copy ):T1(copy){};
00894
00895 virtual ~gzRefData(){};
00896
00897 virtual gzReference* clone() const
00898 {
00899 return new gzRefData<T1,T2>(*this);
00900 }
00901
00902 virtual gzVoid setCopyMode(gzCopyMode mode)
00903 {
00904 gzReference::setCopyMode(mode);
00905 }
00906
00907 static gzType *getClassType() { return T2::getClassType(); }
00908
00909 virtual gzType *getType() const { return T2::getClassType(); }
00910 };
00911
00912
00913
00914 class gzRefInstanceDictionary : public gzRefDict<gzInstanceCompareInterface,gzReference>
00915 {
00916 public:
00917 gzRefInstanceDictionary(gzULong size=100):gzRefDict<gzInstanceCompareInterface,gzReference>(size){};
00918 };
00919
00920 class gzRefInstanceArray : public gzDynamicArray< gzRefPointer<gzReference> >
00921 {
00922 public:
00923 gzRefInstanceArray(gzULong size=100) : gzDynamicArray< gzRefPointer<gzReference> >(size) {};
00924 };
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 class gzRefIdStorage : public gzReference
00943 {
00944 public:
00945
00946 gzQueue<gzUInt> id;
00947 };
00948
00949 #endif // __GZ_REFERENCE_H__