Class.h 14 KB

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