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:
Bill Currie 2004-01-07 05:22:57 +00:00
parent 8d42963c4d
commit e455b760ca
5 changed files with 53 additions and 11 deletions

View File

@ -160,7 +160,7 @@ qboolean PR_EdictValid (progs_t *pr, int e);
#define R_FUNCTION(p) R_var (p, func)
#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_POINTER(pr,p) (R_POINTER (pr) = POINTER_TO_PROG (pr, 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);
struct dstring_s *PR_GetDString(progs_t *pr, int num);
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);
void PR_MakeTempString(progs_t *pr, int str);
int PR_NewString (progs_t *pr);
void PR_ClearReturnStrings (progs_t *pr);
void PR_FreeString (progs_t *pr, int str);
void PR_FreeTempStrings (progs_t *pr);
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 LOCALSTACK_SIZE 4096
#define PR_RS_SLOTS 16
typedef struct strref_s strref_t;
@ -346,6 +349,8 @@ struct progs_s {
struct dstring_mem_s *ds_mem;
strref_t *static_strings;
strref_t **dynamic_strings;
strref_t *return_strings[PR_RS_SLOTS];
int rs_slot;
unsigned dyn_str_size;
struct hashtab_s *strref_hash;
int num_strings;

View File

@ -422,8 +422,9 @@ ED_Print (progs_t *pr, edict_t *ed)
continue;
break;
case ev_string:
if (!PR_GetString (pr, v->string_var)[0])
continue;
if (PR_StringValid (pr, v->string_var))
if (!PR_GetString (pr, v->string_var)[0])
continue;
break;
case ev_float:
if (!v->float_var)

View File

@ -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_Resources_Clear (pr);
PR_ClearReturnStrings (pr);
if (pr->progs)
pr->free_progs_mem (pr, pr->progs);
mem_size = pr->progs_size + pr->zone_size + pr->pr_edictareasize;

View File

@ -187,14 +187,14 @@ ED_WriteGlobals (progs_t *pr, QFile *f)
}
static char *
static int
ED_NewString (progs_t *pr, const char *string)
{
char *new, *new_p;
int i, l;
l = strlen (string) + 1;
new = Hunk_Alloc (l);
new = Hunk_TempAlloc (l);
new_p = new;
for (i = 0; i < l; i++) {
@ -208,7 +208,7 @@ ED_NewString (progs_t *pr, const char *string)
*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) {
case ev_string:
d->string_var = PR_SetString (pr, ED_NewString (pr, s));
d->string_var = ED_NewString (pr, s);
break;
case ev_float:

View File

@ -125,7 +125,7 @@ new_string_ref (progs_t *pr)
}
static void
free_string_ref (progs_t *pr, strref_t *sr)
free_string_ref (strref_t *sr)
{
sr->string = 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
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);
}
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
PR_SetTempString (progs_t *pr, const char *s)
{
@ -355,7 +390,7 @@ PR_FreeString (progs_t *pr, int str)
dstring_delete (sr->dstring);
else
PR_Zone_Free (pr, sr->string);
free_string_ref (pr, sr);
free_string_ref (sr);
return;
}
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) {
t = sr->next;
PR_Zone_Free (pr, sr->string);
free_string_ref (pr, sr);
free_string_ref (sr);
}
pr->pr_xtstr = 0;
}