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 ===========================================================================
29 #ifndef __SCRIPT_PROGRAM_H__
30 #define __SCRIPT_PROGRAM_H__
41 #define MAX_STRING_LEN 128
43 #define MAX_GLOBALS 296608 // in bytes
45 #define MAX_GLOBALS 196608 // in bytes
47 #define MAX_STRINGS 1024
50 #define MAX_FUNCS 3584
52 #define MAX_FUNCS 3072
56 #define MAX_STATEMENTS 131072 // statement_t - 18 bytes last I checked
58 #define MAX_STATEMENTS 81920 // statement_t - 18 bytes last I checked
62 ev_error = -1, ev_void, ev_scriptevent, ev_namespace, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_virtualfunction, ev_pointer, ev_object, ev_jumpoffset, ev_argsize, ev_boolean
69 size_t Allocated( void ) const;
70 void SetName( const char *name );
71 const char *Name( void ) const;
77 const idEventDef *eventdef;
79 const idTypeDef *type;
83 int locals; // total ints of parms + locals
84 int filenum; // source file defined in
88 typedef union eval_s {
89 const char *stringPtr;
97 /***********************************************************************
101 Contains type information for variables and functions.
103 ***********************************************************************/
111 // function types are more complex
112 idTypeDef *auxType; // return type
113 idList<idTypeDef *> parmTypes;
115 idList<const function_t *> functions;
118 idVarDef *def; // a def that points to this type
120 idTypeDef( const idTypeDef &other );
121 idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
122 void operator=( const idTypeDef& other );
123 size_t Allocated( void ) const;
125 bool Inherits( const idTypeDef *basetype ) const;
126 bool MatchesType( const idTypeDef &matchtype ) const;
127 bool MatchesVirtualFunction( const idTypeDef &matchfunc ) const;
128 void AddFunctionParm( idTypeDef *parmtype, const char *name );
129 void AddField( idTypeDef *fieldtype, const char *name );
131 void SetName( const char *newname );
132 const char *Name( void ) const;
134 etype_t Type( void ) const;
135 int Size( void ) const;
137 idTypeDef *SuperClass( void ) const;
139 idTypeDef *ReturnType( void ) const;
140 void SetReturnType( idTypeDef *type );
142 idTypeDef *FieldType( void ) const;
143 void SetFieldType( idTypeDef *type );
145 idTypeDef *PointerType( void ) const;
146 void SetPointerType( idTypeDef *type );
148 int NumParameters( void ) const;
149 idTypeDef *GetParmType( int parmNumber ) const;
150 const char *GetParmName( int parmNumber ) const;
152 int NumFunctions( void ) const;
153 int GetFunctionNumber( const function_t *func ) const;
154 const function_t *GetFunction( int funcNumber ) const;
155 void AddFunction( const function_t *func );
158 /***********************************************************************
162 In-game representation of objects in scripts. Use the idScriptVariable template
163 (below) to access variables.
165 ***********************************************************************/
167 class idScriptObject {
177 void Save( idSaveGame *savefile ) const; // archives object for save game file
178 void Restore( idRestoreGame *savefile ); // unarchives object from save game file
181 bool SetType( const char *typeName );
182 void ClearObject( void );
183 bool HasObject( void ) const;
184 idTypeDef *GetTypeDef( void ) const;
185 const char *GetTypeName( void ) const;
186 const function_t *GetConstructor( void ) const;
187 const function_t *GetDestructor( void ) const;
188 const function_t *GetFunction( const char *name ) const;
190 byte *GetVariable( const char *name, etype_t etype ) const;
193 /***********************************************************************
197 Helper template that handles looking up script variables stored in objects.
198 If the specified variable doesn't exist, or is the wrong data type, idScriptVariable
201 ***********************************************************************/
203 template<class type, etype_t etype, class returnType>
204 class idScriptVariable {
210 bool IsLinked( void ) const;
212 void LinkTo( idScriptObject &obj, const char *name );
213 idScriptVariable &operator=( const returnType &value );
214 operator returnType() const;
217 template<class type, etype_t etype, class returnType>
218 ID_INLINE idScriptVariable<type, etype, returnType>::idScriptVariable() {
222 template<class type, etype_t etype, class returnType>
223 ID_INLINE bool idScriptVariable<type, etype, returnType>::IsLinked( void ) const {
224 return ( data != NULL );
227 template<class type, etype_t etype, class returnType>
228 ID_INLINE void idScriptVariable<type, etype, returnType>::Unlink( void ) {
232 template<class type, etype_t etype, class returnType>
233 ID_INLINE void idScriptVariable<type, etype, returnType>::LinkTo( idScriptObject &obj, const char *name ) {
234 data = ( type * )obj.GetVariable( name, etype );
236 gameError( "Missing '%s' field in script object '%s'", name, obj.GetTypeName() );
240 template<class type, etype_t etype, class returnType>
241 ID_INLINE idScriptVariable<type, etype, returnType> &idScriptVariable<type, etype, returnType>::operator=( const returnType &value ) {
242 // check if we attempt to access the object before it's been linked
245 // make sure we don't crash if we don't have a pointer
247 *data = ( type )value;
252 template<class type, etype_t etype, class returnType>
253 ID_INLINE idScriptVariable<type, etype, returnType>::operator returnType() const {
254 // check if we attempt to access the object before it's been linked
257 // make sure we don't crash if we don't have a pointer
259 return ( const returnType )*data;
261 // reasonably safe value
262 return ( const returnType )0;
266 /***********************************************************************
268 Script object variable access template instantiations
270 These objects will automatically handle looking up of the current value
271 of a variable in a script object. They can be stored as part of a class
272 for up-to-date values of the variable, or can be used in functions to
273 sample the data for non-dynamic values.
275 ***********************************************************************/
277 typedef idScriptVariable<int, ev_boolean, int> idScriptBool;
278 typedef idScriptVariable<float, ev_float, float> idScriptFloat;
279 typedef idScriptVariable<float, ev_float, int> idScriptInt;
280 typedef idScriptVariable<idVec3, ev_vector, idVec3> idScriptVector;
281 typedef idScriptVariable<idStr, ev_string, const char *> idScriptString;
283 /***********************************************************************
287 Causes the compiler to exit out of compiling the current function and
288 display an error message with line and file info.
290 ***********************************************************************/
292 class idCompileError : public idException {
294 idCompileError( const char *text ) : idException( text ) {}
297 /***********************************************************************
301 Define the name, type, and location of variables, functions, and objects
304 ***********************************************************************/
306 typedef union varEval_s {
307 idScriptObject **objectPtrPtr;
311 function_t *functionPtr;
314 int *entityNumberPtr;
317 int stackOffset; // offset in stack for local variables
326 friend class idVarDefName;
331 idVarDef * scope; // function, namespace, or object the var was defined in
332 int numUsers; // number of users if this is a constant
335 uninitialized, initializedVariable, initializedConstant, stackVariable
338 initialized_t initialized;
341 idVarDef( idTypeDef *typeptr = NULL );
344 const char * Name( void ) const;
345 const char * GlobalName( void ) const;
347 void SetTypeDef( idTypeDef *_type ) { typeDef = _type; }
348 idTypeDef * TypeDef( void ) const { return typeDef; }
349 etype_t Type( void ) const { return ( typeDef != NULL ) ? typeDef->Type() : ev_void; }
351 int DepthOfScope( const idVarDef *otherScope ) const;
353 void SetFunction( function_t *func );
354 void SetObject( idScriptObject *object );
355 void SetValue( const eval_t &value, bool constant );
356 void SetString( const char *string, bool constant );
358 idVarDef * Next( void ) const { return next; } // next var def with same name
360 void PrintInfo( idFile *file, int instructionPointer ) const;
364 idVarDefName * name; // name of this var
365 idVarDef * next; // next var with the same name
368 /***********************************************************************
372 ***********************************************************************/
376 idVarDefName( void ) { defs = NULL; }
377 idVarDefName( const char *n ) { name = n; defs = NULL; }
379 const char * Name( void ) const { return name; }
380 idVarDef * GetDefs( void ) const { return defs; }
382 void AddDef( idVarDef *def );
383 void RemoveDef( idVarDef *def );
390 /***********************************************************************
392 Variable and type defintions
394 ***********************************************************************/
396 extern idTypeDef type_void;
397 extern idTypeDef type_scriptevent;
398 extern idTypeDef type_namespace;
399 extern idTypeDef type_string;
400 extern idTypeDef type_float;
401 extern idTypeDef type_vector;
402 extern idTypeDef type_entity;
403 extern idTypeDef type_field;
404 extern idTypeDef type_function;
405 extern idTypeDef type_virtualfunction;
406 extern idTypeDef type_pointer;
407 extern idTypeDef type_object;
408 extern idTypeDef type_jumpoffset; // only used for jump opcodes
409 extern idTypeDef type_argsize; // only used for function call and thread opcodes
410 extern idTypeDef type_boolean;
412 extern idVarDef def_void;
413 extern idVarDef def_scriptevent;
414 extern idVarDef def_namespace;
415 extern idVarDef def_string;
416 extern idVarDef def_float;
417 extern idVarDef def_vector;
418 extern idVarDef def_entity;
419 extern idVarDef def_field;
420 extern idVarDef def_function;
421 extern idVarDef def_virtualfunction;
422 extern idVarDef def_pointer;
423 extern idVarDef def_object;
424 extern idVarDef def_jumpoffset; // only used for jump opcodes
425 extern idVarDef def_argsize; // only used for function call and thread opcodes
426 extern idVarDef def_boolean;
428 typedef struct statement_s {
433 unsigned short linenumber;
437 /***********************************************************************
441 Handles compiling and storage of script data. Multiple idProgram objects
442 would represent seperate programs with no knowledge of each other. Scripts
443 meant to access shared data and functions should all be compiled by a
446 ***********************************************************************/
455 byte variables[ MAX_GLOBALS ];
456 idStaticList<byte,MAX_GLOBALS> variableDefaults;
457 idStaticList<function_t,MAX_FUNCS> functions;
458 idStaticList<statement_t,MAX_STATEMENTS> statements;
459 idList<idTypeDef *> types;
460 idList<idVarDefName *> varDefNames;
461 idHashIndex varDefNameHash;
462 idList<idVarDef *> varDefs;
472 void CompileStats( void );
476 idVarDef *returnStringDef;
482 void Save( idSaveGame *savefile ) const;
483 bool Restore( idRestoreGame *savefile );
484 int CalculateChecksum( void ) const; // Used to insure program code has not
485 // changed between savegames
487 void Startup( const char *defaultScript );
488 void Restart( void );
489 bool CompileText( const char *source, const char *text, bool console );
490 const function_t *CompileFunction( const char *functionName, const char *text );
491 void CompileFile( const char *filename );
492 void BeginCompilation( void );
493 void FinishCompilation( void );
494 void DisassembleStatement( idFile *file, int instructionPointer ) const;
495 void Disassemble( void ) const;
496 void FreeData( void );
498 const char *GetFilename( int num );
499 int GetFilenum( const char *name );
500 int GetLineNumberForStatement( int index );
501 const char *GetFilenameForStatement( int index );
503 idTypeDef *AllocType( idTypeDef &type );
504 idTypeDef *AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
505 idTypeDef *GetType( idTypeDef &type, bool allocate );
506 idTypeDef *FindType( const char *name );
508 idVarDef *AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant );
509 idVarDef *GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const;
510 void FreeDef( idVarDef *d, const idVarDef *scope );
511 idVarDef *FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b );
512 idVarDef *GetDefList( const char *name ) const;
513 void AddDefToNameList( idVarDef *def, const char *name );
515 function_t *FindFunction( const char *name ) const; // returns NULL if function not found
516 function_t *FindFunction( const char *name, const idTypeDef *type ) const; // returns NULL if function not found
517 function_t &AllocFunction( idVarDef *def );
518 function_t *GetFunction( int index );
519 int GetFunctionIndex( const function_t *func );
521 void SetEntity( const char *name, idEntity *ent );
523 statement_t *AllocStatement( void );
524 statement_t &GetStatement( int index );
525 int NumStatements( void ) { return statements.Num(); }
527 int GetReturnedInteger( void );
529 void ReturnFloat( float value );
530 void ReturnInteger( int value );
531 void ReturnVector( idVec3 const &vec );
532 void ReturnString( const char *string );
533 void ReturnEntity( idEntity *ent );
535 int NumFilenames( void ) { return fileList.Num( ); }
540 idProgram::GetStatement
543 ID_INLINE statement_t &idProgram::GetStatement( int index ) {
544 return statements[ index ];
549 idProgram::GetFunction
552 ID_INLINE function_t *idProgram::GetFunction( int index ) {
553 return &functions[ index ];
558 idProgram::GetFunctionIndex
561 ID_INLINE int idProgram::GetFunctionIndex( const function_t *func ) {
562 return func - &functions[0];
567 idProgram::GetReturnedInteger
570 ID_INLINE int idProgram::GetReturnedInteger( void ) {
571 return *returnDef->value.intPtr;
576 idProgram::ReturnFloat
579 ID_INLINE void idProgram::ReturnFloat( float value ) {
580 *returnDef->value.floatPtr = value;
585 idProgram::ReturnInteger
588 ID_INLINE void idProgram::ReturnInteger( int value ) {
589 *returnDef->value.intPtr = value;
594 idProgram::ReturnVector
597 ID_INLINE void idProgram::ReturnVector( idVec3 const &vec ) {
598 *returnDef->value.vectorPtr = vec;
603 idProgram::ReturnString
606 ID_INLINE void idProgram::ReturnString( const char *string ) {
607 idStr::Copynz( returnStringDef->value.stringPtr, string, MAX_STRING_LEN );
612 idProgram::GetFilename
615 ID_INLINE const char *idProgram::GetFilename( int num ) {
616 return fileList[ num ];
621 idProgram::GetLineNumberForStatement
624 ID_INLINE int idProgram::GetLineNumberForStatement( int index ) {
625 return statements[ index ].linenumber;
630 idProgram::GetFilenameForStatement
633 ID_INLINE const char *idProgram::GetFilenameForStatement( int index ) {
634 return GetFilename( statements[ index ].file );
637 #endif /* !__SCRIPT_PROGRAM_H__ */