diff --git a/include/QF/plist.h b/include/QF/plist.h index 5ec11f849..884f6b9f3 100644 --- a/include/QF/plist.h +++ b/include/QF/plist.h @@ -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, diff --git a/libs/audio/cd_file.c b/libs/audio/cd_file.c index 8e027199a..b92c88644 100644 --- a/libs/audio/cd_file.c +++ b/libs/audio/cd_file.c @@ -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"); diff --git a/libs/client/cl_input.c b/libs/client/cl_input.c index cb7812e60..1f288b6bd 100644 --- a/libs/client/cl_input.c +++ b/libs/client/cl_input.c @@ -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 diff --git a/libs/client/cl_light.c b/libs/client/cl_light.c index f1466f3c2..61c4df6b6 100644 --- a/libs/client/cl_light.c +++ b/libs/client/cl_light.c @@ -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]); diff --git a/libs/client/cl_world.c b/libs/client/cl_world.c index a6c245aa4..8b8303136 100644 --- a/libs/client/cl_world.c +++ b/libs/client/cl_world.c @@ -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) { diff --git a/libs/gamecode/pr_parse.c b/libs/gamecode/pr_parse.c index 94bff9f58..6ef2770f8 100644 --- a/libs/gamecode/pr_parse.c +++ b/libs/gamecode/pr_parse.c @@ -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); } } diff --git a/libs/input/in_binding.c b/libs/input/in_binding.c index 76ba7d521..9c8957975 100644 --- a/libs/input/in_binding.c +++ b/libs/input/in_binding.c @@ -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 diff --git a/libs/ruamoko/rua_plist.c b/libs/ruamoko/rua_plist.c index 304fe14b0..972acb237 100644 --- a/libs/ruamoko/rua_plist.c +++ b/libs/ruamoko/rua_plist.c @@ -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); diff --git a/libs/util/plist.c b/libs/util/plist.c index 475380dc3..9beda5a15 100644 --- a/libs/util/plist.c +++ b/libs/util/plist.c @@ -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; } } diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index 6e4db10eb..ae736d433 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -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); diff --git a/libs/util/test/test-plist.c b/libs/util/test/test-plist.c index d3ce32715..14b516d6c 100644 --- a/libs/util/test/test-plist.c +++ b/libs/util/test/test-plist.c @@ -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)) diff --git a/libs/video/renderer/vulkan/vkparse.c b/libs/video/renderer/vulkan/vkparse.c index 23ac80d3f..82ce59c61 100644 --- a/libs/video/renderer/vulkan/vkparse.c +++ b/libs/video/renderer/vulkan/vkparse.c @@ -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; } diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index fd8237a85..1316a051e 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -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; } diff --git a/nq/source/host_cmd.c b/nq/source/host_cmd.c index a14149190..e6c8cf5c1 100644 --- a/nq/source/host_cmd.c +++ b/nq/source/host_cmd.c @@ -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) diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index 6746301f0..8a07c30d5 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -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; } diff --git a/ruamoko/include/PropertyList.h b/ruamoko/include/PropertyList.h index cc72dc3f4..a2cca1fc6 100644 --- a/ruamoko/include/PropertyList.h +++ b/ruamoko/include/PropertyList.h @@ -30,7 +30,6 @@ @interface PLItem: Object { 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; diff --git a/ruamoko/include/plist.h b/ruamoko/include/plist.h index 9b5817491..161a1a611 100644 --- a/ruamoko/include/plist.h +++ b/ruamoko/include/plist.h @@ -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 diff --git a/ruamoko/lib/Entity.r b/ruamoko/lib/Entity.r index 12c465df8..9816d1fb9 100644 --- a/ruamoko/lib/Entity.r +++ b/ruamoko/lib/Entity.r @@ -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); } diff --git a/ruamoko/lib/PropertyList.r b/ruamoko/lib/PropertyList.r index 02f28fb54..c165d7192 100644 --- a/ruamoko/lib/PropertyList.r +++ b/ruamoko/lib/PropertyList.r @@ -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 diff --git a/ruamoko/lib/plist.r b/ruamoko/lib/plist.r index b961dc0d7..724eac34c 100644 --- a/ruamoko/lib/plist.r +++ b/ruamoko/lib/plist.r @@ -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; diff --git a/tools/qflight/source/entities.c b/tools/qflight/source/entities.c index 0157014f8..26c61638f 100644 --- a/tools/qflight/source/entities.c +++ b/tools/qflight/source/entities.c @@ -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,