[plist] Use reference counts for items

This makes it much easier to share items between property lists (eg,
targets and the main entity list in cl_light).
This commit is contained in:
Bill Currie 2023-03-12 15:17:28 +09:00
parent 45bcb31684
commit 7d4c1d79b1
21 changed files with 166 additions and 204 deletions

View file

@ -238,11 +238,8 @@ plitem_t *PL_ObjectForKey (const plitem_t *dict, const char *key);
\param dict The Dictionary to remove the value from
\param key The unique key associated with the value to be removed
\return the value associated with the key, or NULL if not found or \a dict
isn't a dictionary (includes if \a dict is null).
\note You are responsible for freeing the returned object.
*/
plitem_t *PL_RemoveObjectForKey (plitem_t *dict, const char *key);
void PL_RemoveObjectForKey (plitem_t *dict, const char *key);
/** Retrieve a key from a dictionary object.
@ -332,15 +329,12 @@ int PL_A_NumObjects (const plitem_t *array) __attribute__((pure));
qboolean PL_A_InsertObjectAtIndex (plitem_t *array, plitem_t *item, int index);
/** Remove a value from an array object.
The array items will be shuffled to fill the resulting hole.
The array items will be shifted to fill the resulting hole.
\param array The array from which to remove the value
\param index The index within the array to remove
\return the value associated with the index, or NULL if not found or array
is noll or an array.
\note You are responsible for freeing the returned object.
*/
plitem_t *PL_RemoveObjectAtIndex (plitem_t *array, int index);
void PL_RemoveObjectAtIndex (plitem_t *array, int index);
/** Create a new dictionary object.
The dictionary will be empty.
@ -372,14 +366,32 @@ plitem_t *PL_NewData (void *data, size_t size);
*/
plitem_t *PL_NewString (const char *str);
/** Free a property list object.
/** Retain ownership of a property list object.
This function takes care of freeing any referenced property list data, so
call it only on top-level objects. Safe to call with a null argument.
Use prior to removal to ensure the property list object is not freed when
removed from an array or dictionary. Adding an object to a dictionary or
array automatically retains the object.
\param item the property list object to be freed
\param item the property list object to be retained
\return the item
\note item may be null, in which case nothing is done but to return null
*/
void PL_Free (plitem_t *item);
plitem_t *PL_Retain (plitem_t *item);
/** Release ownership of a property list object.
If the number of owners is reduced to 0 (or is already 0) then the object
will be freed. If the object contains other objects, then those objects
will be released.
\param item the property list object to be released
\return the item if it is still valid, otherwise null
\note item may be null, in which case nothing is done but to return null
*/
plitem_t *PL_Release (plitem_t *item);
void PL_SetUserData (plitem_t *item, void *data);
void *PL_GetUserData (plitem_t *item) __attribute__((pure));
int PL_CheckType (pltype_t field_type, pltype_t item_type) __attribute__((const));
void PL_TypeMismatch (plitem_t *messages, const plitem_t *item,

View file

@ -142,7 +142,7 @@ I_OGGMus_Shutdown (void)
{
if (tracklist) {
I_OGGMus_Stop ();
PL_Free (tracklist);
PL_Release (tracklist);
tracklist = NULL;
}
mus_enabled = false;
@ -184,7 +184,7 @@ Load_Tracklist (void)
buffile = calloc (size+10, sizeof (char));
Qread (oggfile, buffile, size);
PL_Free (tracklist);
PL_Release (tracklist);
tracklist = PL_GetPropertyList (buffile, 0);
if (!tracklist || PL_Type (tracklist) != QFDictionary) {
Sys_Printf ("Malformed or empty tracklist file. check mus_ogglist\n");

View file

@ -495,7 +495,7 @@ CL_Legacy_Init (void)
Cmd_AddCommand ("unbind", cl_unbind_f, "compatibility wrapper for in_bind");
plitem_t *cfg = PL_GetPropertyList (default_input_config, 0);
IN_LoadConfig (cfg);
PL_Free (cfg);
PL_Release (cfg);
}
void

View file

@ -321,12 +321,7 @@ CL_LoadLights (plitem_t *entities, scene_t *scene)
}
}
}
// targets does not own the objects, so need to remove them before
// freeing targets
for (int i = PL_D_NumKeys (targets); i-- > 0; ) {
PL_RemoveObjectForKey (targets, PL_KeyAtIndex (targets, i));
}
PL_Free (targets);
PL_Release (targets);
for (size_t i = 0; i < ldata->lights.size; i++) {
dump_light (&ldata->lights.a[i], ldata->lightleafs.a[i]);

View file

@ -217,7 +217,7 @@ CL_World_NewMap (const char *mapname, const char *skyname)
if (cl_world.models.a[1] && cl_world.models.a[1]->brush.entities) {
if (cl_world.edicts) {
PL_Free (cl_world.edicts);
PL_Release (cl_world.edicts);
}
cl_world.edicts = map_ent (mapname);
if (cl_world.edicts) {

View file

@ -347,7 +347,7 @@ ED_ConvertToPlist (script_t *script, int nohack, struct hashctx_s **hashctx)
value = PL_NewString (token);
}
PL_D_AddObject (ent, PL_String (key), value);
PL_Free (key);
PL_Release (key);
}
PL_A_AddObject (plist, ent);
}
@ -356,7 +356,7 @@ ED_ConvertToPlist (script_t *script, int nohack, struct hashctx_s **hashctx)
parse_error:
Sys_Printf ("%s:%d: %s", script->file, script->line, msg);
dstring_delete (dstr);
PL_Free (plist);
PL_Release (plist);
return 0;
}
@ -406,7 +406,7 @@ ED_InitGlobals (progs_t *pr, plitem_t *globals)
if (!ED_ParseEpair (pr, pr->pr_globals, global, value))
PR_Error (pr, "ED_InitGlobals: parse error");
}
PL_Free (keys);
PL_Release (keys);
}
VISIBLE void
@ -437,7 +437,7 @@ ED_InitEntity (progs_t *pr, plitem_t *entity, edict_t *ent)
}
init = 1;
}
PL_Free (keys);
PL_Release (keys);
if (!init)
ent->free = 1;
}
@ -539,7 +539,7 @@ ED_LoadFromFile (progs_t *pr, const char *data)
entity_list = ED_Parse (pr, data);
if (entity_list) {
ED_SpawnEntities (pr, entity_list);
PL_Free (entity_list);
PL_Release (entity_list);
}
}

View file

@ -462,7 +462,7 @@ in_bind_f (void)
IMT_BindAxis (imt, dev->axis_imt_id + num, axis, &recipe);
}
Hash_DelTable (vars_tab.tab);
PL_Free (exprctx.messages);
PL_Release (exprctx.messages);
delete_memsuper (exprctx.memsuper);
} else {
// the rest of the command line is the binding

View file

@ -51,13 +51,12 @@ typedef struct bi_plist_s {
struct bi_plist_s *next;
struct bi_plist_s **prev;
plitem_t *plitem;
int own;
int users;
} bi_plist_t;
typedef struct {
PR_RESMAP (bi_plist_t) plist_map;
bi_plist_t *plists;
hashtab_t *plist_tab;
} plist_resources_t;
static bi_plist_t *
@ -97,12 +96,10 @@ bi_plist_clear (progs_t *pr, void *_res)
bi_plist_t *plist;
for (plist = res->plists; plist; plist = plist->next) {
if (plist->own)
PL_Free (plist->plitem);
PL_Release (plist->plitem);
}
res->plists = 0;
Hash_FlushTable (res->plist_tab);
plist_reset (res);
}
@ -110,7 +107,6 @@ static void
bi_plist_destroy (progs_t *pr, void *_res)
{
__auto_type res = (plist_resources_t *) _res;
Hash_DelTable (res->plist_tab);
PR_RESDELMAP (res->plist_map);
@ -120,8 +116,7 @@ bi_plist_destroy (progs_t *pr, void *_res)
static inline int
plist_handle (plist_resources_t *res, plitem_t *plitem)
{
bi_plist_t dummy = {0, 0, plitem, 0};
bi_plist_t *plist = Hash_FindElement (res->plist_tab, &dummy);
bi_plist_t *plist = PL_GetUserData (plitem);
if (plist)
return plist_index (res, plist);
@ -137,16 +132,19 @@ plist_handle (plist_resources_t *res, plitem_t *plitem)
res->plists->prev = &plist->next;
res->plists = plist;
PL_Retain (plitem);
plist->plitem = plitem;
Hash_AddElement (res->plist_tab, plist);
PL_SetUserData (plitem, plist);
return plist_index (res, plist);
}
static inline void
plist_free_handle (plist_resources_t *res, bi_plist_t *plist)
{
Hash_DelElement (res->plist_tab, plist);
PL_SetUserData (plist->plitem, 0);
PL_Release (plist->plitem);
*plist->prev = plist->next;
if (plist->next)
plist->next->prev = plist->prev;
@ -168,7 +166,6 @@ static inline int
plist_retain (plist_resources_t *res, plitem_t *plitem)
{
int handle;
bi_plist_t *plist;
if (!plitem)
return 0;
@ -178,12 +175,10 @@ plist_retain (plist_resources_t *res, plitem_t *plitem)
// we're taking ownership of the plitem, but we have nowhere to store
// it, so we have to lose it. However, in this situation, we have worse
// things to worry about.
PL_Free (plitem);
PL_Release (plitem);
return 0;
}
plist = plist_get (res, handle);
plist->own = 1;
return handle;
}
@ -327,9 +322,7 @@ bi_PL_RemoveObjectForKey (progs_t *pr, void *_res)
int handle = P_INT (pr, 0);
bi_plist_t *plist = get_plist (pr, res, __FUNCTION__, handle);
const char *key = P_GSTRING (pr, 1);
plitem_t *plitem = PL_RemoveObjectForKey (plist->plitem, key);
R_INT (pr) = plist_retain (res, plitem);
PL_RemoveObjectForKey (plist->plitem, key);
}
static void
@ -390,7 +383,6 @@ bi_PL_D_AddObject (progs_t *pr, void *_res)
const char *key = P_GSTRING (pr, 1);
bi_plist_t *obj = get_plist (pr, res, __FUNCTION__, obj_handle);
obj->own = 0;
R_INT (pr) = PL_D_AddObject (dict->plitem, key, obj->plitem);
}
@ -403,7 +395,6 @@ bi_PL_A_AddObject (progs_t *pr, void *_res)
bi_plist_t *arr = get_plist (pr, res, __FUNCTION__, arr_handle);
bi_plist_t *obj = get_plist (pr, res, __FUNCTION__, obj_handle);
obj->own = 0;
R_INT (pr) = PL_A_AddObject (arr->plitem, obj->plitem);
}
@ -427,7 +418,6 @@ bi_PL_A_InsertObjectAtIndex (progs_t *pr, void *_res)
bi_plist_t *obj = get_plist (pr, res, __FUNCTION__, obj_handle);
int ind = P_INT (pr, 2);
obj->own = 0;
R_INT (pr) = PL_A_InsertObjectAtIndex (arr->plitem, obj->plitem, ind);
}
@ -438,9 +428,7 @@ bi_PL_RemoveObjectAtIndex (progs_t *pr, void *_res)
int handle = P_INT (pr, 0);
bi_plist_t *plist = get_plist (pr, res, __FUNCTION__, handle);
int ind = P_INT (pr, 1);
plitem_t *plitem = PL_RemoveObjectAtIndex (plist->plitem, ind);
R_INT (pr) = plist_retain (res, plitem);
PL_RemoveObjectAtIndex (plist->plitem, ind);
}
static void
@ -481,18 +469,28 @@ bi_PL_NewString (progs_t *pr, void *_res)
}
static void
bi_PL_Free (progs_t *pr, void *_res)
bi_PL_Release (progs_t *pr, void *_res)
{
plist_resources_t *res = _res;
int handle = P_INT (pr, 0);
bi_plist_t *plist = get_plist (pr, res, __FUNCTION__, handle);
if (!plist->own)
PR_RunError (pr, "attempt to free unowned plist");
if (!(plist->users && --plist->users > 0)) {
plist_free_handle (res, plist);
handle = 0;
}
R_INT (pr) = handle;
}
PL_Free (plist->plitem);
static void
bi_PL_Retain (progs_t *pr, void *_res)
{
plist_resources_t *res = _res;
int handle = P_INT (pr, 0);
bi_plist_t *plist = get_plist (pr, res, __FUNCTION__, handle);
plist_free_handle (res, plist);
plist->users++;
R_INT (pr) = handle;
}
plitem_t *
@ -503,21 +501,6 @@ Plist_GetItem (progs_t *pr, int handle)
return plist->plitem;
}
static uintptr_t
plist_get_hash (const void *key, void *unused)
{
bi_plist_t *plist = (bi_plist_t *) key;
return (uintptr_t) plist->plitem;
}
static int
plist_compare (const void *k1, const void *k2, void *unused)
{
bi_plist_t *pl1 = (bi_plist_t *) k1;
bi_plist_t *pl2 = (bi_plist_t *) k2;
return pl1->plitem == pl2->plitem;
}
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
#define p(type) PR_PARAM(type)
static builtin_t builtins[] = {
@ -546,7 +529,8 @@ static builtin_t builtins[] = {
bi(PL_NewArray, 0),
bi(PL_NewData, 2, p(ptr), p(int)),
bi(PL_NewString, 1, p(string)),
bi(PL_Free, 1, p(ptr)),
bi(PL_Release, 1, p(ptr)),
bi(PL_Retain, 1, p(ptr)),
{0}
};
@ -554,8 +538,6 @@ void
RUA_Plist_Init (progs_t *pr, int secure)
{
plist_resources_t *res = calloc (1, sizeof (plist_resources_t));
res->plist_tab = Hash_NewTable (1021, 0, 0, 0, pr->hashctx);
Hash_SetHashCompare (res->plist_tab, plist_get_hash, plist_compare);
PR_Resources_Register (pr, "plist", res, bi_plist_clear, bi_plist_destroy);
PR_RegisterBuiltins (pr, builtins, res);

View file

@ -49,10 +49,12 @@
Generic property list item.
*/
struct plitem_s {
pltype_t type;
pltype_t type;
unsigned users;
void *data;
void *user_data;
int line;
void *data;
};
};//plitem_t
/*
Dictionaries
@ -146,7 +148,7 @@ dict_free (void *i, void *unused)
dictkey_t *item = (dictkey_t *) i;
free (item->key);
if (item->value) // Make descended stuff get freed
PL_Free (item->value);
PL_Release (item->value);
free (item);
}
@ -206,14 +208,23 @@ PL_NewString (const char *str)
return new_string (str, strlen (str), 0);
}
VISIBLE void
PL_Free (plitem_t *item)
VISIBLE plitem_t *
PL_Retain (plitem_t *item)
{
if (item) {
item->users++;
}
return item;
}
VISIBLE plitem_t *
PL_Release (plitem_t *item)
{
pldict_t *dict;
plarray_t *array;
if (!item) {
return;
if (!item || (item->users && --item->users > 0)) {
return item;
}
switch (item->type) {
case QFDictionary:
@ -229,7 +240,7 @@ PL_Free (plitem_t *item)
int i = array->numvals;
while (i-- > 0) {
PL_Free (array->values[i]);
PL_Release (array->values[i]);
}
free (array->values);
free (item->data);
@ -248,6 +259,19 @@ PL_Free (plitem_t *item)
break;
}
free (item);
return 0;
}
VISIBLE void
PL_SetUserData (plitem_t *item, void *data)
{
item->user_data = data;
}
VISIBLE void *
PL_GetUserData (plitem_t *item)
{
return item->user_data;
}
VISIBLE size_t
@ -308,11 +332,11 @@ PL_KeyAtIndex (const plitem_t *item, int index)
return dict->keys.a[index]->key;
}
VISIBLE plitem_t *
VISIBLE void
PL_RemoveObjectForKey (plitem_t *item, const char *key)
{
if (!item || item->type != QFDictionary) {
return NULL;
return;
}
pldict_t *dict = (pldict_t *) item->data;
@ -320,8 +344,9 @@ PL_RemoveObjectForKey (plitem_t *item, const char *key)
plitem_t *value;
k = (dictkey_t *) Hash_Del (dict->tab, key);
if (!k)
return NULL;
if (!k) {
return;
}
value = k->value;
k->value = 0;
for (size_t i = 0; i < dict->keys.size; i++) {
@ -331,7 +356,7 @@ PL_RemoveObjectForKey (plitem_t *item, const char *key)
}
}
dict_free (k, 0);
return value;
value->users--;
}
VISIBLE plitem_t *
@ -389,7 +414,8 @@ PL_D_AddObject (plitem_t *item, const char *key, plitem_t *value)
dictkey_t *k;
if ((k = Hash_Find (dict->tab, key))) {
PL_Free ((plitem_t *) k->value);
value->users++;
PL_Release (k->value);
k->value = value;
} else {
k = malloc (sizeof (dictkey_t));
@ -397,6 +423,7 @@ PL_D_AddObject (plitem_t *item, const char *key, plitem_t *value)
if (!k)
return false;
value->users++;
k->key = strdup (key);
k->value = value;
@ -438,6 +465,8 @@ PL_A_InsertObjectAtIndex (plitem_t *array, plitem_t *item, int index)
memmove (arr->values + index + 1, arr->values + index,
(arr->numvals - index) * sizeof (plitem_t *));
item->users++;
arr->values[index] = item;
arr->numvals++;
return true;
@ -458,11 +487,11 @@ PL_A_NumObjects (const plitem_t *array)
return ((plarray_t *) array->data)->numvals;
}
VISIBLE plitem_t *
VISIBLE void
PL_RemoveObjectAtIndex (plitem_t *array, int index)
{
if (!array || array->type != QFArray) {
return 0;
return;
}
plarray_t *arr;
@ -471,7 +500,7 @@ PL_RemoveObjectAtIndex (plitem_t *array, int index)
arr = (plarray_t *)array->data;
if (index < 0 || index >= arr->numvals)
return 0;
return;
item = arr->values[index];
arr->numvals--;
@ -480,7 +509,7 @@ PL_RemoveObjectAtIndex (plitem_t *array, int index)
index++;
}
return item;
item->users--;
}
static void __attribute__((format(printf, 2, 3)))
@ -631,7 +660,7 @@ pl_parsekeyvalue (pldata_t *pl, plitem_t *dict, int end_ok)
if (!PL_D_AddObject (dict, PL_String (key), value)) {
goto error;
}
PL_Free (key); // don't need the key item
PL_Release (key); // don't need the key item
if (!pl_checknext (pl, end_ok ? ";" : ";}", end_ok)) {
return 0;
@ -642,8 +671,8 @@ pl_parsekeyvalue (pldata_t *pl, plitem_t *dict, int end_ok)
}
return 1;
error:
PL_Free (key);
PL_Free (value);
PL_Release (key);
PL_Release (value);
return 0;
}
@ -656,13 +685,13 @@ pl_parsedictionary (pldata_t *pl)
pl->pos++; // skip over opening {
while (pl_skipspace (pl, 0) && pl->ptr[pl->pos] != '}') {
if (!pl_parsekeyvalue (pl, dict, 0)) {
PL_Free (dict);
PL_Release (dict);
return NULL;
}
}
if (pl->pos >= pl->end) {
pl_error (pl, "Unexpected end of string when parsing dictionary");
PL_Free (dict);
PL_Release (dict);
return NULL;
}
pl->pos++; // skip over closing }
@ -680,7 +709,7 @@ pl_parsevalue (pldata_t *pl, plitem_t *array, int end_ok)
}
if (!PL_A_AddObject (array, value)) {
pl_error (pl, "too many items in array");
PL_Free (value);
PL_Release (value);
return 0;
}
@ -705,13 +734,13 @@ pl_parsearray (pldata_t *pl)
while (pl_skipspace (pl, 0) && pl->ptr[pl->pos] != ')') {
if (!pl_parsevalue (pl, array, 0)) {
PL_Free (array);
PL_Release (array);
return NULL;
}
}
if (pl->pos >= pl->end) {
pl_error (pl, "Unexpected end of string when parsing array");
PL_Free (array);
PL_Release (array);
return NULL;
}
pl->pos++; // skip over opening )
@ -978,7 +1007,7 @@ pl_getdictionary (pldata_t *pl)
while (pl_skipspace (pl, 1)) {
if (!pl_parsekeyvalue (pl, dict, 1)) {
PL_Free (dict);
PL_Release (dict);
return NULL;
}
}
@ -1000,7 +1029,7 @@ pl_getarray (pldata_t *pl)
while (pl_skipspace (pl, 1)) {
if (!pl_parsevalue (pl, array, 1)) {
PL_Free (array);
PL_Release (array);
return NULL;
}
}

View file

@ -543,7 +543,7 @@ qfs_find_gamedir (const char *name, hashtab_t *dirs)
}
}
free (list);
PL_Free (keys);
PL_Release (keys);
}
return gdpl;
}
@ -706,7 +706,7 @@ qfs_load_config (void)
Qclose (f);
if (qfs_gd_plist)
PL_Free (qfs_gd_plist);
PL_Release (qfs_gd_plist);
qfs_gd_plist = PL_GetDictionary (buf, 0);
free (buf);
if (qfs_gd_plist && PL_Type (qfs_gd_plist) == QFDictionary)
@ -714,7 +714,7 @@ qfs_load_config (void)
Sys_Printf ("not a dictionary\n");
no_config:
if (qfs_gd_plist)
PL_Free (qfs_gd_plist);
PL_Release (qfs_gd_plist);
qfs_gd_plist = PL_GetPropertyList (qfs_default_dirconf, 0);
}
@ -1470,7 +1470,7 @@ qfs_shutdown (void *data)
{
clear_findfile ();
qfs_free_gamedir ();
PL_Free (qfs_gd_plist);
PL_Release (qfs_gd_plist);
free ((char *) qfs_userpath);
free (gamedir_callbacks);
ALLOC_FREE_BLOCKS (vpaths);

View file

@ -28,7 +28,7 @@ test_string_io (const char *str)
item = PL_NewString (str);
saved = PL_WritePropertyList (item);
PL_Free (item);
PL_Release (item);
item = PL_GetPropertyList (saved, 0);
res = PL_String (item);
if (!strcmp (str, res))

View file

@ -1283,7 +1283,7 @@ parse_object (vulkan_ctx_t *ctx, memsuper_t *memsuper, plitem_t *plist,
return 0;
}
Hash_DelTable (vars_tab.tab);
PL_Free (messages);
PL_Release (messages);
return 1;
}
@ -1979,7 +1979,7 @@ delete_configs (void)
{
int num_plists = 0;
for (exprsym_t *sym = builtin_plist_syms; sym->name; sym++) {
PL_Free (builtin_plists[num_plists]);
PL_Release (builtin_plists[num_plists]);
num_plists++;
}
free (builtin_plists);
@ -2030,7 +2030,7 @@ Vulkan_GetConfig (vulkan_ctx_t *ctx, const char *name)
dstring_delete (msg);
config = 0;
}
PL_Free (ectx.messages);
PL_Release (ectx.messages);
delete_memsuper (ectx.memsuper);
return config;
}
@ -2353,7 +2353,7 @@ QFV_ParseRenderInfo (vulkan_ctx_t *ctx, plitem_t *item, qfv_renderctx_t *rctx)
}
}
QFV_DestroySymtab (exprctx.external_variables);
PL_Free (messages);
PL_Release (messages);
if (!ret) {
delete_memsuper (memsuper);
ri = 0;
@ -2409,7 +2409,7 @@ QFV_ParseJobInfo (vulkan_ctx_t *ctx, plitem_t *item, qfv_renderctx_t *rctx)
}
}
QFV_DestroySymtab (exprctx.external_variables);
PL_Free (messages);
PL_Release (messages);
if (!ret) {
delete_memsuper (memsuper);
ri = 0;
@ -2448,8 +2448,8 @@ QFV_ParseLayoutInfo (vulkan_ctx_t *ctx, memsuper_t *memsuper,
Sys_Printf ("%s\n", PL_String (PL_ObjectAtIndex (messages, i)));
}
}
PL_Free (messages);
PL_Free (item);
PL_Release (messages);
PL_Release (item);
return ret;
}

View file

@ -170,7 +170,7 @@ CL_WriteConfiguration (void)
free (cfg);
Qclose (f);
}
PL_Free (config);
PL_Release (config);
}
}
@ -197,7 +197,7 @@ CL_ReadConfiguration (const char *cfg_name)
Cvar_LoadConfig (config);
IN_LoadConfig (config);
PL_Free (config);
PL_Release (config);
return 1;
}

View file

@ -506,9 +506,10 @@ convert_to_game_dict (script_t *script)
// load the edicts out of the savegame file
list = ED_ConvertToPlist (script, 0, 0);
item = PL_RemoveObjectAtIndex (list, 0);
item = PL_ObjectAtIndex (list, 0);
PL_D_AddObject (game, "globals", item);
PL_D_AddObject (game, "entities", list);
PL_RemoveObjectAtIndex (list, 0);
return game;
}
@ -728,7 +729,7 @@ Host_Loadgame_f (void)
}
end:
if (game)
PL_Free (game);
PL_Release (game);
if (mapname)
free (mapname);
if (script)

View file

@ -1734,7 +1734,7 @@ Host_WriteConfiguration (void)
free (cfg);
Qclose (f);
}
PL_Free (config);
PL_Release (config);
}
}
@ -1761,7 +1761,7 @@ Host_ReadConfiguration (const char *cfg_name)
Cvar_LoadConfig (config);
IN_LoadConfig (config);
PL_Free (config);
PL_Release (config);
return 1;
}

View file

@ -30,7 +30,6 @@
@interface PLItem: Object <PLDictionary, PLArray, PLString>
{
plitem_t *item;
int own;
}
+ (PLItem *) newDictionary;
+ (PLItem *) newArray;
@ -40,7 +39,6 @@
+ (PLItem *) fromFile:(QFile) file;
- initWithItem:(plitem_t *) item;
- initWithOwnItem:(plitem_t *) item;
- (plitem_t *) item;
- (string) write;
- (pltype_t) type;

View file

@ -17,7 +17,7 @@ typedef enum {QFDictionary, QFArray, QFBinary, QFString} pltype_t; // possible t
@extern int PL_Line (plitem_t *str);
@extern string PL_String (plitem_t *str);
@extern plitem_t *PL_ObjectForKey (plitem_t *item, string key);
@extern plitem_t *PL_RemoveObjectForKey (plitem_t *item, string key);
@extern void PL_RemoveObjectForKey (plitem_t *item, string key);
@extern plitem_t *PL_ObjectAtIndex (plitem_t *item, int index);
@extern plitem_t *PL_D_AllKeys (plitem_t *item);
@extern string PL_KeyAtIndex (plitem_t *item, int index);
@ -26,11 +26,12 @@ typedef enum {QFDictionary, QFArray, QFBinary, QFString} pltype_t; // possible t
@extern int PL_A_AddObject (plitem_t *array_item, plitem_t *item);
@extern int PL_A_NumObjects (plitem_t *item);
@extern int PL_A_InsertObjectAtIndex (plitem_t *array_item, plitem_t *item, int index);
@extern plitem_t *PL_RemoveObjectAtIndex (plitem_t *array_item, int index);
@extern void PL_RemoveObjectAtIndex (plitem_t *array_item, int index);
@extern plitem_t *PL_NewDictionary ();
@extern plitem_t *PL_NewArray ();
@extern plitem_t *PL_NewData (void *data, int len);
@extern plitem_t *PL_NewString (string str);
@extern void PL_Free (plitem_t *pl);
@extern plitem_t *PL_Retain (plitem_t *pl);
@extern plitem_t *PL_Release (plitem_t *pl);
#endif//__ruamoko_plist_h

View file

@ -99,7 +99,7 @@ int PR_SetField (entity ent, string field, string value) = #0;
value = PL_String (PL_ObjectForKey (dict, field));
PR_SetField (ent, field, value);
}
PL_Free (keys);
PL_Release (keys);
if ((func = PR_FindFunction (classname))) {
//dprint ("calling " + classname + "\n");
@self = ent;
@ -157,7 +157,7 @@ int PR_SetField (entity ent, string field, string value) = #0;
else
value = PL_NewString (token);
PL_D_AddObject (ent, PL_String (key), value);
PL_Free (key);
PL_Release (key);
}
PL_A_AddObject (plist, ent);
}

View file

@ -49,47 +49,28 @@
return [[class alloc] initWithItem: item];
}
+ (PLItem *) ownItemClass:(plitem_t *) item
{
PLItem *plitem = [PLItem itemClass:item];
if (plitem) {
plitem.own = 1;
}
return plitem;
}
+ (PLItem *) fromString:(string) str
{
return [[PLItem ownItemClass: PL_GetPropertyList (str)] autorelease];
return [[PLItem itemClass: PL_GetPropertyList (str)] autorelease];
}
+ (PLItem *) fromFile:(QFile) file
{
return [[PLItem ownItemClass: PL_GetFromFile (file)] autorelease];
return [[PLItem itemClass: PL_GetFromFile (file)] autorelease];
}
- initWithItem:(plitem_t *) item
{
if (!(self = [super init]))
return self;
PL_Retain (item);
self.item = item;
own = 0;
return self;
}
-initWithOwnItem:(plitem_t *) item
{
if (!(self = [super init]))
return self;
self.item = item;
own = 1;
return self;
}
- (void) dealloc
{
if (own)
PL_Free (item);
PL_Release (item);
[super dealloc];
}
@ -144,13 +125,7 @@
- addKey:(string) key value:(PLItem *) value
{
if (!value.own) {
obj_error (self, 0, "add of unowned key/value to PLDictionary");
return self;
}
PL_D_AddObject (item, key, value.item);
value.own = 0;
[value release];
return self;
}
@ -166,25 +141,13 @@
- addObject:(PLItem *) object
{
if (!object.own) {
obj_error (self, 0, "add of unowned object to PLArray");
return self;
}
PL_A_AddObject (item, object.item);
object.own = 0;
[object release];
return self;
}
- insertObject:(PLItem *) object atIndex:(int) index
{
if (!object.own) {
obj_error (self, 0, "add of unowned object to PLArray");
return self;
}
PL_A_InsertObjectAtIndex (item, object.item, index);
object.own = 0;
[object release];
return self;
}
@ -200,17 +163,17 @@
+ (PLDictionary *) new
{
return [[PLDictionary alloc] initWithOwnItem: PL_NewDictionary ()];
return [[PLDictionary alloc] initWithItem: PL_NewDictionary ()];
}
+ (PLItem *) fromString:(string) str
{
return [[PLItem ownItemClass: PL_GetDictionary (str)] autorelease];
return [[PLItem itemClass: PL_GetDictionary (str)] autorelease];
}
+ (PLItem *) fromFile:(QFile) file
{
return [[PLItem ownItemClass: PL_GetDictionaryFromFile (file)] autorelease];
return [[PLItem itemClass: PL_GetDictionaryFromFile (file)] autorelease];
}
- (int) count
@ -230,20 +193,12 @@
- (PLItem *) allKeys
{
PLItem *item = [[PLItem itemClass: PL_D_AllKeys (item)] autorelease];
item.own = 1;
return item;
return [[PLItem itemClass: PL_D_AllKeys (item)] autorelease];
}
- addKey:(string) key value:(PLItem *) value
{
if (!value.own) {
obj_error (self, 0, "add of unowned key/value to PLDictionary");
return self;
}
PL_D_AddObject (item, key, value.item);
value.own = 0;
[value release];
return self;
}
@ -253,17 +208,17 @@
+ (PLArray *) new
{
return [[PLArray alloc] initWithOwnItem: PL_NewArray ()];
return [[PLArray alloc] initWithItem: PL_NewArray ()];
}
+ (PLItem *) fromString:(string) str
{
return [[PLItem ownItemClass: PL_GetArray (str)] autorelease];
return [[PLItem itemClass: PL_GetArray (str)] autorelease];
}
+ (PLItem *) fromFile:(QFile) file
{
return [[PLItem ownItemClass: PL_GetArrayFromFile (file)] autorelease];
return [[PLItem itemClass: PL_GetArrayFromFile (file)] autorelease];
}
- (int) count
@ -283,25 +238,13 @@
- addObject:(PLItem *) object
{
if (!object.own) {
obj_error (self, 0, "add of unowned object to PLArray");
return self;
}
PL_A_AddObject (item, object.item);
object.own = 0;
[object release];
return self;
}
- insertObject:(PLItem *) object atIndex:(int) index
{
if (!object.own) {
obj_error (self, 0, "add of unowned object to PLArray");
return self;
}
PL_A_InsertObjectAtIndex (item, object.item, index);
object.own = 0;
[object release];
return self;
}
@ -311,7 +254,7 @@
+ (PLData *) new:(void*) data size:(int) len
{
return [[PLData alloc] initWithOwnItem: PL_NewData (data, len)];
return [[PLData alloc] initWithItem: PL_NewData (data, len)];
}
@end
@ -320,7 +263,7 @@
+ (PLString *) new: (string) str
{
return [[PLString alloc] initWithOwnItem: PL_NewString (str)];
return [[PLString alloc] initWithItem: PL_NewString (str)];
}
- (string) string

View file

@ -11,7 +11,7 @@ pltype_t PL_Type (plitem_t *str) = #0;
int PL_Line (plitem_t *str) = #0;
string PL_String (plitem_t *str) = #0;
plitem_t *PL_ObjectForKey (plitem_t *item, string key) = #0;
plitem_t *PL_RemoveObjectForKey (plitem_t *item, string key) = #0;
void PL_RemoveObjectForKey (plitem_t *item, string key) = #0;
plitem_t *PL_ObjectAtIndex (plitem_t *item, int index) = #0;
plitem_t *PL_D_AllKeys (plitem_t *item) = #0;
string PL_KeyAtIndex (plitem_t *item, int index) = #0;
@ -20,9 +20,10 @@ int PL_D_AddObject (plitem_t *dict, string key, plitem_t *value) = #0;
int PL_A_AddObject (plitem_t *array_item, plitem_t *item) = #0;
int PL_A_NumObjects (plitem_t *item) = #0;
int PL_A_InsertObjectAtIndex (plitem_t *array_item, plitem_t *item, int index) = #0;
plitem_t *PL_RemoveObjectAtIndex (plitem_t *array_item, int index) = #0;
void PL_RemoveObjectAtIndex (plitem_t *array_item, int index) = #0;
plitem_t *PL_NewDictionary (void) = #0;
plitem_t *PL_NewArray (void) = #0;
plitem_t *PL_NewData (void *data, int len) = #0;
plitem_t *PL_NewString (string str) = #0;
void PL_Free (plitem_t *pl) = #0;
plitem_t *PL_Retain (plitem_t *pl) = #0;
plitem_t *PL_Release (plitem_t *pl) = #0;

View file

@ -274,7 +274,7 @@ LoadEntities (void)
entity->persistence = 1;
}
}
PL_Free (dict);
PL_Release (dict);
if (entity->light) {
// convert to subtraction to the brightness for the whole light,