diff --git a/include/QF/progs.h b/include/QF/progs.h index 7affaaf2a..764bfd05f 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -1157,8 +1157,7 @@ string_t PR_SetTempString(progs_t *pr, const char *s); \param a C string \param b C string \return string index of the progs string that represents the - concatenation - of strings a and b + concatenation of strings a and b */ string_t PR_CatStrings (progs_t *pr, const char *a, const char *b); @@ -1266,14 +1265,75 @@ void PR_Sprintf (progs_t *pr, struct dstring_s *result, const char *name, */ //@{ +/** Initialize the resource management fields. + + \param pr The VM of which the resource fields will be initialized. +*/ void PR_Resources_Init (progs_t *pr); + +/** Clear all resources before loading a new progs. + + Calls the clear() callback of all registered resources. + + \param pr The VM of which the resources will be cleared. +*/ void PR_Resources_Clear (progs_t *pr); + +/** Register a resource with a VM. + + \param pr The VM to which the resource will be associated. + \param name The name of the resource. Used for retrieving the + resource. + \param data The resource data. + callback. + \param clear Callback for performing any necessary cleanup. Called + by PR_Resources_Clear(). The parameters are the current + VM (\p pr) and \p data. + \note The name should be unique to the VM, but no checking is + done. If the name is not unique, the previous registered + resource will break. The name of the sub-system + registering the resource is a suitable name, and will + probably be unique. +*/ void PR_Resources_Register (progs_t *pr, const char *name, void *data, void (*clear)(progs_t *, void *)); + +/** Retrieve a resource registered with the VM. + + \param pr The VM from which the resource will be retrieved. + \param name The name of the resource. + \return The resource, or NULL if \p name does not match any + resource registered with the VM. +*/ void *PR_Resources_Find (progs_t *pr, const char *name); +/** \name Resource Map support + + These macros can be used to create functions for mapping C resources + to QuakeC integer handles. + + Valid handles are always negative. + + \note \p map is the resource map itself, not a pointer to the + resource map. +*/ +//@{ + +/** Type delcaration for the resource map. + + \param type The type of the resource. The size must be at least + as large as \c sizeof(type *). +*/ #define PR_RESMAP(type) struct { type *_free; type **_map; unsigned _size; } +/** Allocate a new resource from the resource map. + + \param type The type of the resource. Must match the \c type parameter + used for PR_RESMAP. + \param map The resource map. + \return A pointer to the new resource, or null if no more could + be allocated. +*/ #define PR_RESNEW(type,map) \ type *t; \ \ @@ -1297,11 +1357,27 @@ void *PR_Resources_Find (progs_t *pr, const char *name); memset (t, 0, sizeof (type)); \ return t +/** Free a resource returning it to the resource map. + + \param type The type of the resource. Must match the \c type parameter + used for PR_RESMAP. + \param map The resource map. + \param t Pointer to the resource to be freed. +*/ #define PR_RESFREE(type,map,t) \ memset (t, 0, sizeof (type)); \ *(type **) t = map._free; \ map._free = t +/** Free all resources in the resource map. + + Any memory allocated to the resource must be freed before freeing the + resource. + + \param type The type of the resource. Must match the \c type parameter + used for PR_RESMAP. + \param map The resource map. +*/ #define PR_RESRESET(type,map) \ unsigned i, j; \ if (!map._size) \ @@ -1315,6 +1391,13 @@ void *PR_Resources_Find (progs_t *pr, const char *name); } \ map._free = map._map[0]; +/** Retrieve a resource from the resource map using a handle. + + \param map The resource map. + \param col The handle. + \return A pointer to the resource, or NULL if the handle is + invalid. +*/ #define PR_RESGET(map,col) \ unsigned row = ~col / 1024; \ col = ~col % 1024; \ @@ -1322,6 +1405,12 @@ void *PR_Resources_Find (progs_t *pr, const char *name); return 0; \ return &map._map[row][col] +/** Convert a resource pointer to a handle. + + \param map The resource map. + \param ptr The resource pointer. + \return The handle or 0 if the pointer is invalid. +*/ #define PR_RESINDEX(map,ptr) \ unsigned i; \ for (i = 0; i < map._size; i++) { \ @@ -1330,6 +1419,7 @@ void *PR_Resources_Find (progs_t *pr, const char *name); return ~(i * 1024 + d); \ } \ return 0 +//@} //@} @@ -1401,9 +1491,9 @@ extern const char *pr_gametype; typedef struct strref_s strref_t; typedef struct { - pr_int_t s; - bfunction_t *f; - strref_t *tstr; + pr_int_t s; ///< Return statement. + bfunction_t *f; ///< Calling function. + strref_t *tstr; ///< Linked list of temporary strings. } prstack_t; struct obj_list_s; @@ -1438,15 +1528,23 @@ struct progs_s { struct memzone_s *zone; int zone_size; + /// \name builtin functions + //@{ struct hashtab_s *builtin_hash; struct hashtab_s *builtin_num_hash; unsigned bi_next; unsigned (*bi_map) (progs_t *pr, unsigned binum); + //@} + /// \name symbol management + //@{ struct hashtab_s *function_hash; struct hashtab_s *global_hash; struct hashtab_s *field_hash; + //@} + /// \name load hooks + //@{ int num_load_funcs; int max_load_funcs; pr_load_func_t **load_funcs; @@ -1457,7 +1555,10 @@ struct progs_s { int max_load_finish_funcs; pr_load_func_t **load_finish_funcs; //@} + //@} + /// \name string management + //@{ struct dstring_mem_s *ds_mem; strref_t *free_string_refs; strref_t *static_strings; @@ -1468,7 +1569,10 @@ struct progs_s { struct hashtab_s *strref_hash; int num_strings; strref_t *pr_xtstr; + //@} + /// \name memory map + //@{ dfunction_t *pr_functions; bfunction_t *function_table; char *pr_strings; @@ -1478,7 +1582,10 @@ struct progs_s { dstatement_t *pr_statements; pr_type_t *pr_globals; int globals_size; + //@} + /// \name parameter block + //@{ pr_type_t *pr_return; pr_type_t *pr_params[MAX_PARMS]; pr_type_t *pr_real_params[MAX_PARMS]; @@ -1486,11 +1593,14 @@ struct progs_s { pr_type_t *pr_saved_params; int pr_saved_argc; int pr_param_size; ///< covers both params and return + //@} int pr_edict_size; ///< in bytes int pr_edictareasize; ///< for bounds checking, starts at 0 func_t edict_parse; + /// \name execution state + //@{ int pr_argc; qboolean pr_trace; @@ -1503,11 +1613,15 @@ struct progs_s { int localstack[LOCALSTACK_SIZE]; int localstack_used; + //@} + /// \name resources + //@{ pr_resource_t *resources; struct hashtab_s *resource_hash; + //@} - /// obj info + /// \name obj info //@{ int selector_index; int selector_index_max; @@ -1523,7 +1637,7 @@ struct progs_s { struct obj_list_s *class_tree_list; //@} - /// debug info + /// \name debug info //@{ const char *debugfile; struct pr_debug_header_s *debug; @@ -1536,6 +1650,8 @@ struct progs_s { pr_type_t wp_val; //@} + /// \name globals and fields needed by the VM + //@{ struct { float *time; ///< required for OP_STATE pr_int_t *self; ///< required for OP_STATE @@ -1546,6 +1662,7 @@ struct progs_s { pr_int_t think; ///< required for OP_STATE pr_int_t this; ///< optional for entity<->object linking } fields; + //@} }; /** \addtogroup progs_data_access