00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef ArmageTron_LIST_H
00029 #define ArmageTron_LIST_H
00030
00031 #include "tArray.h"
00032 #include "tSafePTR.h"
00033 #include <new>
00034 #include <stdlib.h>
00035
00036 namespace referencing
00037 {
00038 inline void AddReference( void* )
00039 {
00040 }
00041
00042 inline void ReleaseReference( void* )
00043 {
00044 }
00045 }
00046
00047 #define tDECLARE_REFOBJ(T) \
00048 class T;\
00049 namespace referencing \
00050 {\
00051 void AddReference( T* );\
00052 void ReleaseReference( T* );\
00053 }
00054
00055 #define tDEFINE_REFOBJ(T) \
00056 namespace referencing \
00057 {\
00058 void AddReference( T* t)\
00059 {\
00060 tASSERT(t);\
00061 t->AddRef();\
00062 }\
00063 void ReleaseReference( T* t)\
00064 {\
00065 tASSERT(t);\
00066 t->Release();\
00067 }\
00068 }
00069
00070 tDECLARE_REFOBJ( nNetObject )
00071 tDECLARE_REFOBJ( ePoint )
00072 tDECLARE_REFOBJ( eHalfEdge )
00073 tDECLARE_REFOBJ( eFace )
00074
00075
00076
00077 template < class T >
00078 class tReferencer
00079 {
00080 public:
00081 static void AddReference( T* t )
00082 {
00083 referencing::AddReference( t );
00084 }
00085
00086 static void ReleaseReference( T* t )
00087 {
00088 referencing::ReleaseReference( t );
00089 }
00090 };
00091
00092 template <class T, bool MALLOC=false, bool REFERENCE=false> class tList:public tArray<T *, MALLOC> {
00093
00094 int offset;
00095
00096
00097 public:
00098
00099 ~tList(){
00100 for(int i=this->Len()-1;i>=0;i--)
00101 (reinterpret_cast<int *>((*this)(i)))[offset]=-1;
00102 }
00103
00104 tList(int size=0):tArray<T*, MALLOC>(size){}
00105
00106 void Add(T *t,int &idnum){
00107 offset=&idnum-(reinterpret_cast<int *>(t));
00108
00109 if (idnum<0){
00110 idnum=this->Len();
00111 (*this)[idnum]=t;
00112 if ( REFERENCE )
00113 {
00114 tReferencer< T >::AddReference( t );
00115 }
00116 }
00117 }
00118
00119 void Add( T* t )
00120 {
00121 Add( t, t->ListIDRef() );
00122 }
00123
00124 void Remove(T *t,int &idref)
00125 {
00126 int idnum = idref;
00127 idref = -1;
00128
00129
00130 if ( idnum>=0 ){
00131 #ifdef DEBUG
00132 if (idnum>=this->Len())
00133 tERR_ERROR_INT("Corrupted list structure!");
00134
00135 T *test=(*this)(idnum);
00136 if (test!=t)
00137 tERR_ERROR_INT("Corrupted list structure!");
00138 #endif
00139
00140
00141 if ( this->Len() > idnum+1 )
00142 {
00143 T *other=(*this)(this->Len()-1);
00144 tASSERT( other );
00145 (*this)(idnum)=other;
00146 int &other_id=(reinterpret_cast<int *>(other))[offset];
00147 tASSERT( other_id == this->Len()-1 );
00148 other_id=idnum;
00149 }
00150 (*this)[this->Len()-1] = NULL;
00151
00152 SetLen(this->Len()-1);
00153
00154 if ( REFERENCE )
00155 {
00156 tReferencer< T >::ReleaseReference( t );
00157 }
00158 }
00159
00160
00161 }
00162
00163 void Remove( T* t )
00164 {
00165 Remove( t, t->ListIDRef() );
00166 }
00167 };
00168
00169 class tListMember
00170 {
00171 public:
00172 int ListID(){return listID_;}
00173 int& ListIDRef(){return listID_;}
00174 tListMember():listID_(-1){};
00175 private:
00176 int listID_;
00177 };
00178
00179 #endif