]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/game/script/Script_Program.h
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / game / script / Script_Program.h
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
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.
13
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.
18
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/>.
21
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.
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 #ifndef __SCRIPT_PROGRAM_H__
30 #define __SCRIPT_PROGRAM_H__
31
32 class idScriptObject;
33 class idEventDef;
34 class idVarDef;
35 class idTypeDef;
36 class idEntity;
37 class idThread;
38 class idSaveGame;
39 class idRestoreGame;
40
41 #define MAX_STRING_LEN          128
42 #define MAX_GLOBALS                     196608                  // in bytes
43 #define MAX_STRINGS                     1024
44 #define MAX_FUNCS                       3072
45 #define MAX_STATEMENTS          81920                   // statement_t - 18 bytes last I checked
46
47 typedef enum {
48         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
49 } etype_t;
50
51 class function_t {
52 public:
53                                                 function_t();
54
55         size_t                          Allocated( void ) const;
56         void                            SetName( const char *name );
57         const char                      *Name( void ) const;
58         void                            Clear( void );
59
60 private:
61         idStr                           name;
62 public:
63         const idEventDef        *eventdef;
64         idVarDef                        *def;
65         const idTypeDef         *type;
66         int                             firstStatement;
67         int                             numStatements;
68         int                             parmTotal;
69         int                             locals;                         // total ints of parms + locals
70         int                                     filenum;                        // source file defined in
71         idList<int>                     parmSize;
72 };
73
74 typedef union eval_s {
75         const char                      *stringPtr;
76         float                           _float;
77         float                           vector[ 3 ];
78         function_t                      *function;
79         int                             _int;
80         int                             entity;
81 } eval_t;
82
83 /***********************************************************************
84
85 idTypeDef
86
87 Contains type information for variables and functions.
88
89 ***********************************************************************/
90
91 class idTypeDef {
92 private:
93         etype_t                                         type;
94         idStr                                           name;
95         int                                                     size;
96
97         // function types are more complex
98         idTypeDef                                       *auxType;                                       // return type
99         idList<idTypeDef *>                     parmTypes;
100         idStrList                                       parmNames;
101         idList<const function_t *>      functions;
102
103 public:
104         idVarDef                                        *def;                                           // a def that points to this type
105
106                                                 idTypeDef( const idTypeDef &other );
107                                                 idTypeDef( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
108         void                            operator=( const idTypeDef& other );
109         size_t                          Allocated( void ) const;
110
111         bool                            Inherits( const idTypeDef *basetype ) const;
112         bool                            MatchesType( const idTypeDef &matchtype ) const;
113         bool                            MatchesVirtualFunction( const idTypeDef &matchfunc ) const;
114         void                            AddFunctionParm( idTypeDef *parmtype, const char *name );
115         void                            AddField( idTypeDef *fieldtype, const char *name );
116
117         void                            SetName( const char *newname );
118         const char                      *Name( void ) const;
119
120         etype_t                         Type( void ) const;
121         int                                     Size( void ) const;
122
123         idTypeDef                       *SuperClass( void ) const;
124         
125         idTypeDef                       *ReturnType( void ) const;
126         void                            SetReturnType( idTypeDef *type );
127
128         idTypeDef                       *FieldType( void ) const;
129         void                            SetFieldType( idTypeDef *type );
130
131         idTypeDef                       *PointerType( void ) const;
132         void                            SetPointerType( idTypeDef *type );
133
134         int                                     NumParameters( void ) const;
135         idTypeDef                       *GetParmType( int parmNumber ) const;
136         const char                      *GetParmName( int parmNumber ) const;
137
138         int                                     NumFunctions( void ) const;
139         int                                     GetFunctionNumber( const function_t *func ) const;
140         const function_t        *GetFunction( int funcNumber ) const;
141         void                            AddFunction( const function_t *func );
142 };
143
144 /***********************************************************************
145
146 idScriptObject
147
148 In-game representation of objects in scripts.  Use the idScriptVariable template
149 (below) to access variables.
150
151 ***********************************************************************/
152
153 class idScriptObject {
154 private:
155         idTypeDef                                       *type;
156         
157 public:
158         byte                                            *data;
159
160                                                                 idScriptObject();
161                                                                 ~idScriptObject();
162
163         void                                            Save( idSaveGame *savefile ) const;                     // archives object for save game file
164         void                                            Restore( idRestoreGame *savefile );                     // unarchives object from save game file
165
166         void                                            Free( void );
167         bool                                            SetType( const char *typeName );
168         void                                            ClearObject( void );
169         bool                                            HasObject( void ) const;
170         idTypeDef                                       *GetTypeDef( void ) const;
171         const char                                      *GetTypeName( void ) const;
172         const function_t                        *GetConstructor( void ) const;
173         const function_t                        *GetDestructor( void ) const;
174         const function_t                        *GetFunction( const char *name ) const;
175
176         byte                                            *GetVariable( const char *name, etype_t etype ) const;
177 };
178
179 /***********************************************************************
180
181 idScriptVariable
182
183 Helper template that handles looking up script variables stored in objects.
184 If the specified variable doesn't exist, or is the wrong data type, idScriptVariable
185 will cause an error.
186
187 ***********************************************************************/
188
189 template<class type, etype_t etype, class returnType>
190 class idScriptVariable {
191 private:
192         type                            *data;
193
194 public:
195                                                 idScriptVariable();
196         bool                            IsLinked( void ) const;
197         void                            Unlink( void );
198         void                            LinkTo( idScriptObject &obj, const char *name );
199         idScriptVariable        &operator=( const returnType &value );
200                                                 operator returnType() const;
201 };
202
203 template<class type, etype_t etype, class returnType>
204 ID_INLINE idScriptVariable<type, etype, returnType>::idScriptVariable() {
205         data = NULL;
206 }
207
208 template<class type, etype_t etype, class returnType>
209 ID_INLINE bool idScriptVariable<type, etype, returnType>::IsLinked( void ) const {
210         return ( data != NULL );
211 }
212
213 template<class type, etype_t etype, class returnType>
214 ID_INLINE void idScriptVariable<type, etype, returnType>::Unlink( void ) {
215         data = NULL;
216 }
217
218 template<class type, etype_t etype, class returnType>
219 ID_INLINE void idScriptVariable<type, etype, returnType>::LinkTo( idScriptObject &obj, const char *name ) {
220         data = ( type * )obj.GetVariable( name, etype );
221         if ( !data ) {
222                 gameError( "Missing '%s' field in script object '%s'", name, obj.GetTypeName() );
223         }
224 }
225
226 template<class type, etype_t etype, class returnType>
227 ID_INLINE idScriptVariable<type, etype, returnType> &idScriptVariable<type, etype, returnType>::operator=( const returnType &value ) {
228         // check if we attempt to access the object before it's been linked
229         assert( data );
230
231         // make sure we don't crash if we don't have a pointer
232         if ( data ) {
233                 *data = ( type )value;
234         }
235         return *this;
236 }
237
238 template<class type, etype_t etype, class returnType>
239 ID_INLINE idScriptVariable<type, etype, returnType>::operator returnType() const {
240         // check if we attempt to access the object before it's been linked
241         assert( data );
242
243         // make sure we don't crash if we don't have a pointer
244         if ( data ) {
245                 return ( const returnType )*data;
246         } else {
247                 // reasonably safe value
248                 return ( const returnType )0;
249         }
250 }
251
252 /***********************************************************************
253
254 Script object variable access template instantiations
255
256 These objects will automatically handle looking up of the current value
257 of a variable in a script object.  They can be stored as part of a class
258 for up-to-date values of the variable, or can be used in functions to
259 sample the data for non-dynamic values.
260
261 ***********************************************************************/
262
263 typedef idScriptVariable<int, ev_boolean, int>                          idScriptBool;
264 typedef idScriptVariable<float, ev_float, float>                        idScriptFloat;
265 typedef idScriptVariable<float, ev_float, int>                          idScriptInt;
266 typedef idScriptVariable<idVec3, ev_vector, idVec3>                     idScriptVector;
267 typedef idScriptVariable<idStr, ev_string, const char *>        idScriptString;
268
269 /***********************************************************************
270
271 idCompileError
272
273 Causes the compiler to exit out of compiling the current function and
274 display an error message with line and file info.
275
276 ***********************************************************************/
277
278 class idCompileError : public idException {
279 public:
280         idCompileError( const char *text ) : idException( text ) {}
281 };
282
283 /***********************************************************************
284
285 idVarDef
286
287 Define the name, type, and location of variables, functions, and objects
288 defined in script.
289
290 ***********************************************************************/
291
292 typedef union varEval_s {
293         idScriptObject                  **objectPtrPtr;
294         char                                    *stringPtr;
295         float                                   *floatPtr;
296         idVec3                                  *vectorPtr;
297         function_t                              *functionPtr;
298         int                                     *intPtr;
299         byte                                    *bytePtr;
300         int                                     *entityNumberPtr;
301         int                                             virtualFunction;
302         int                                             jumpOffset;
303         int                                             stackOffset;            // offset in stack for local variables
304         int                                             argSize;
305         varEval_s                               *evalPtr;
306         int                                             ptrOffset;
307 } varEval_t;
308
309 class idVarDefName;
310
311 class idVarDef {
312         friend class idVarDefName;
313
314 public:
315         int                                             num;
316         varEval_t                               value;
317         idVarDef *                              scope;                  // function, namespace, or object the var was defined in
318         int                                             numUsers;               // number of users if this is a constant
319
320         typedef enum {
321                 uninitialized, initializedVariable, initializedConstant, stackVariable
322         } initialized_t;
323
324         initialized_t                   initialized;
325
326 public:
327                                                         idVarDef( idTypeDef *typeptr = NULL );
328                                                         ~idVarDef();
329
330         const char *                    Name( void ) const;
331         const char *                    GlobalName( void ) const;
332
333         void                                    SetTypeDef( idTypeDef *_type ) { typeDef = _type; }
334         idTypeDef *                             TypeDef( void ) const { return typeDef; }
335         etype_t                                 Type( void ) const { return ( typeDef != NULL ) ? typeDef->Type() : ev_void; }
336
337         int                                             DepthOfScope( const idVarDef *otherScope ) const;
338
339         void                                    SetFunction( function_t *func );
340         void                                    SetObject( idScriptObject *object );
341         void                                    SetValue( const eval_t &value, bool constant );
342         void                                    SetString( const char *string, bool constant );
343
344         idVarDef *                              Next( void ) const { return next; }             // next var def with same name
345
346         void                                    PrintInfo( idFile *file, int instructionPointer ) const;
347
348 private:
349         idTypeDef *                             typeDef;
350         idVarDefName *                  name;           // name of this var
351         idVarDef *                              next;           // next var with the same name
352 };
353
354 /***********************************************************************
355
356   idVarDefName
357
358 ***********************************************************************/
359
360 class idVarDefName {
361 public:
362                                                         idVarDefName( void ) { defs = NULL; }
363                                                         idVarDefName( const char *n ) { name = n; defs = NULL; }
364
365         const char *                    Name( void ) const { return name; }
366         idVarDef *                              GetDefs( void ) const { return defs; }
367
368         void                                    AddDef( idVarDef *def );
369         void                                    RemoveDef( idVarDef *def );
370
371 private:
372         idStr                                   name;
373         idVarDef *                              defs;
374 };
375
376 /***********************************************************************
377
378   Variable and type defintions
379
380 ***********************************************************************/
381
382 extern  idTypeDef       type_void;
383 extern  idTypeDef       type_scriptevent;
384 extern  idTypeDef       type_namespace;
385 extern  idTypeDef       type_string;
386 extern  idTypeDef       type_float;
387 extern  idTypeDef       type_vector;
388 extern  idTypeDef       type_entity;
389 extern  idTypeDef       type_field;
390 extern  idTypeDef       type_function;
391 extern  idTypeDef       type_virtualfunction;
392 extern  idTypeDef       type_pointer;
393 extern  idTypeDef       type_object;
394 extern  idTypeDef       type_jumpoffset;        // only used for jump opcodes
395 extern  idTypeDef       type_argsize;           // only used for function call and thread opcodes
396 extern  idTypeDef       type_boolean;
397
398 extern  idVarDef        def_void;
399 extern  idVarDef        def_scriptevent;
400 extern  idVarDef        def_namespace;
401 extern  idVarDef        def_string;
402 extern  idVarDef        def_float;
403 extern  idVarDef        def_vector;
404 extern  idVarDef        def_entity;
405 extern  idVarDef        def_field;
406 extern  idVarDef        def_function;
407 extern  idVarDef        def_virtualfunction;
408 extern  idVarDef        def_pointer;
409 extern  idVarDef        def_object;
410 extern  idVarDef        def_jumpoffset;         // only used for jump opcodes
411 extern  idVarDef        def_argsize;            // only used for function call and thread opcodes
412 extern  idVarDef        def_boolean;
413
414 typedef struct statement_s {
415         unsigned short  op;
416         idVarDef                *a;
417         idVarDef                *b;
418         idVarDef                *c;
419         unsigned short  linenumber;
420         unsigned short  file;
421 } statement_t;
422
423 /***********************************************************************
424
425 idProgram
426
427 Handles compiling and storage of script data.  Multiple idProgram objects
428 would represent seperate programs with no knowledge of each other.  Scripts
429 meant to access shared data and functions should all be compiled by a
430 single idProgram.
431
432 ***********************************************************************/
433
434 class idProgram {
435 private:
436         idStrList                                                                       fileList;
437         idStr                                                                           filename;
438         int                                                                                     filenum;
439
440         int                                                                                     numVariables;
441         byte                                                                            variables[ MAX_GLOBALS ];
442         idStaticList<byte,MAX_GLOBALS>                          variableDefaults;
443         idStaticList<function_t,MAX_FUNCS>                      functions;
444         idStaticList<statement_t,MAX_STATEMENTS>        statements;
445         idList<idTypeDef *>                                                     types;
446         idList<idVarDefName *>                                          varDefNames;
447         idHashIndex                                                                     varDefNameHash;
448         idList<idVarDef *>                                                      varDefs;
449
450         idVarDef                                                                        *sysDef;
451
452         int                                                                                     top_functions;
453         int                                                                                     top_statements;
454         int                                                                                     top_types;
455         int                                                                                     top_defs;
456         int                                                                                     top_files;
457
458         void                                                                            CompileStats( void );
459
460 public:
461         idVarDef                                                                        *returnDef;
462         idVarDef                                                                        *returnStringDef;
463
464                                                                                                 idProgram();
465                                                                                                 ~idProgram();
466
467         // save games
468         void                                                                            Save( idSaveGame *savefile ) const;
469         bool                                                                            Restore( idRestoreGame *savefile );
470         int                                                                                     CalculateChecksum( void ) const;                // Used to insure program code has not
471                                                                                                                                                                                 //    changed between savegames
472
473         void                                                                            Startup( const char *defaultScript );
474         void                                                                            Restart( void );
475         bool                                                                            CompileText( const char *source, const char *text, bool console );
476         const function_t                                                        *CompileFunction( const char *functionName, const char *text );
477         void                                                                            CompileFile( const char *filename );
478         void                                                                            BeginCompilation( void );
479         void                                                                            FinishCompilation( void );
480         void                                                                            DisassembleStatement( idFile *file, int instructionPointer ) const;
481         void                                                                            Disassemble( void ) const;
482         void                                                                            FreeData( void );
483
484         const char                                                                      *GetFilename( int num );
485         int                                                                                     GetFilenum( const char *name );
486         int                                                                                     GetLineNumberForStatement( int index );
487         const char                                                                      *GetFilenameForStatement( int index );
488
489         idTypeDef                                                                       *AllocType( idTypeDef &type );
490         idTypeDef                                                                       *AllocType( etype_t etype, idVarDef *edef, const char *ename, int esize, idTypeDef *aux );
491         idTypeDef                                                                       *GetType( idTypeDef &type, bool allocate );
492         idTypeDef                                                                       *FindType( const char *name );
493
494         idVarDef                                                                        *AllocDef( idTypeDef *type, const char *name, idVarDef *scope, bool constant );
495         idVarDef                                                                        *GetDef( const idTypeDef *type, const char *name, const idVarDef *scope ) const;
496         void                                                                            FreeDef( idVarDef *d, const idVarDef *scope );
497         idVarDef                                                                        *FindFreeResultDef( idTypeDef *type, const char *name, idVarDef *scope, const idVarDef *a, const idVarDef *b );
498         idVarDef                                                                        *GetDefList( const char *name ) const;
499         void                                                                            AddDefToNameList( idVarDef *def, const char *name );
500
501         function_t                                                                      *FindFunction( const char *name ) const;                                                // returns NULL if function not found
502         function_t                                                                      *FindFunction( const char *name, const idTypeDef *type ) const; // returns NULL if function not found
503         function_t                                                                      &AllocFunction( idVarDef *def );
504         function_t                                                                      *GetFunction( int index );
505         int                                                                                     GetFunctionIndex( const function_t *func );
506
507         void                                                                            SetEntity( const char *name, idEntity *ent );
508
509         statement_t                                                                     *AllocStatement( void );
510         statement_t                                                                     &GetStatement( int index );
511         int                                                                                     NumStatements( void ) { return statements.Num(); }
512
513         int                                                                             GetReturnedInteger( void );
514
515         void                                                                            ReturnFloat( float value );
516         void                                                                            ReturnInteger( int value );
517         void                                                                            ReturnVector( idVec3 const &vec );
518         void                                                                            ReturnString( const char *string );
519         void                                                                            ReturnEntity( idEntity *ent );
520         
521         int                                                                                     NumFilenames( void ) { return fileList.Num( ); }
522 };
523
524 /*
525 ================
526 idProgram::GetStatement
527 ================
528 */
529 ID_INLINE statement_t &idProgram::GetStatement( int index ) {
530         return statements[ index ];
531 }
532
533 /*
534 ================
535 idProgram::GetFunction
536 ================
537 */
538 ID_INLINE function_t *idProgram::GetFunction( int index ) {
539         return &functions[ index ];
540 }
541
542 /*
543 ================
544 idProgram::GetFunctionIndex
545 ================
546 */
547 ID_INLINE int idProgram::GetFunctionIndex( const function_t *func ) {
548         return func - &functions[0];
549 }
550
551 /*
552 ================
553 idProgram::GetReturnedInteger
554 ================
555 */
556 ID_INLINE int idProgram::GetReturnedInteger( void ) {
557         return *returnDef->value.intPtr;
558 }
559
560 /*
561 ================
562 idProgram::ReturnFloat
563 ================
564 */
565 ID_INLINE void idProgram::ReturnFloat( float value ) {
566         *returnDef->value.floatPtr = value;
567 }
568
569 /*
570 ================
571 idProgram::ReturnInteger
572 ================
573 */
574 ID_INLINE void idProgram::ReturnInteger( int value ) {
575         *returnDef->value.intPtr = value;
576 }
577
578 /*
579 ================
580 idProgram::ReturnVector
581 ================
582 */
583 ID_INLINE void idProgram::ReturnVector( idVec3 const &vec ) {
584         *returnDef->value.vectorPtr = vec;
585 }
586
587 /*
588 ================
589 idProgram::ReturnString
590 ================
591 */
592 ID_INLINE void idProgram::ReturnString( const char *string ) {
593         idStr::Copynz( returnStringDef->value.stringPtr, string, MAX_STRING_LEN );
594 }
595
596 /*
597 ================
598 idProgram::GetFilename
599 ================
600 */
601 ID_INLINE const char *idProgram::GetFilename( int num ) {
602         return fileList[ num ];
603 }
604
605 /*
606 ================
607 idProgram::GetLineNumberForStatement
608 ================
609 */
610 ID_INLINE int idProgram::GetLineNumberForStatement( int index ) {
611         return statements[ index ].linenumber;
612 }
613
614 /*
615 ================
616 idProgram::GetFilenameForStatement
617 ================
618 */
619 ID_INLINE const char *idProgram::GetFilenameForStatement( int index ) {
620         return GetFilename( statements[ index ].file );
621 }
622
623 #endif /* !__SCRIPT_PROGRAM_H__ */