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__ */