mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-17 22:50:51 +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_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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue