From 1eb91fddcd551a9c4e60892c65ec9a05bc4e8ffc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 11 Jun 2008 12:17:45 +0000 Subject: [PATCH] - Fixed: Wall scrolling interpolations incremented their reference count twice. - Fixed: Before a level's thinkers are loaded all previous interpolations must be cleared. - Fixed: deleted interpolations didn't NULL the pointer in the interpolated object. Also added all interpolation pointers to DSectorMarker to ensure that they are properyl processed by the garbage collector. SVN r1028 (trunk) --- docs/rh-log.txt | 8 +++++ src/dobjgc.cpp | 68 +++++++++++++++++++++++++++++++--------- src/g_level.cpp | 2 ++ src/r_interpolate.cpp | 72 +++++++++++++++++++++++++++++++++++++------ src/r_interpolate.h | 2 ++ src/version.h | 2 +- 6 files changed, 129 insertions(+), 25 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index a99a9204c..498f552d2 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,11 @@ +June 11, 2008 (Changes by Graf Zahl) +- Fixed: Wall scrolling interpolations incremented their reference count twice. +- Fixed: Before a level's thinkers are loaded all previous interpolations must + be cleared. +- Fixed: deleted interpolations didn't NULL the pointer in the interpolated + object. Also added all interpolation pointers to DSectorMarker to ensure + that they are properyl processed by the garbage collector. + June 10, 2008 (Changes by Graf Zahl) - Added scaling to double size for idmypos display. - Changed: Players don't telefrag when they are spawned now but after all diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index ca3344c14..ac59004e1 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -93,6 +93,8 @@ // Number of sectors to mark for each step. #define SECTORSTEPSIZE 32 +#define POLYSTEPSIZE 120 +#define SIDEDEFSTEPSIZE 240 #define GCSTEPSIZE 1024u #define GCSWEEPMAX 40 @@ -108,9 +110,11 @@ class DSectorMarker : public DObject { DECLARE_CLASS(DSectorMarker, DObject) public: - DSectorMarker() : SecNum(0) {} + DSectorMarker() : SecNum(0),PolyNum(0),SideNum(0) {} size_t PropagateMark(); int SecNum; + int PolyNum; + int SideNum; }; IMPLEMENT_CLASS(DSectorMarker) @@ -602,32 +606,66 @@ void DelSoftRoot(DObject *obj) size_t DSectorMarker::PropagateMark() { int i; + int marked = 0; + bool moretodo = false; - if (sectors == NULL) + if (sectors != NULL) { - return 0; + for (i = 0; i < SECTORSTEPSIZE && SecNum + i < numsectors; ++i) + { + sector_t *sec = §ors[SecNum + i]; + GC::Mark(sec->SoundTarget); + GC::Mark(sec->CeilingSkyBox); + GC::Mark(sec->FloorSkyBox); + GC::Mark(sec->SecActTarget); + GC::Mark(sec->floordata); + GC::Mark(sec->ceilingdata); + GC::Mark(sec->lightingdata); + for(int j=0;j<4;j++) GC::Mark(sec->interpolations[j]); + } + marked += i * sizeof(sector_t); + if (SecNum + i < numsectors) + { + SecNum += i; + moretodo = true; + } } - for (i = 0; i < SECTORSTEPSIZE && SecNum + i < numsectors; ++i) + if (!moretodo && polyobjs != NULL) { - sector_t *sec = §ors[SecNum + i]; - GC::Mark(sec->SoundTarget); - GC::Mark(sec->CeilingSkyBox); - GC::Mark(sec->FloorSkyBox); - GC::Mark(sec->SecActTarget); - GC::Mark(sec->floordata); - GC::Mark(sec->ceilingdata); - GC::Mark(sec->lightingdata); + for (i = 0; i < POLYSTEPSIZE && PolyNum + i < po_NumPolyobjs; ++i) + { + GC::Mark(polyobjs[PolyNum + i].interpolation); + } + marked += i * sizeof(FPolyObj); + if (PolyNum + i < po_NumPolyobjs) + { + PolyNum += i; + moretodo = true; + } + } + if (!moretodo && sides != NULL) + { + for (i = 0; i < SIDEDEFSTEPSIZE && SideNum + i < numsides; ++i) + { + side_t *side = &sides[SideNum + i]; + for(int j=0;j<3;j++) GC::Mark(side->textures[j].interpolation); + } + marked += i * sizeof(side_t); + if (SideNum + i < numsides) + { + SideNum += i; + moretodo = true; + } } // If there are more sectors to mark, put ourself back into the gray // list. - if (SecNum + i < numsectors) + if (moretodo) { - SecNum += i; Black2Gray(); GCNext = GC::Gray; GC::Gray = this; } - return i * sizeof(sector_t); + return marked; } //========================================================================== diff --git a/src/g_level.cpp b/src/g_level.cpp index 5fac9d282..c73f50816 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -75,6 +75,7 @@ #include "sbarinfo.h" #include "r_translate.h" #include "p_lnspec.h" +#include "r_interpolate.h" #include "gi.h" @@ -2740,6 +2741,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) } FBehavior::StaticSerializeModuleStates (arc); + if (arc.IsLoading()) interpolator.ClearInterpolations(); P_SerializeThinkers (arc, hubLoad); P_SerializeWorld (arc); P_SerializePolyobjs (arc); diff --git a/src/r_interpolate.cpp b/src/r_interpolate.cpp index cbe1553e6..27cb1ffe8 100644 --- a/src/r_interpolate.cpp +++ b/src/r_interpolate.cpp @@ -88,6 +88,7 @@ public: DSectorScrollInterpolation() {} DSectorScrollInterpolation(sector_t *sector, bool plane); + void Destroy(); void UpdateInterpolation(); void Restore(); void Interpolate(fixed_t smoothratio); @@ -114,6 +115,7 @@ public: DWallScrollInterpolation() {} DWallScrollInterpolation(side_t *side, int part); + void Destroy(); void UpdateInterpolation(); void Restore(); void Interpolate(fixed_t smoothratio); @@ -137,6 +139,7 @@ public: DPolyobjInterpolation() {} DPolyobjInterpolation(FPolyObj *poly); + void Destroy(); void UpdateInterpolation(); void Restore(); void Interpolate(fixed_t smoothratio); @@ -180,14 +183,6 @@ FInterpolator interpolator; int FInterpolator::CountInterpolations () { - int count = 0; - - DInterpolation *probe = Head; - while (probe != NULL) - { - count++; - probe = probe->Next; - } return count; } @@ -217,6 +212,7 @@ void FInterpolator::AddInterpolation(DInterpolation *interp) if (Head != NULL) Head->Prev = &interp->Next; Head = interp; interp->Prev = &Head; + count++; } //========================================================================== @@ -233,6 +229,7 @@ void FInterpolator::RemoveInterpolation(DInterpolation *interp) if (interp->Next != NULL) interp->Next->Prev = interp->Prev; interp->Next = NULL; interp->Prev = NULL; + count--; } } @@ -403,6 +400,17 @@ DSectorPlaneInterpolation::DSectorPlaneInterpolation(sector_t *_sector, bool _pl void DSectorPlaneInterpolation::Destroy() { + if (ceiling) + { + assert(sector->interpolations[sector_t::CeilingMove] == this); + sector->interpolations[sector_t::CeilingMove] = NULL; + } + else + { + assert(sector->interpolations[sector_t::FloorMove] == this); + sector->interpolations[sector_t::FloorMove] = NULL; + } + for(unsigned i=0; iDelRef(); @@ -552,6 +560,27 @@ DSectorScrollInterpolation::DSectorScrollInterpolation(sector_t *_sector, bool _ // //========================================================================== +void DSectorScrollInterpolation::Destroy() +{ + if (ceiling) + { + assert(sector->interpolations[sector_t::CeilingScroll] == this); + sector->interpolations[sector_t::CeilingScroll] = NULL; + } + else + { + assert(sector->interpolations[sector_t::FloorScroll] == this); + sector->interpolations[sector_t::FloorScroll] = NULL; + } + Super::Destroy(); +} + +//========================================================================== +// +// +// +//========================================================================== + void DSectorScrollInterpolation::UpdateInterpolation() { if (!ceiling) @@ -654,6 +683,19 @@ DWallScrollInterpolation::DWallScrollInterpolation(side_t *_side, int _part) // //========================================================================== +void DWallScrollInterpolation::Destroy() +{ + assert(side->textures[part].interpolation == this); + side->textures[part].interpolation = NULL; + Super::Destroy(); +} + +//========================================================================== +// +// +// +//========================================================================== + void DWallScrollInterpolation::UpdateInterpolation() { oldx = side->GetTextureXOffset(part); @@ -726,6 +768,19 @@ DPolyobjInterpolation::DPolyobjInterpolation(FPolyObj *po) // //========================================================================== +void DPolyobjInterpolation::Destroy() +{ + assert(poly->interpolation == this); + poly->interpolation = NULL; + Super::Destroy(); +} + +//========================================================================== +// +// +// +//========================================================================== + void DPolyobjInterpolation::UpdateInterpolation() { for(int i = 0; i < poly->numvertices; i++) @@ -801,7 +856,6 @@ DInterpolation *side_t::SetInterpolation(int position) if (textures[position].interpolation == NULL) { textures[position].interpolation = new DWallScrollInterpolation(this, position); - textures[position].interpolation->AddRef(); } textures[position].interpolation->AddRef(); GC::WriteBarrier(textures[position].interpolation); diff --git a/src/r_interpolate.h b/src/r_interpolate.h index 63716e367..9334827e8 100644 --- a/src/r_interpolate.h +++ b/src/r_interpolate.h @@ -41,6 +41,7 @@ struct FInterpolator { DInterpolation *Head; bool didInterp; + int count; int CountInterpolations (); @@ -49,6 +50,7 @@ public: { Head = NULL; didInterp = false; + count = 0; } void UpdateInterpolations(); void AddInterpolation(DInterpolation *); diff --git a/src/version.h b/src/version.h index 13661243b..b7b66e183 100644 --- a/src/version.h +++ b/src/version.h @@ -75,7 +75,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 1027 +#define MINSAVEVER 1028 #if SVN_REVISION_NUMBER < MINSAVEVER // Never write a savegame with a version lower than what we need