2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
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.
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.
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/>.
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.
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.
26 ===========================================================================
30 Base class for all game objects. Provides fast run-time type checking and run-time
31 instancing of objects.
35 #ifndef __SYS_CLASS_H__
36 #define __SYS_CLASS_H__
41 extern const idEventDef EV_Remove;
42 extern const idEventDef EV_SafeRemove;
44 typedef void ( idClass::*eventCallback_t )( void );
46 template< class Type >
48 const idEventDef *event;
49 eventCallback_t function;
52 // added & so gcc could compile this
53 #define EVENT( event, function ) { &( event ), ( void ( idClass::* )( void ) )( &function ) },
54 #define END_CLASS { NULL, NULL } };
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 ); };
72 class idAllocError : public idException {
74 idAllocError( const char *text = "" ) : idException( text ) {}
77 /***********************************************************************
81 ***********************************************************************/
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.
92 #define CLASS_PROTOTYPE( nameofclass ) \
94 static idTypeInfo Type; \
95 static idClass *CreateInstance( void ); \
96 virtual idTypeInfo *GetType( void ) const; \
97 static idEventFunc<nameofclass> eventCallbacks[]
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.
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 ) { \
116 nameofclass *ptr = new nameofclass; \
117 ptr->FindUninitializedMemory(); \
120 catch( idAllocError & ) { \
124 idTypeInfo *nameofclass::GetType( void ) const { \
125 return &( nameofclass::Type ); \
127 idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
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.
138 #define ABSTRACT_PROTOTYPE( nameofclass ) \
140 static idTypeInfo Type; \
141 static idClass *CreateInstance( void ); \
142 virtual idTypeInfo *GetType( void ) const; \
143 static idEventFunc<nameofclass> eventCallbacks[]
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.
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 ); \
164 idTypeInfo *nameofclass::GetType( void ) const { \
165 return &( nameofclass::Type ); \
167 idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
169 typedef void ( idClass::*classSpawnFunc_t )( void );
176 ABSTRACT_PROTOTYPE( idClass );
178 #ifdef ID_REDIRECT_NEWDELETE
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
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 );
198 void Save( idSaveGame *savefile ) const {};
199 void Restore( idRestoreGame *savefile ) {};
201 bool RespondsTo( const idEventDef &ev ) const;
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 );
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 );
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 );
233 bool ProcessEventArgPtr( const idEventDef *ev, int *data );
234 void CancelEvents( const idEventDef *ev );
236 void Event_Remove( void );
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 );
250 classSpawnFunc_t CallSpawnFunc( idTypeInfo *cls );
252 bool PostEventArgs( const idEventDef *ev, int time, int numargs, ... );
253 bool ProcessEventArgs( const idEventDef *ev, int numargs, ... );
255 void Event_SafeRemove( void );
257 static bool initialized;
258 static idList<idTypeInfo *> types;
259 static idList<idTypeInfo *> typenums;
260 static int typeNumBits;
262 static int numobjects;
265 /***********************************************************************
269 ***********************************************************************/
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 );
280 idEventFunc<idClass> * eventCallbacks;
281 eventCallback_t * eventMap;
288 idHierarchy<idTypeInfo> node;
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 ) );
296 void Shutdown( void );
298 bool IsType( const idTypeInfo &superclass ) const;
299 bool RespondsTo( const idEventDef &ev ) const;
306 Checks if the object's class is a subclass of the class defined by the
307 passed in idTypeInfo.
310 ID_INLINE bool idTypeInfo::IsType( const idTypeInfo &type ) const {
311 return ( ( typeNum >= type.typeNum ) && ( typeNum <= type.lastChild ) );
316 idTypeInfo::RespondsTo
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
333 Checks if the object's class is a subclass of the class defined by the
334 passed in idTypeInfo.
337 ID_INLINE bool idClass::IsType( const idTypeInfo &superclass ) const {
338 idTypeInfo *subclass;
340 subclass = GetType();
341 return subclass->IsType( superclass );
349 ID_INLINE bool idClass::RespondsTo( const idEventDef &ev ) const {
352 assert( idEvent::initialized );
354 return c->RespondsTo( ev );
357 #endif /* !__SYS_CLASS_H__ */