1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/*
*************************************************************************
ArmageTron -- Just another Tron Lightcycle Game in 3D.
Copyright (C) 2005 by Manuel Moos
and the AA DevTeam (see the file AUTHORS(.txt) in the main source directory)
**************************************************************************
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
***************************************************************************
*/
#include "tDecorator.h"
// *******************************************************************************
// *
// * Allocate
// *
// *******************************************************************************
//!
//! @param size size of the memory block to allocate
//! @param classn name of the class that is allocated
//! @param file name of the file this call comes from
//! @param line line in the file the call ocmes from
//! @return the newly allocated block of memory, with space for decorators
//!
// *******************************************************************************
void * tDecoratableManagerBase::Allocate( size_t size, const char * classn, const char * file, int line )
{
// register object with manager
if ( refCount_++ == 0 )
{
/// calculate offsets of decorators if required
CalculateOffsets();
}
// allocate requested space plus overhead for decorators
size_t overhead = GetSize();
#ifndef DONTUSEMEMMANAGER
char * base = static_cast< char * > ( ::operator new( size + overhead, classn, file, line ) ) + overhead;
#else
char * base = static_cast< char * > ( ::operator new( size + overhead ) ) + overhead;
#endif
// call decoration constructors
ConstructAll( base);
return base;
}
// *******************************************************************************
// *
// * Free
// *
// *******************************************************************************
//!
//! @param ptr pointer to the memory area to be freed
//! @param classn name of the class that is allocated
//! @param file name of the file this call comes from
//! @param line line in the file the call ocmes from
//!
// *******************************************************************************
void tDecoratableManagerBase::Free( void * ptr, const char * classn, const char * file, int line )
{
// call decoration destructors
DestructAll( ptr );
// deregister with manager
--refCount_;
// deallocate space and overhead
size_t overhead = GetSize();
char * base = ( ( char * ) ptr ) - overhead;
#ifndef DONTUSEMEMMANAGER
::operator delete( base, classn, file, line );
#else
::operator delete( base );
#endif
}
// *******************************************************************************
// *
// * Tests
// *
// *******************************************************************************
class base
{
public:
virtual ~base(){}
DECORATABLE_BASE(base)
};
static tDecoratorPOD< base, int > decorator( 0 );
class derived: public base
{
public:
~derived(){}
DECORATABLE(derived,base)
};
class dummy{};
void test_decorators()
{
tASSERT( tIsDecoratable< base >::DECORATABLE );
tASSERT( !tIsDecoratable< dummy >::DECORATABLE );
base * p = new base;
int * decoration = &decorator.Get( *p );
*decoration = 5;
delete p;
p = new derived;
decoration = &decorator.Get( *p );
delete p;
// shouldn't compile
// tDecoratable decoratable;
// tDecoratable * d2 = &decoratable;
// d2 = tNEW(tDecoratable);
// delete d2;
// d2 = new tDerivedDecoratable;
// delete d2;
}
|