DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

Class.h (14235B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition 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 BFG Edition 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 )();
     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::* )() )( &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();	\
     96 	virtual	idTypeInfo						*GetType() 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::* )() )&nameofclass::Spawn,	\
    113 		( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore );	\
    114 	idClass *nameofclass::CreateInstance() {														\
    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() 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();	\
    142 	virtual	idTypeInfo						*GetType() 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::* )() )&nameofclass::Spawn,	\
    159 		( void ( idClass::* )( idSaveGame * ) const )&nameofclass::Save, ( void ( idClass::* )( idRestoreGame * ) )&nameofclass::Restore );	\
    160 	idClass *nameofclass::CreateInstance() {													\
    161 		gameLocal.Error( "Cannot instanciate abstract class %s.", #nameofclass );					\
    162 		return NULL;																				\
    163 	}																								\
    164 	idTypeInfo *nameofclass::GetType() const {												\
    165 		return &( nameofclass::Type );																\
    166 	}																								\
    167 	idEventFunc<nameofclass> nameofclass::eventCallbacks[] = {
    168 
    169 typedef void ( idClass::*classSpawnFunc_t )();
    170 
    171 class idSaveGame;
    172 class idRestoreGame;
    173 
    174 class idClass {
    175 public:
    176 	ABSTRACT_PROTOTYPE( idClass );
    177 
    178 	void *						operator new( size_t );
    179 	void						operator delete( void * );
    180 
    181 	virtual						~idClass();
    182 
    183 	void						Spawn();
    184 	void						CallSpawn();
    185 	bool						IsType( const idTypeInfo &c ) const;
    186 	const char *				GetClassname() const;
    187 	const char *				GetSuperclass() const;
    188 	void						FindUninitializedMemory();
    189 
    190 	void						Save( idSaveGame *savefile ) const {};
    191 	void						Restore( idRestoreGame *savefile ) {};
    192 
    193 	bool						RespondsTo( const idEventDef &ev ) const;
    194 
    195 	bool						PostEventMS( const idEventDef *ev, int time );
    196 	bool						PostEventMS( const idEventDef *ev, int time, idEventArg arg1 );
    197 	bool						PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2 );
    198 	bool						PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
    199 	bool						PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
    200 	bool						PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
    201 	bool						PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
    202 	bool						PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
    203 	bool						PostEventMS( const idEventDef *ev, int time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
    204 
    205 	bool						PostEventSec( const idEventDef *ev, float time );
    206 	bool						PostEventSec( const idEventDef *ev, float time, idEventArg arg1 );
    207 	bool						PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2 );
    208 	bool						PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
    209 	bool						PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
    210 	bool						PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
    211 	bool						PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
    212 	bool						PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
    213 	bool						PostEventSec( const idEventDef *ev, float time, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
    214 
    215 	bool						ProcessEvent( const idEventDef *ev );
    216 	bool						ProcessEvent( const idEventDef *ev, idEventArg arg1 );
    217 	bool						ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2 );
    218 	bool						ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3 );
    219 	bool						ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4 );
    220 	bool						ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5 );
    221 	bool						ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6 );
    222 	bool						ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7 );
    223 	bool						ProcessEvent( const idEventDef *ev, idEventArg arg1, idEventArg arg2, idEventArg arg3, idEventArg arg4, idEventArg arg5, idEventArg arg6, idEventArg arg7, idEventArg arg8 );
    224 
    225 	bool						ProcessEventArgPtr( const idEventDef *ev, int *data );
    226 	void						CancelEvents( const idEventDef *ev );
    227 
    228 	void						Event_Remove();
    229 
    230 	// Static functions
    231 	static void					Init();
    232 	static void					Shutdown();
    233 	static idTypeInfo *			GetClass( const char *name );
    234 	static void					DisplayInfo_f( const idCmdArgs &args );
    235 	static void					ListClasses_f( const idCmdArgs &args );
    236 	static idClass *			CreateInstance( const char *name );
    237 	static int					GetNumTypes() { return types.Num(); }
    238 	static int					GetTypeNumBits() { return typeNumBits; }
    239 	static idTypeInfo *			GetType( int num );
    240 
    241 private:
    242 	classSpawnFunc_t			CallSpawnFunc( idTypeInfo *cls );
    243 
    244 	bool						PostEventArgs( const idEventDef *ev, int time, int numargs, ... );
    245 	bool						ProcessEventArgs( const idEventDef *ev, int numargs, ... );
    246 
    247 	void						Event_SafeRemove();
    248 
    249 	static bool					initialized;
    250 	static idList<idTypeInfo *, TAG_IDCLASS>	types;
    251 	static idList<idTypeInfo *, TAG_IDCLASS>	typenums;
    252 	static int					typeNumBits;
    253 	static int					memused;
    254 	static int					numobjects;
    255 };
    256 
    257 /***********************************************************************
    258 
    259   idTypeInfo
    260 
    261 ***********************************************************************/
    262 
    263 class idTypeInfo {
    264 public:
    265 	const char *				classname;
    266 	const char *				superclass;
    267 	idClass *					( *CreateInstance )();
    268 	void						( idClass::*Spawn )();
    269 	void						( idClass::*Save )( idSaveGame *savefile ) const;
    270 	void						( idClass::*Restore )( idRestoreGame *savefile );
    271 
    272 	idEventFunc<idClass> *		eventCallbacks;
    273 	eventCallback_t *			eventMap;
    274 	idTypeInfo *				super;
    275 	idTypeInfo *				next;
    276 	bool						freeEventMap;
    277 	int							typeNum;
    278 	int							lastChild;
    279 
    280 	idHierarchy<idTypeInfo>		node;
    281 
    282 								idTypeInfo( const char *classname, const char *superclass, 
    283 												idEventFunc<idClass> *eventCallbacks, idClass *( *CreateInstance )(), void ( idClass::*Spawn )(),
    284 												void ( idClass::*Save )( idSaveGame *savefile ) const, void	( idClass::*Restore )( idRestoreGame *savefile ) );
    285 								~idTypeInfo();
    286 
    287 	void						Init();
    288 	void						Shutdown();
    289 
    290 	bool						IsType( const idTypeInfo &superclass ) const;
    291 	bool						RespondsTo( const idEventDef &ev ) const;
    292 };
    293 
    294 /*
    295 ================
    296 idTypeInfo::IsType
    297 
    298 Checks if the object's class is a subclass of the class defined by the 
    299 passed in idTypeInfo.
    300 ================
    301 */
    302 ID_INLINE bool idTypeInfo::IsType( const idTypeInfo &type ) const {
    303 	return ( ( typeNum >= type.typeNum ) && ( typeNum <= type.lastChild ) );
    304 }
    305 
    306 /*
    307 ================
    308 idTypeInfo::RespondsTo
    309 ================
    310 */
    311 ID_INLINE bool idTypeInfo::RespondsTo( const idEventDef &ev ) const {
    312 	assert( idEvent::initialized );
    313 	if ( !eventMap[ ev.GetEventNum() ] ) {
    314 		// we don't respond to this event
    315 		return false;
    316 	}
    317 
    318 	return true;
    319 }
    320 
    321 /*
    322 ================
    323 idClass::IsType
    324 
    325 Checks if the object's class is a subclass of the class defined by the 
    326 passed in idTypeInfo.
    327 ================
    328 */
    329 ID_INLINE bool idClass::IsType( const idTypeInfo &superclass ) const {
    330 	idTypeInfo *subclass;
    331 
    332 	subclass = GetType();
    333 	return subclass->IsType( superclass );
    334 }
    335 
    336 /*
    337 ================
    338 idClass::RespondsTo
    339 ================
    340 */
    341 ID_INLINE bool idClass::RespondsTo( const idEventDef &ev ) const {
    342 	const idTypeInfo *c;
    343 
    344 	assert( idEvent::initialized );
    345 	c = GetType();
    346 	return c->RespondsTo( ev );
    347 }
    348 
    349 #endif /* !__SYS_CLASS_H__ */