Cache and reuse removed mobjs when spawning mobjs

This commit is contained in:
Gustaf Alhäll 2023-11-05 13:52:23 +01:00
parent 5fc7a5c2da
commit 4cf1d7fe10
No known key found for this signature in database
GPG key ID: 6C1F67D690CDEDFD
5 changed files with 29 additions and 3 deletions

View file

@ -51,6 +51,7 @@ typedef struct thinker_s
// killough 11/98: count of how many other objects reference // killough 11/98: count of how many other objects reference
// this one using pointers. Used for garbage collection. // this one using pointers. Used for garbage collection.
INT32 references; INT32 references;
boolean cachable;
#ifdef PARANOIA #ifdef PARANOIA
INT32 debug_mobjtype; INT32 debug_mobjtype;

View file

@ -71,6 +71,7 @@ typedef enum
NUM_THINKERLISTS NUM_THINKERLISTS
} thinklistnum_t; /**< Thinker lists. */ } thinklistnum_t; /**< Thinker lists. */
extern thinker_t thlist[]; extern thinker_t thlist[];
extern mobj_t *mobjcache;
void P_InitThinkers(void); void P_InitThinkers(void);
void P_AddThinker(const thinklistnum_t n, thinker_t *thinker); void P_AddThinker(const thinklistnum_t n, thinker_t *thinker);

View file

@ -45,6 +45,8 @@ actioncache_t actioncachehead;
static mobj_t *overlaycap = NULL; static mobj_t *overlaycap = NULL;
mobj_t *mobjcache = NULL;
void P_InitCachedActions(void) void P_InitCachedActions(void)
{ {
actioncachehead.prev = actioncachehead.next = &actioncachehead; actioncachehead.prev = actioncachehead.next = &actioncachehead;
@ -10659,7 +10661,16 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
type = MT_RAY; type = MT_RAY;
} }
if (mobjcache != NULL)
{
mobj = mobjcache;
mobjcache = mobjcache->hnext;
memset(mobj, 0, sizeof(*mobj));
}
else
{
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
}
// this is officially a mobj, declared as soon as possible. // this is officially a mobj, declared as soon as possible.
mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
@ -11214,7 +11225,9 @@ void P_RemoveMobj(mobj_t *mobj)
INT32 prevreferences; INT32 prevreferences;
if (!mobj->thinker.references) if (!mobj->thinker.references)
{ {
Z_Free(mobj); // No refrrences? Can be removed immediately! :D // no references, dump it directly in the mobj cache
mobj->hnext = mobjcache;
mobjcache = mobj;
return; return;
} }

View file

@ -7806,6 +7806,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
Patch_FreeTag(PU_PATCH_LOWPRIORITY); Patch_FreeTag(PU_PATCH_LOWPRIORITY);
Patch_FreeTag(PU_PATCH_ROTATED); Patch_FreeTag(PU_PATCH_ROTATED);
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1); Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);
mobjcache = NULL;
R_InitializeLevelInterpolators(); R_InitializeLevelInterpolators();

View file

@ -217,6 +217,7 @@ void P_AddThinker(const thinklistnum_t n, thinker_t *thinker)
thlist[n].prev = thinker; thlist[n].prev = thinker;
thinker->references = 0; // killough 11/98: init reference counter to 0 thinker->references = 0; // killough 11/98: init reference counter to 0
thinker->cachable = n == THINK_MOBJ;
#ifdef PARANOIA #ifdef PARANOIA
thinker->debug_mobjtype = MT_NULL; thinker->debug_mobjtype = MT_NULL;
@ -319,8 +320,17 @@ void P_RemoveThinkerDelayed(thinker_t *thinker)
(next->prev = currentthinker = thinker->prev)->next = next; (next->prev = currentthinker = thinker->prev)->next = next;
R_DestroyLevelInterpolators(thinker); R_DestroyLevelInterpolators(thinker);
if (thinker->cachable)
{
// put cachable thinkers in the mobj cache, so we can avoid allocations
((mobj_t *)thinker)->hnext = mobjcache;
mobjcache = (mobj_t *)thinker;
}
else
{
Z_Free(thinker); Z_Free(thinker);
} }
}
// //
// P_RemoveThinker // P_RemoveThinker