]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/game/gamesys/Class.h
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / game / gamesys / Class.h
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28 /*
29
30 Base class for all game objects.  Provides fast run-time type checking and run-time
31 instancing of objects.
32
33 */
34
35 #ifndef __SYS_CLASS_H__
36 #define __SYS_CLASS_H__
37
38 class idClass;
39 class idTypeInfo;
40
41 extern const idEventDef EV_Remove;
42 extern const idEventDef EV_SafeRemove;
43
44 typedef void ( idClass::*eventCallback_t )( void );
45
46 template< class Type >
47 struct idEventFunc {
48         const idEventDef        *event;
49         eventCallback_t         function;
50 };
51
52 // added & so gcc could compile this
53 #define EVENT( event, function )        { &( event ), ( void ( idClass::* )( void ) )( &function ) },
54 #define END_CLASS                                       { NULL, NULL } };
55
56
57 class idEventArg {
58 public:
59         int                     type;
60         int                     value;
61
62         idEventArg()                                                            { type = D_EVENT_INTEGER; value = 0; };
63         idEventArg( int data )                                          { type = D_EVENT_INTEGER; value = data; };
64         idEventArg( float data )                                        { type = D_EVENT_FLOAT; value = *reinterpret_cast<int *>( &data ); };
65         idEventArg( idVec3 &data )                                      { type = D_EVENT_VECTOR; value = reinterpret_cast<int>( &data ); };
66         idEventArg( const idStr &data )                         { type = D_EVENT_STRING; value = reinterpret_cast<int>( data.c_str() ); };
67         idEventArg( const char *data )                          { type = D_EVENT_STRING; value = reinterpret_cast<int>( data ); };
68         idEventArg( const class idEntity *data )        { type = D_EVENT_ENTITY; value = reinterpret_cast<int>( data ); };
69         idEventArg( const struct trace_s *data )        { type = D_EVENT_TRACE; value = reinterpret_cast<int>( data ); };
70 };
71
72 class idAllocError : public idException {
73 public:
74         idAllocError( const char *text = "" ) : idException( text ) {}
75 };
76
77 /***********************************************************************
78
79   idClass
80
81 ***********************************************************************/
82
83 /*
84 ================
85 CLASS_PROTOTYPE
86
87 This macro must be included in the definition of any subclass of idClass.
88 It prototypes variables used in class instanciation and type checking.
89 Use this on single inheritance concrete classes only.
90 ================
91 */
92 #define CLASS_PROTOTYPE( nameofclass )                                                                  \
93 public:                                                                                                                                 \
94         static  idTypeInfo                                              Type;                                           \
95         static  idClass                                                 *CreateInstance( void );        \
96         virtual idTypeInfo                                              *GetType( void ) const;         \
97         static  idEventFunc<nameofclass>                eventCallbacks[]
98
99 /*
100 ================
101 CLASS_DECLARATION
102
103 This macro must be included in the code to properly initialize variables
104 used in type checking and run-time instanciation.  It also defines the list
105 of events that the class responds to.  Take special care to ensure that the 
106 proper superclass is indicated or the run-time type information will be
107 incorrect.  Use this on concrete classes only.
108 ================
109 */
110 #define CLASS_DECLARATION( nameofsuperclass, nameofclass )                                                                                      \
111         idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass,                                                                  \
112                 ( idEventFunc<idClass> * )nameofclass::eventCallbacks,  nameofclass::CreateInstance, ( void ( idClass::* )( void ) )&nameofclass::Spawn,        \
113                 ( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore );     \
114         idClass *nameofclass::CreateInstance( void ) {                                                                                                  \
115                 try {                                                                                                                                                                           \
116                         nameofclass *ptr = new nameofclass;                                                                                                             \
117                         ptr->FindUninitializedMemory();                                                                                                                 \
118                         return ptr;                                                                                                                                                             \
119                 }                                                                                                                                                                                       \
120                 catch( idAllocError & ) {                                                                                                                                       \
121                         return NULL;                                                                                                                                                    \
122                 }                                                                                                                                                                                       \
123         }                                                                                                                                                                                               \
124         idTypeInfo *nameofclass::GetType( void ) const {                                                                                                \
125                 return &( nameofclass::Type );                                                                                                                          \
126         }                                                                                                                                                                                               \
127 idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
128
129 /*
130 ================
131 ABSTRACT_PROTOTYPE
132
133 This macro must be included in the definition of any abstract subclass of idClass.
134 It prototypes variables used in class instanciation and type checking.
135 Use this on single inheritance abstract classes only.
136 ================
137 */
138 #define ABSTRACT_PROTOTYPE( nameofclass )                                                               \
139 public:                                                                                                                                 \
140         static  idTypeInfo                                              Type;                                           \
141         static  idClass                                                 *CreateInstance( void );        \
142         virtual idTypeInfo                                              *GetType( void ) const;         \
143         static  idEventFunc<nameofclass>                eventCallbacks[]
144
145 /*
146 ================
147 ABSTRACT_DECLARATION
148
149 This macro must be included in the code to properly initialize variables
150 used in type checking.  It also defines the list of events that the class
151 responds to.  Take special care to ensure that the proper superclass is
152 indicated or the run-time tyep information will be incorrect.  Use this
153 on abstract classes only.
154 ================
155 */
156 #define ABSTRACT_DECLARATION( nameofsuperclass, nameofclass )                                                                           \
157         idTypeInfo nameofclass::Type( #nameofclass, #nameofsuperclass,                                                                  \
158                 ( idEventFunc<idClass> * )nameofclass::eventCallbacks, nameofclass::CreateInstance, ( void ( idClass::* )( void ) )&nameofclass::Spawn, \
159                 ( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore );     \
160         idClass *nameofclass::CreateInstance( void ) {                                                                                                  \
161                 gameLocal.Error( "Cannot instanciate abstract class %s.", #nameofclass );                                       \
162                 return NULL;                                                                                                                                                            \
163         }                                                                                                                                                                                               \
164         idTypeInfo *nameofclass::GetType( void ) const {                                                                                                \
165                 return &( nameofclass::Type );                                                                                                                          \
166         }                                                                                                                                                                                               \
167         idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
168
169 typedef void ( idClass::*classSpawnFunc_t )( void );
170
171 class idSaveGame;
172 class idRestoreGame;
173
174 class idClass {
175 public:
176         ABSTRACT_PROTOTYPE( idClass );
177
178 #ifdef ID_REDIRECT_NEWDELETE
179 #undef new
180 #endif
181         void *                                          operator new( size_t );
182         void *                                          operator new( size_t s, int, int, char *, int );
183         void                                            operator delete( void * );
184         void                                            operator delete( void *, int, int, char *, int );
185 #ifdef ID_REDIRECT_NEWDELETE
186 #define new ID_DEBUG_NEW
187 #endif
188
189         virtual                                         ~idClass();
190
191         void                                            Spawn( void );
192         void                                            CallSpawn( void );
193         bool                                            IsType( const idTypeInfo &c ) const;
194         const char *                            GetClassname( void ) const;
195         const char *                            GetSuperclass( void ) const;
196         void                                            FindUninitializedMemory( void );
197
198         void                                            Save( idSaveGame *savefile ) const {};
199         void                                            Restore( idRestoreGame *savefile ) {};
200
201         bool                                            RespondsTo( const idEventDef &ev ) const;
202
203         bool                                            PostEventMS( const idEventDef *ev, int time );
204         bool                                            PostEventMS( const idEventDef *ev, int time, idEventArg arg1 );
205         bool                                            PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2 );
206         bool                                            PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
207         bool                                            PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
208         bool                                            PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
209         bool                                            PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
210         bool                                            PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
211         bool                                            PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
212
213         bool                                            PostEventSec( const idEventDef *ev, float time );
214         bool                                            PostEventSec( const idEventDef *ev, float time, idEventArg arg1 );
215         bool                                            PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2 );
216         bool                                            PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
217         bool                                            PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
218         bool                                            PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
219         bool                                            PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
220         bool                                            PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
221         bool                                            PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
222
223         bool                                            ProcessEvent( const idEventDef *ev );
224         bool                                            ProcessEvent( const idEventDef *ev, idEventArg arg1 );
225         bool                                            ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2 );
226         bool                                            ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
227         bool                                            ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
228         bool                                            ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
229         bool                                            ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
230         bool                                            ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
231         bool                                            ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
232
233         bool                                            ProcessEventArgPtr( const idEventDef *ev, int *data );
234         void                                            CancelEvents( const idEventDef *ev );
235
236         void                                            Event_Remove( void );
237
238         // Static functions
239         static void                                     Init( void );
240         static void                                     Shutdown( void );
241         static idTypeInfo *                     GetClass( const char *name );
242         static void                                     DisplayInfo_f( const idCmdArgs &args );
243         static void                                     ListClasses_f( const idCmdArgs &args );
244         static idClass *                        CreateInstance( const char *name );
245         static int                                      GetNumTypes( void ) { return types.Num(); }
246         static int                                      GetTypeNumBits( void ) { return typeNumBits; }
247         static idTypeInfo *                     GetType( int num );
248
249 private:
250         classSpawnFunc_t                        CallSpawnFunc( idTypeInfo *cls );
251
252         bool                                            PostEventArgs( const idEventDef *ev, int time, int numargs, ... );
253         bool                                            ProcessEventArgs( const idEventDef *ev, int numargs, ... );
254
255         void                                            Event_SafeRemove( void );
256
257         static bool                                     initialized;
258         static idList<idTypeInfo *>     types;
259         static idList<idTypeInfo *>     typenums;
260         static int                                      typeNumBits;
261         static int                                      memused;
262         static int                                      numobjects;
263 };
264
265 /***********************************************************************
266
267   idTypeInfo
268
269 ***********************************************************************/
270
271 class idTypeInfo {
272 public:
273         const char *                            classname;
274         const char *                            superclass;
275         idClass *                                       ( *CreateInstance )( void );
276         void                                            ( idClass::*Spawn )( void );
277         void                                            ( idClass::*Save )( idSaveGame *savefile ) const;
278         void                                            ( idClass::*Restore )( idRestoreGame *savefile );
279
280         idEventFunc<idClass> *          eventCallbacks;
281         eventCallback_t *                       eventMap;
282         idTypeInfo *                            super;
283         idTypeInfo *                            next;
284         bool                                            freeEventMap;
285         int                                                     typeNum;
286         int                                                     lastChild;
287
288         idHierarchy<idTypeInfo>         node;
289
290                                                                 idTypeInfo( const char *classname, const char *superclass, 
291                                                                                                 idEventFunc<idClass> *eventCallbacks, idClass *( *CreateInstance )( void ), void ( idClass::*Spawn )( void ),
292                                                                                                 void ( idClass::*Save )( idSaveGame *savefile ) const, void     ( idClass::*Restore )( idRestoreGame *savefile ) );
293                                                                 ~idTypeInfo();
294
295         void                                            Init( void );
296         void                                            Shutdown( void );
297
298         bool                                            IsType( const idTypeInfo &superclass ) const;
299         bool                                            RespondsTo( const idEventDef &ev ) const;
300 };
301
302 /*
303 ================
304 idTypeInfo::IsType
305
306 Checks if the object's class is a subclass of the class defined by the 
307 passed in idTypeInfo.
308 ================
309 */
310 ID_INLINE bool idTypeInfo::IsType( const idTypeInfo &type ) const {
311         return ( ( typeNum >= type.typeNum ) && ( typeNum <= type.lastChild ) );
312 }
313
314 /*
315 ================
316 idTypeInfo::RespondsTo
317 ================
318 */
319 ID_INLINE bool idTypeInfo::RespondsTo( const idEventDef &ev ) const {
320         assert( idEvent::initialized );
321         if ( !eventMap[ ev.GetEventNum() ] ) {
322                 // we don't respond to this event
323                 return false;
324         }
325
326         return true;
327 }
328
329 /*
330 ================
331 idClass::IsType
332
333 Checks if the object's class is a subclass of the class defined by the 
334 passed in idTypeInfo.
335 ================
336 */
337 ID_INLINE bool idClass::IsType( const idTypeInfo &superclass ) const {
338         idTypeInfo *subclass;
339
340         subclass = GetType();
341         return subclass->IsType( superclass );
342 }
343
344 /*
345 ================
346 idClass::RespondsTo
347 ================
348 */
349 ID_INLINE bool idClass::RespondsTo( const idEventDef &ev ) const {
350         const idTypeInfo *c;
351
352         assert( idEvent::initialized );
353         c = GetType();
354         return c->RespondsTo( ev );
355 }
356
357 #endif /* !__SYS_CLASS_H__ */