mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 04:22:34 +00:00
- fixed some garbage collection issues with interpolations:
* FInterpolator depended on external references to prevent its content from getting GC'd. * none of the pointers in the interpolation objects were declared to the GC. The result of these issues was that changing anything about the life cycle of interpolation objects caused corrupted memory crashes when a level was changed.
This commit is contained in:
parent
e4982b1ced
commit
d347415aee
5 changed files with 32 additions and 15 deletions
|
@ -203,6 +203,11 @@ private: \
|
|||
#define IMPLEMENT_ABSTRACT_CLASS(cls) \
|
||||
_IMP_PCLASS(cls,NULL,NULL)
|
||||
|
||||
#define IMPLEMENT_ABSTRACT_POINTY_CLASS(cls) \
|
||||
_IMP_PCLASS(cls,cls::PointerOffsets,NULL) \
|
||||
const size_t cls::PointerOffsets[] = {
|
||||
|
||||
|
||||
enum EObjectFlags
|
||||
{
|
||||
// GC flags
|
||||
|
|
|
@ -335,6 +335,7 @@ static void MarkRoot()
|
|||
SectorMarker->SecNum = 0;
|
||||
}
|
||||
Mark(SectorMarker);
|
||||
Mark(interpolator.Head);
|
||||
// Mark bot stuff.
|
||||
Mark(bglobal.firstthing);
|
||||
Mark(bglobal.body1);
|
||||
|
|
|
@ -3353,6 +3353,7 @@ extern polyblock_t **PolyBlockMap;
|
|||
|
||||
void P_FreeLevelData ()
|
||||
{
|
||||
interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level.
|
||||
Renderer->CleanLevelData();
|
||||
FPolyObj::ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
|
||||
SN_StopAllSequences ();
|
||||
|
@ -3584,7 +3585,6 @@ void P_SetupLevel (const char *lumpname, int position)
|
|||
|
||||
// Free all level data from the previous map
|
||||
P_FreeLevelData ();
|
||||
interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level.
|
||||
|
||||
MapData *map = P_OpenMapData(lumpname, true);
|
||||
if (map == NULL)
|
||||
|
|
|
@ -157,7 +157,10 @@ public:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
IMPLEMENT_ABSTRACT_CLASS(DInterpolation)
|
||||
IMPLEMENT_ABSTRACT_POINTY_CLASS(DInterpolation)
|
||||
DECLARE_POINTER(Next)
|
||||
DECLARE_POINTER(Prev)
|
||||
END_POINTERS
|
||||
IMPLEMENT_CLASS(DSectorPlaneInterpolation)
|
||||
IMPLEMENT_CLASS(DSectorScrollInterpolation)
|
||||
IMPLEMENT_CLASS(DWallScrollInterpolation)
|
||||
|
@ -213,9 +216,9 @@ void FInterpolator::UpdateInterpolations()
|
|||
void FInterpolator::AddInterpolation(DInterpolation *interp)
|
||||
{
|
||||
interp->Next = Head;
|
||||
if (Head != NULL) Head->Prev = &interp->Next;
|
||||
if (Head != NULL) Head->Prev = interp;
|
||||
interp->Prev = NULL;
|
||||
Head = interp;
|
||||
interp->Prev = &Head;
|
||||
count++;
|
||||
}
|
||||
|
||||
|
@ -227,14 +230,19 @@ void FInterpolator::AddInterpolation(DInterpolation *interp)
|
|||
|
||||
void FInterpolator::RemoveInterpolation(DInterpolation *interp)
|
||||
{
|
||||
if (interp->Prev != NULL)
|
||||
if (Head == interp)
|
||||
{
|
||||
*interp->Prev = interp->Next;
|
||||
if (interp->Next != NULL) interp->Next->Prev = interp->Prev;
|
||||
interp->Next = NULL;
|
||||
interp->Prev = NULL;
|
||||
count--;
|
||||
Head = interp->Next;
|
||||
if (Head != NULL) Head->Prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (interp->Prev != NULL) interp->Prev->Next = interp->Next;
|
||||
if (interp->Next != NULL) interp->Next->Prev = interp->Prev;
|
||||
}
|
||||
interp->Next = NULL;
|
||||
interp->Prev = NULL;
|
||||
count--;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -285,13 +293,15 @@ void FInterpolator::RestoreInterpolations()
|
|||
|
||||
void FInterpolator::ClearInterpolations()
|
||||
{
|
||||
for (DInterpolation *probe = Head; probe != NULL; )
|
||||
DInterpolation *probe = Head;
|
||||
Head = NULL;
|
||||
while (probe != NULL)
|
||||
{
|
||||
DInterpolation *next = probe->Next;
|
||||
probe->Next = probe->Prev = NULL;
|
||||
probe->Destroy();
|
||||
probe = next;
|
||||
}
|
||||
Head = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,9 +13,10 @@ class DInterpolation : public DObject
|
|||
friend struct FInterpolator;
|
||||
|
||||
DECLARE_ABSTRACT_CLASS(DInterpolation, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
|
||||
DInterpolation *Next;
|
||||
DInterpolation **Prev;
|
||||
TObjPtr<DInterpolation> Next;
|
||||
TObjPtr<DInterpolation> Prev;
|
||||
int refcount;
|
||||
|
||||
protected:
|
||||
|
@ -40,7 +41,7 @@ public:
|
|||
|
||||
struct FInterpolator
|
||||
{
|
||||
DInterpolation *Head;
|
||||
TObjPtr<DInterpolation> Head;
|
||||
bool didInterp;
|
||||
int count;
|
||||
|
||||
|
|
Loading…
Reference in a new issue