mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
use a cycled pool of "return strings". I'd love to come up with something
better, but this will do (similar to what qwe does, but qf style:)
This commit is contained in:
parent
8d42963c4d
commit
e455b760ca
5 changed files with 53 additions and 11 deletions
|
@ -160,7 +160,7 @@ qboolean PR_EdictValid (progs_t *pr, int e);
|
||||||
#define R_FUNCTION(p) R_var (p, func)
|
#define R_FUNCTION(p) R_var (p, func)
|
||||||
#define R_POINTER(p) R_var (p, pointer)
|
#define R_POINTER(p) R_var (p, pointer)
|
||||||
|
|
||||||
#define RETURN_STRING(p, s) (R_STRING (p) = PR_SetTempString((p), s))
|
#define RETURN_STRING(p, s) (R_STRING (p) = PR_SetReturnString((p), s))
|
||||||
#define RETURN_EDICT(p, e) (R_STRING (p) = EDICT_TO_PROG(p, e))
|
#define RETURN_EDICT(p, e) (R_STRING (p) = EDICT_TO_PROG(p, e))
|
||||||
#define RETURN_POINTER(pr,p) (R_POINTER (pr) = POINTER_TO_PROG (pr, p))
|
#define RETURN_POINTER(pr,p) (R_POINTER (pr) = POINTER_TO_PROG (pr, p))
|
||||||
#define RETURN_VECTOR(p, v) (VectorCopy (v, R_VECTOR (p)))
|
#define RETURN_VECTOR(p, v) (VectorCopy (v, R_VECTOR (p)))
|
||||||
|
@ -251,9 +251,11 @@ qboolean PR_StringValid (progs_t *pr, int num);
|
||||||
const char *PR_GetString(progs_t *pr, int num);
|
const char *PR_GetString(progs_t *pr, int num);
|
||||||
struct dstring_s *PR_GetDString(progs_t *pr, int num);
|
struct dstring_s *PR_GetDString(progs_t *pr, int num);
|
||||||
int PR_SetString(progs_t *pr, const char *s);
|
int PR_SetString(progs_t *pr, const char *s);
|
||||||
|
int PR_SetReturnString(progs_t *pr, const char *s);
|
||||||
int PR_SetTempString(progs_t *pr, const char *s);
|
int PR_SetTempString(progs_t *pr, const char *s);
|
||||||
void PR_MakeTempString(progs_t *pr, int str);
|
void PR_MakeTempString(progs_t *pr, int str);
|
||||||
int PR_NewString (progs_t *pr);
|
int PR_NewString (progs_t *pr);
|
||||||
|
void PR_ClearReturnStrings (progs_t *pr);
|
||||||
void PR_FreeString (progs_t *pr, int str);
|
void PR_FreeString (progs_t *pr, int str);
|
||||||
void PR_FreeTempStrings (progs_t *pr);
|
void PR_FreeTempStrings (progs_t *pr);
|
||||||
void PR_Sprintf (progs_t *pr, struct dstring_s *result, const char *name,
|
void PR_Sprintf (progs_t *pr, struct dstring_s *result, const char *name,
|
||||||
|
@ -313,6 +315,7 @@ void PR_Cmds_Init (progs_t *pr);
|
||||||
|
|
||||||
#define MAX_STACK_DEPTH 64
|
#define MAX_STACK_DEPTH 64
|
||||||
#define LOCALSTACK_SIZE 4096
|
#define LOCALSTACK_SIZE 4096
|
||||||
|
#define PR_RS_SLOTS 16
|
||||||
|
|
||||||
typedef struct strref_s strref_t;
|
typedef struct strref_s strref_t;
|
||||||
|
|
||||||
|
@ -346,6 +349,8 @@ struct progs_s {
|
||||||
struct dstring_mem_s *ds_mem;
|
struct dstring_mem_s *ds_mem;
|
||||||
strref_t *static_strings;
|
strref_t *static_strings;
|
||||||
strref_t **dynamic_strings;
|
strref_t **dynamic_strings;
|
||||||
|
strref_t *return_strings[PR_RS_SLOTS];
|
||||||
|
int rs_slot;
|
||||||
unsigned dyn_str_size;
|
unsigned dyn_str_size;
|
||||||
struct hashtab_s *strref_hash;
|
struct hashtab_s *strref_hash;
|
||||||
int num_strings;
|
int num_strings;
|
||||||
|
|
|
@ -422,8 +422,9 @@ ED_Print (progs_t *pr, edict_t *ed)
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case ev_string:
|
case ev_string:
|
||||||
if (!PR_GetString (pr, v->string_var)[0])
|
if (PR_StringValid (pr, v->string_var))
|
||||||
continue;
|
if (!PR_GetString (pr, v->string_var)[0])
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
case ev_float:
|
case ev_float:
|
||||||
if (!v->float_var)
|
if (!v->float_var)
|
||||||
|
|
|
@ -171,6 +171,7 @@ PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts, int zone)
|
||||||
pr->free_progs_mem = free_progs_mem;
|
pr->free_progs_mem = free_progs_mem;
|
||||||
|
|
||||||
PR_Resources_Clear (pr);
|
PR_Resources_Clear (pr);
|
||||||
|
PR_ClearReturnStrings (pr);
|
||||||
if (pr->progs)
|
if (pr->progs)
|
||||||
pr->free_progs_mem (pr, pr->progs);
|
pr->free_progs_mem (pr, pr->progs);
|
||||||
mem_size = pr->progs_size + pr->zone_size + pr->pr_edictareasize;
|
mem_size = pr->progs_size + pr->zone_size + pr->pr_edictareasize;
|
||||||
|
|
|
@ -187,14 +187,14 @@ ED_WriteGlobals (progs_t *pr, QFile *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static int
|
||||||
ED_NewString (progs_t *pr, const char *string)
|
ED_NewString (progs_t *pr, const char *string)
|
||||||
{
|
{
|
||||||
char *new, *new_p;
|
char *new, *new_p;
|
||||||
int i, l;
|
int i, l;
|
||||||
|
|
||||||
l = strlen (string) + 1;
|
l = strlen (string) + 1;
|
||||||
new = Hunk_Alloc (l);
|
new = Hunk_TempAlloc (l);
|
||||||
new_p = new;
|
new_p = new;
|
||||||
|
|
||||||
for (i = 0; i < l; i++) {
|
for (i = 0; i < l; i++) {
|
||||||
|
@ -208,7 +208,7 @@ ED_NewString (progs_t *pr, const char *string)
|
||||||
*new_p++ = string[i];
|
*new_p++ = string[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return new;
|
return PR_SetString (pr, new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, ddef_t *key, const char *s)
|
||||||
|
|
||||||
switch (key->type & ~DEF_SAVEGLOBAL) {
|
switch (key->type & ~DEF_SAVEGLOBAL) {
|
||||||
case ev_string:
|
case ev_string:
|
||||||
d->string_var = PR_SetString (pr, ED_NewString (pr, s));
|
d->string_var = ED_NewString (pr, s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_float:
|
case ev_float:
|
||||||
|
|
|
@ -125,7 +125,7 @@ new_string_ref (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_string_ref (progs_t *pr, strref_t *sr)
|
free_string_ref (strref_t *sr)
|
||||||
{
|
{
|
||||||
sr->string = 0;
|
sr->string = 0;
|
||||||
sr->dstring = 0;
|
sr->dstring = 0;
|
||||||
|
@ -169,7 +169,7 @@ strref_free (void *_sr, void *_pr)
|
||||||
|
|
||||||
// free the string and ref only if it's not a static string
|
// free the string and ref only if it's not a static string
|
||||||
if (sr < pr->static_strings || sr >= pr->static_strings + pr->num_strings) {
|
if (sr < pr->static_strings || sr >= pr->static_strings + pr->num_strings) {
|
||||||
free_string_ref (pr, sr);
|
free_string_ref (sr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,6 +302,41 @@ PR_SetString (progs_t *pr, const char *s)
|
||||||
return string_index (pr, sr);
|
return string_index (pr, sr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PR_ClearReturnStrings (progs_t *pr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < PR_RS_SLOTS; i++)
|
||||||
|
if (pr->return_strings[i])
|
||||||
|
free_string_ref (pr->return_strings[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PR_SetReturnString (progs_t *pr, const char *s)
|
||||||
|
{
|
||||||
|
strref_t *sr;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
s = "";
|
||||||
|
if ((sr = Hash_Find (pr->strref_hash, s))) {
|
||||||
|
return string_index (pr, sr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sr = pr->return_strings[pr->rs_slot])) {
|
||||||
|
if (sr->string)
|
||||||
|
PR_Zone_Free (pr, sr->string);
|
||||||
|
} else {
|
||||||
|
sr = new_string_ref (pr);
|
||||||
|
}
|
||||||
|
sr->string = pr_strdup(pr, s);
|
||||||
|
sr->count = 0;
|
||||||
|
|
||||||
|
pr->return_strings[pr->rs_slot++] = sr;
|
||||||
|
pr->rs_slot %= PR_RS_SLOTS;
|
||||||
|
return string_index (pr, sr);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PR_SetTempString (progs_t *pr, const char *s)
|
PR_SetTempString (progs_t *pr, const char *s)
|
||||||
{
|
{
|
||||||
|
@ -355,7 +390,7 @@ PR_FreeString (progs_t *pr, int str)
|
||||||
dstring_delete (sr->dstring);
|
dstring_delete (sr->dstring);
|
||||||
else
|
else
|
||||||
PR_Zone_Free (pr, sr->string);
|
PR_Zone_Free (pr, sr->string);
|
||||||
free_string_ref (pr, sr);
|
free_string_ref (sr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PR_RunError (pr, "attempt to free invalid string %d", str);
|
PR_RunError (pr, "attempt to free invalid string %d", str);
|
||||||
|
@ -369,7 +404,7 @@ PR_FreeTempStrings (progs_t *pr)
|
||||||
for (sr = pr->pr_xtstr; sr; sr = t) {
|
for (sr = pr->pr_xtstr; sr; sr = t) {
|
||||||
t = sr->next;
|
t = sr->next;
|
||||||
PR_Zone_Free (pr, sr->string);
|
PR_Zone_Free (pr, sr->string);
|
||||||
free_string_ref (pr, sr);
|
free_string_ref (sr);
|
||||||
}
|
}
|
||||||
pr->pr_xtstr = 0;
|
pr->pr_xtstr = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue