00001 /* 00002 00003 ************************************************************************* 00004 00005 ArmageTron -- Just another Tron Lightcycle Game in 3D. 00006 Copyright (C) 2005 by Manuel Moos 00007 and the AA DevTeam (see the file AUTHORS(.txt) in the main source directory) 00008 00009 ************************************************************************** 00010 00011 This program is free software; you can redistribute it and/or 00012 modify it under the terms of the GNU General Public License 00013 as published by the Free Software Foundation; either version 2 00014 of the License, or (at your option) any later version. 00015 00016 This program is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 GNU General Public License for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with this program; if not, write to the Free Software 00023 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00024 00025 *************************************************************************** 00026 00027 */ 00028 00029 #include "tDecorator.h" 00030 00031 // ******************************************************************************* 00032 // * 00033 // * Allocate 00034 // * 00035 // ******************************************************************************* 00043 // ******************************************************************************* 00044 00045 void * tDecoratableManagerBase::Allocate( size_t size, const char * classn, const char * file, int line ) 00046 { 00047 // register object with manager 00048 if ( refCount_++ == 0 ) 00049 { 00051 CalculateOffsets(); 00052 } 00053 00054 // allocate requested space plus overhead for decorators 00055 size_t overhead = GetSize(); 00056 #ifndef DONTUSEMEMMANAGER 00057 00058 char * base = static_cast< char * > ( ::operator new( size + overhead, classn, file, line ) ) + overhead; 00059 #else 00060 char * base = static_cast< char * > ( ::operator new( size + overhead ) ) + overhead; 00061 #endif 00062 00063 // call decoration constructors 00064 ConstructAll( base); 00065 00066 return base; 00067 } 00068 00069 // ******************************************************************************* 00070 // * 00071 // * Free 00072 // * 00073 // ******************************************************************************* 00080 // ******************************************************************************* 00081 00082 void tDecoratableManagerBase::Free( void * ptr, const char * classn, const char * file, int line ) 00083 { 00084 // call decoration destructors 00085 DestructAll( ptr ); 00086 00087 // deregister with manager 00088 --refCount_; 00089 00090 // deallocate space and overhead 00091 size_t overhead = GetSize(); 00092 char * base = ( ( char * ) ptr ) - overhead; 00093 00094 #ifndef DONTUSEMEMMANAGER 00095 ::operator delete( base, classn, file, line ); 00096 #else 00097 ::operator delete( base ); 00098 #endif 00099 } 00100 00101 // ******************************************************************************* 00102 // * 00103 // * Tests 00104 // * 00105 // ******************************************************************************* 00106 00107 class base 00108 { 00109 public: 00110 virtual ~base(){} 00111 00112 DECORATABLE_BASE(base) 00113 }; 00114 00115 static tDecoratorPOD< base, int > decorator( 0 ); 00116 00117 class derived: public base 00118 { 00119 public: 00120 ~derived(){} 00121 00122 DECORATABLE(derived,base) 00123 }; 00124 00125 class dummy{}; 00126 void test_decorators() 00127 { 00128 tASSERT( tIsDecoratable< base >::DECORATABLE ); 00129 tASSERT( !tIsDecoratable< dummy >::DECORATABLE ); 00130 00131 base * p = new base; 00132 int * decoration = &decorator.Get( *p ); 00133 delete p; 00134 p = new derived; 00135 decoration = &decorator.Get( *p ); 00136 delete p; 00137 00138 // shouldn't compile 00139 // tDecoratable decoratable; 00140 00141 // tDecoratable * d2 = &decoratable; 00142 // d2 = tNEW(tDecoratable); 00143 // delete d2; 00144 // d2 = new tDerivedDecoratable; 00145 // delete d2; 00146 }