src/tools/tList.h

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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 // a usefull class of lists
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     //  friend T;
00094     int offset;
00095 
00096     // Array<T *> list;
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){    // tEventQueue relies on the fact that we put t in
00110             idnum=this->Len();   // the last place.
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         // con << "offset=" << offset << '\n';
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             // the check for Len() is done, since this may be
00140             // called on an allready descructed list.
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         //              tASSERT( idref == -1 );
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

Generated on Sat Mar 15 22:56:00 2008 for Armagetron Advanced by  doxygen 1.5.4