diff --git a/src/actor.h b/src/actor.h index a32e15277..562984577 100644 --- a/src/actor.h +++ b/src/actor.h @@ -595,7 +595,7 @@ public: AActor &operator= (const AActor &other); ~AActor (); - virtual void Destroy() override; + virtual void OnDestroy() override; virtual void Serialize(FSerializer &arc) override; virtual void PostSerialize() override; virtual void PostBeginPlay() override; // Called immediately before the actor's first tick diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 4f380ee04..41b89f7c4 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -3199,14 +3199,14 @@ void ADehackedPickup::DoPickupSpecial (AActor *toucher) RealPickup = nullptr; } -void ADehackedPickup::Destroy () +void ADehackedPickup::OnDestroy () { if (RealPickup != nullptr) { RealPickup->Destroy (); RealPickup = nullptr; } - Super::Destroy (); + Super::OnDestroy(); } PClassActor *ADehackedPickup::DetermineType () diff --git a/src/d_dehacked.h b/src/d_dehacked.h index 434853bf2..7b21e8694 100644 --- a/src/d_dehacked.h +++ b/src/d_dehacked.h @@ -41,7 +41,7 @@ class ADehackedPickup : public AInventory DECLARE_CLASS (ADehackedPickup, AInventory) HAS_OBJECT_POINTERS public: - void Destroy() override; + void OnDestroy() override; FString PickupMessage (); bool ShouldRespawn (); bool ShouldStay (); diff --git a/src/d_main.cpp b/src/d_main.cpp index 2c6b1c9e9..1fd89c6bf 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2715,7 +2715,6 @@ void D_DoomMain (void) *(afunc->VMPointer) = NULL; } - ReleaseGlobalSymbols(); PClass::StaticShutdown(); GC::FullGC(); // perform one final garbage collection after shutdown @@ -2727,6 +2726,7 @@ void D_DoomMain (void) restart++; PClass::bShutdown = false; + PClass::bShuttingDown = false; } while (1); } diff --git a/src/dobject.cpp b/src/dobject.cpp index b96cc5ff9..ead9848be 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -351,8 +351,18 @@ DObject::~DObject () // //========================================================================== -void DObject::Destroy () +void DObject:: Destroy () { + // We cannot call the VM during shutdown because all the needed data has been or is in the process of being deleted. + if (!PClass::bShuttingDown) + { + IFVIRTUAL(DObject, OnDestroy) + { + VMValue params[1] = { (DObject*)this }; + GlobalVMStack.Call(func, params, 1, nullptr, 0); + } + } + OnDestroy(); ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe; } @@ -555,4 +565,4 @@ DEFINE_ACTION_FUNCTION(DObject, GetClassName) { PARAM_SELF_PROLOGUE(DObject); ACTION_RETURN_INT(self->GetClass()->TypeName); -} \ No newline at end of file +} diff --git a/src/dobject.h b/src/dobject.h index 374d4a8c8..0f99361ef 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -473,7 +473,8 @@ public: // that don't call their base class. void CheckIfSerialized () const; - virtual void Destroy(); + virtual void OnDestroy() {} + void Destroy(); // If you need to replace one object with another and want to // change any pointers from the old object to the new object, diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 99071c520..cc5dfdb4e 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -72,6 +72,7 @@ FTypeTable TypeTable; PSymbolTable GlobalSymbols; TArray PClass::AllClasses; bool PClass::bShutdown; +bool PClass::bShuttingDown; PErrorType *TypeError; PErrorType *TypeAuto; @@ -534,16 +535,9 @@ const char *PType::DescriptiveName() const // //========================================================================== -void ReleaseGlobalSymbols() -{ - TypeTable.Clear(); - GlobalSymbols.ReleaseSymbols(); -} - void PType::StaticInit() { // Add types to the global symbol table. - atterm(ReleaseGlobalSymbols); // Set up TypeTable hash keys. RUNTIME_CLASS(PErrorType)->TypeTableType = RUNTIME_CLASS(PErrorType); @@ -2962,7 +2956,18 @@ void PClass::StaticShutdown () TArray uniqueFPs(64); unsigned int i, j; - FS_Close(); // this must be done before the classes get deleted. + + // Make a full garbage collection here so that all destroyed but uncollected higher level objects that still exist can be properly taken down. + GC::FullGC(); + + // From this point onward no scripts may be called anymore because the data needed by the VM is getting deleted now. + // This flags DObject::Destroy not to call any scripted OnDestroy methods anymore. + bShuttingDown = true; + + // Unless something went wrong, anything left here should be class and type objects only, which do not own any scripts. + TypeTable.Clear(); + GlobalSymbols.ReleaseSymbols(); + for (i = 0; i < PClass::AllClasses.Size(); ++i) { PClass *type = PClass::AllClasses[i]; @@ -2989,7 +2994,6 @@ void PClass::StaticShutdown () { delete[] uniqueFPs[i]; } - TypeTable.Clear(); bShutdown = true; AllClasses.Clear(); @@ -3002,7 +3006,7 @@ void PClass::StaticShutdown () auto cr = ((ClassReg *)*probe); cr->MyClass = nullptr; } - + } //========================================================================== diff --git a/src/dobjtype.h b/src/dobjtype.h index 952f4d627..3035a6eb2 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -883,6 +883,7 @@ public: static TArray AllClasses; static bool bShutdown; + static bool bShuttingDown; }; class PClassType : public PClass @@ -1015,8 +1016,6 @@ public: PSymbolConstString() {} }; -void ReleaseGlobalSymbols(); - // Enumerations for serializing types in an archive ------------------------- enum ETypeVal : BYTE diff --git a/src/dsectoreffect.cpp b/src/dsectoreffect.cpp index e934c5b9d..22acf74bc 100644 --- a/src/dsectoreffect.cpp +++ b/src/dsectoreffect.cpp @@ -39,7 +39,7 @@ DSectorEffect::DSectorEffect () m_Sector = NULL; } -void DSectorEffect::Destroy() +void DSectorEffect::OnDestroy() { if (m_Sector) { @@ -56,7 +56,7 @@ void DSectorEffect::Destroy() m_Sector->lightingdata = NULL; } } - Super::Destroy(); + Super::OnDestroy(); } DSectorEffect::DSectorEffect (sector_t *sector) @@ -87,10 +87,10 @@ DMover::DMover (sector_t *sector) interpolation = NULL; } -void DMover::Destroy() +void DMover::OnDestroy() { StopInterpolation(); - Super::Destroy(); + Super::OnDestroy(); } void DMover::Serialize(FSerializer &arc) diff --git a/src/dsectoreffect.h b/src/dsectoreffect.h index e9327ce70..5139aaabd 100644 --- a/src/dsectoreffect.h +++ b/src/dsectoreffect.h @@ -12,7 +12,7 @@ public: void Serialize(FSerializer &arc); - void Destroy() override; + void OnDestroy() override; sector_t *GetSector() const { return m_Sector; } @@ -35,7 +35,7 @@ protected: DMover (); void Serialize(FSerializer &arc); - void Destroy() override; + void OnDestroy() override; }; class DMovingFloor : public DMover diff --git a/src/dthinker.cpp b/src/dthinker.cpp index 11ba54dbc..ac0abf3c5 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -253,7 +253,7 @@ DThinker::~DThinker () assert(NextThinker == NULL && PrevThinker == NULL); } -void DThinker::Destroy () +void DThinker::OnDestroy () { assert((NextThinker != NULL && PrevThinker != NULL) || (NextThinker == NULL && PrevThinker == NULL)); @@ -261,7 +261,7 @@ void DThinker::Destroy () { Remove(); } - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== diff --git a/src/dthinker.h b/src/dthinker.h index 3d580c3c2..fce3e4f7a 100644 --- a/src/dthinker.h +++ b/src/dthinker.h @@ -66,7 +66,7 @@ class DThinker : public DObject DECLARE_CLASS (DThinker, DObject) public: DThinker (int statnum = STAT_DEFAULT) throw(); - void Destroy () override; + void OnDestroy () override; virtual ~DThinker (); virtual void Tick (); void CallTick(); diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 6d656cbce..ce46daeb3 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1786,7 +1786,7 @@ public: DLightLevel(sector_t * s,int destlevel,int speed); void Serialize(FSerializer &arc); void Tick (); - void Destroy() { Super::Destroy(); m_Sector->lightingdata=NULL; } + void OnDestroy() { Super::OnDestroy(); m_Sector->lightingdata = nullptr; } }; IMPLEMENT_CLASS(DLightLevel, false, false) diff --git a/src/fragglescript/t_script.cpp b/src/fragglescript/t_script.cpp index b5c21632b..1ff4321fa 100644 --- a/src/fragglescript/t_script.cpp +++ b/src/fragglescript/t_script.cpp @@ -184,7 +184,7 @@ DFsScript::~DFsScript() // //========================================================================== -void DFsScript::Destroy() +void DFsScript::OnDestroy() { ClearVariables(true); ClearSections(); @@ -194,7 +194,7 @@ void DFsScript::Destroy() data = NULL; parent = NULL; trigger = NULL; - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== @@ -334,7 +334,7 @@ DRunningScript::DRunningScript(AActor *trigger, DFsScript *owner, int index) // //========================================================================== -void DRunningScript::Destroy() +void DRunningScript::OnDestroy() { int i; DFsVariable *current, *next; @@ -352,7 +352,7 @@ void DRunningScript::Destroy() } variables[i] = NULL; } - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== @@ -421,7 +421,7 @@ DFraggleThinker::DFraggleThinker() // //========================================================================== -void DFraggleThinker::Destroy() +void DFraggleThinker::OnDestroy() { DRunningScript *p = RunningScripts; while (p) @@ -438,7 +438,7 @@ void DFraggleThinker::Destroy() SpawnedThings.Clear(); ActiveThinker = NULL; - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== diff --git a/src/fragglescript/t_script.h b/src/fragglescript/t_script.h index 43f34acd4..7a5c21a10 100644 --- a/src/fragglescript/t_script.h +++ b/src/fragglescript/t_script.h @@ -347,7 +347,7 @@ public: DFsScript(); ~DFsScript(); - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer &ar); DFsVariable *NewVariable(const char *name, int vtype); @@ -662,7 +662,7 @@ class DRunningScript : public DObject public: DRunningScript(AActor *trigger=NULL, DFsScript *owner = NULL, int index = 0) ; - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer &arc); TObjPtr script; @@ -697,7 +697,7 @@ public: bool nocheckposition; DFraggleThinker(); - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer & arc); diff --git a/src/g_inventory/a_artifacts.cpp b/src/g_inventory/a_artifacts.cpp index e67e1247f..e767d4356 100644 --- a/src/g_inventory/a_artifacts.cpp +++ b/src/g_inventory/a_artifacts.cpp @@ -292,10 +292,10 @@ void APowerup::CallEndEffect() // //=========================================================================== -void APowerup::Destroy () +void APowerup::OnDestroy () { CallEndEffect (); - Super::Destroy (); + Super::OnDestroy(); } //=========================================================================== diff --git a/src/g_inventory/a_artifacts.h b/src/g_inventory/a_artifacts.h index 95182ce43..6cd10f637 100644 --- a/src/g_inventory/a_artifacts.h +++ b/src/g_inventory/a_artifacts.h @@ -12,7 +12,7 @@ class APowerup : public AInventory DECLARE_CLASS (APowerup, AInventory) public: virtual void Tick () override; - virtual void Destroy () override; + virtual void OnDestroy() override; virtual bool HandlePickup (AInventory *item) override; virtual AInventory *CreateCopy (AActor *other) override; virtual AInventory *CreateTossable () override; diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index aa00ba8b0..1b26a2db4 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -1137,14 +1137,14 @@ bool AInventory::CallShouldStay() // //=========================================================================== -void AInventory::Destroy () +void AInventory::OnDestroy () { if (Owner != NULL) { Owner->RemoveInventory (this); } Inventory = NULL; - Super::Destroy (); + Super::OnDestroy(); // Although contrived it can theoretically happen that these variables still got a pointer to this item if (SendItemUse == this) SendItemUse = NULL; diff --git a/src/g_inventory/a_pickups.h b/src/g_inventory/a_pickups.h index eedadbdff..db61e3a22 100644 --- a/src/g_inventory/a_pickups.h +++ b/src/g_inventory/a_pickups.h @@ -76,7 +76,7 @@ public: virtual void Serialize(FSerializer &arc) override; virtual void MarkPrecacheSounds() const override; virtual void BeginPlay () override; - virtual void Destroy () override; + virtual void OnDestroy() override; virtual void Tick() override; virtual bool Grind(bool items) override; diff --git a/src/g_inventory/a_weapons.cpp b/src/g_inventory/a_weapons.cpp index 3b3b765d6..750aad952 100644 --- a/src/g_inventory/a_weapons.cpp +++ b/src/g_inventory/a_weapons.cpp @@ -329,7 +329,7 @@ bool AWeapon::Use (bool pickup) // //=========================================================================== -void AWeapon::Destroy() +void AWeapon::OnDestroy() { AWeapon *sister = SisterWeapon; @@ -342,7 +342,7 @@ void AWeapon::Destroy() sister->Destroy(); } } - Super::Destroy(); + Super::OnDestroy(); } //=========================================================================== diff --git a/src/g_inventory/a_weapons.h b/src/g_inventory/a_weapons.h index 8913963cc..efabf1fcf 100644 --- a/src/g_inventory/a_weapons.h +++ b/src/g_inventory/a_weapons.h @@ -145,7 +145,7 @@ public: virtual bool TryPickup (AActor *&toucher) override; virtual bool TryPickupRestricted (AActor *&toucher) override; virtual bool Use (bool pickup) override; - virtual void Destroy() override; + virtual void OnDestroy() override; bool PickupForAmmo(AWeapon *ownedWeapon); void PostMorphWeapon(); diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index 187b215b8..ca92e731f 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -219,7 +219,7 @@ class DCorpsePointer : public DThinker HAS_OBJECT_POINTERS public: DCorpsePointer (AActor *ptr); - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer &arc); TObjPtr Corpse; DWORD Count; // Only the first corpse pointer's count is valid. @@ -271,7 +271,7 @@ DCorpsePointer::DCorpsePointer (AActor *ptr) ++first->Count; } -void DCorpsePointer::Destroy () +void DCorpsePointer::OnDestroy () { // Store the count of corpses in the first thinker in the list TThinkerIterator iterator (STAT_CORPSEPOINTER); @@ -293,7 +293,7 @@ void DCorpsePointer::Destroy () { Corpse->Destroy (); } - Super::Destroy (); + Super::OnDestroy(); } void DCorpsePointer::Serialize(FSerializer &arc) diff --git a/src/g_shared/a_bridge.cpp b/src/g_shared/a_bridge.cpp index bded2b55e..06fbb6ad3 100644 --- a/src/g_shared/a_bridge.cpp +++ b/src/g_shared/a_bridge.cpp @@ -8,12 +8,12 @@ class ACustomBridge : public AActor { DECLARE_CLASS (ACustomBridge, AActor) public: - void Destroy() override; + void OnDestroy() override; }; IMPLEMENT_CLASS(ACustomBridge, false, false) -void ACustomBridge::Destroy() +void ACustomBridge::OnDestroy() { // Hexen originally just set a flag to make the bridge balls remove themselves in A_BridgeOrbit. // But this is not safe with custom bridge balls that do not necessarily call that function. @@ -29,5 +29,5 @@ void ACustomBridge::Destroy() thing->Destroy(); } } - Super::Destroy(); + Super::OnDestroy(); } diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index 5ac3cb452..dfa66795c 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -111,10 +111,10 @@ DBaseDecal::DBaseDecal (const DBaseDecal *basis) { } -void DBaseDecal::Destroy () +void DBaseDecal::OnDestroy () { Remove (); - Super::Destroy (); + Super::OnDestroy(); } void DBaseDecal::Remove () @@ -670,10 +670,10 @@ DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, double ix, doubl return decal; } -void DImpactDecal::Destroy () +void DImpactDecal::OnDestroy () { ImpactCount--; - Super::Destroy (); + Super::OnDestroy(); } CCMD (countdecals) diff --git a/src/g_shared/a_flashfader.cpp b/src/g_shared/a_flashfader.cpp index 006b7ef84..504eb7308 100644 --- a/src/g_shared/a_flashfader.cpp +++ b/src/g_shared/a_flashfader.cpp @@ -23,10 +23,10 @@ DFlashFader::DFlashFader (float r1, float g1, float b1, float a1, Blends[1][0]=r2; Blends[1][1]=g2; Blends[1][2]=b2; Blends[1][3]=a2; } -void DFlashFader::Destroy () +void DFlashFader::OnDestroy () { SetBlend (1.f); - Super::Destroy(); + Super::OnDestroy(); } void DFlashFader::Serialize(FSerializer &arc) diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index b48a126cd..0ca8e3945 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -690,13 +690,13 @@ void AMorphedMonster::Serialize(FSerializer &arc) ("flagsave", FlagsSave); } -void AMorphedMonster::Destroy () +void AMorphedMonster::OnDestroy () { if (UnmorphedMe != NULL) { UnmorphedMe->Destroy (); } - Super::Destroy (); + Super::OnDestroy(); } void AMorphedMonster::Die (AActor *source, AActor *inflictor, int dmgflags) diff --git a/src/g_shared/a_sectoraction.cpp b/src/g_shared/a_sectoraction.cpp index 2d7037551..e19abade0 100644 --- a/src/g_shared/a_sectoraction.cpp +++ b/src/g_shared/a_sectoraction.cpp @@ -47,7 +47,7 @@ bool ASectorAction::IsActivatedByUse() const return ActivatedByUse; } -void ASectorAction::Destroy () +void ASectorAction::OnDestroy () { if (Sector != nullptr) { @@ -72,7 +72,7 @@ void ASectorAction::Destroy () Sector = nullptr; } - Super::Destroy (); + Super::OnDestroy(); } void ASectorAction::BeginPlay () diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 001df5488..96dbb1531 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -24,7 +24,7 @@ public: DBaseDecal (const DBaseDecal *basis); void Serialize(FSerializer &arc); - void Destroy() override; + void OnDestroy() override; FTextureID StickToWall(side_t *wall, double x, double y, F3DFloor * ffloor); double GetRealZ (const side_t *wall) const; void SetShade (DWORD rgb); @@ -66,7 +66,7 @@ public: static DImpactDecal *StaticCreate(const FDecalTemplate *tpl, const DVector3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color = 0); void BeginPlay (); - void Destroy() override; + void OnDestroy() override; protected: DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const; @@ -88,7 +88,7 @@ class ASkyViewpoint : public AActor DECLARE_CLASS (ASkyViewpoint, AActor) public: void BeginPlay (); - void Destroy() override; + void OnDestroy() override; }; // For an EE compatible linedef based definition. @@ -116,7 +116,7 @@ public: DFlashFader (float r1, float g1, float b1, float a1, float r2, float g2, float b2, float a2, float time, AActor *who); - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer &arc); void Tick (); AActor *WhoFor() { return ForWho; } @@ -207,7 +207,7 @@ public: void Serialize(FSerializer &arc); void Die (AActor *source, AActor *inflictor, int dmgflags); - void Destroy() override; + void OnDestroy() override; TObjPtr UnmorphedMe; int UnmorphTime, MorphStyle; diff --git a/src/g_shared/a_skies.cpp b/src/g_shared/a_skies.cpp index b2098f206..72ad6a7ee 100644 --- a/src/g_shared/a_skies.cpp +++ b/src/g_shared/a_skies.cpp @@ -56,7 +56,7 @@ void ASkyViewpoint::BeginPlay () } } -void ASkyViewpoint::Destroy () +void ASkyViewpoint::OnDestroy () { // remove all sector references to ourselves. for (auto &s : sectorPortals) @@ -70,7 +70,7 @@ void ASkyViewpoint::Destroy () } } - Super::Destroy(); + Super::OnDestroy(); } IMPLEMENT_CLASS(ASkyCamCompat, false, false) @@ -157,7 +157,7 @@ class ASectorSilencer : public AActor DECLARE_CLASS (ASectorSilencer, AActor) public: void BeginPlay (); - void Destroy() override; + void OnDestroy() override; }; IMPLEMENT_CLASS(ASectorSilencer, false, false) @@ -168,12 +168,12 @@ void ASectorSilencer::BeginPlay () Sector->Flags |= SECF_SILENT; } -void ASectorSilencer::Destroy () +void ASectorSilencer::OnDestroy () { if (Sector != nullptr) { Sector->Flags &= ~SECF_SILENT; } - Super::Destroy (); + Super::OnDestroy(); } diff --git a/src/g_shared/a_soundsequence.cpp b/src/g_shared/a_soundsequence.cpp index 304017fba..1352e72de 100644 --- a/src/g_shared/a_soundsequence.cpp +++ b/src/g_shared/a_soundsequence.cpp @@ -104,7 +104,7 @@ class ASoundSequence : public AActor { DECLARE_CLASS (ASoundSequence, AActor) public: - void Destroy() override; + void OnDestroy() override; void PostBeginPlay (); void Activate (AActor *activator); void Deactivate (AActor *activator); @@ -119,10 +119,10 @@ IMPLEMENT_CLASS(ASoundSequence, false, false) // //========================================================================== -void ASoundSequence::Destroy () +void ASoundSequence::OnDestroy () { SN_StopSequence (this); - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== diff --git a/src/g_shared/a_specialspot.cpp b/src/g_shared/a_specialspot.cpp index 335f10ace..46a9ccc41 100644 --- a/src/g_shared/a_specialspot.cpp +++ b/src/g_shared/a_specialspot.cpp @@ -220,13 +220,13 @@ DSpotState::DSpotState () // //---------------------------------------------------------------------------- -void DSpotState::Destroy () +void DSpotState::OnDestroy () { SpotLists.Clear(); SpotLists.ShrinkToFit(); SpotState = NULL; - Super::Destroy(); + Super::OnDestroy(); } //---------------------------------------------------------------------------- @@ -389,11 +389,11 @@ void ASpecialSpot::BeginPlay() // //---------------------------------------------------------------------------- -void ASpecialSpot::Destroy() +void ASpecialSpot::OnDestroy() { DSpotState *state = DSpotState::GetSpotState(false); if (state != NULL) state->RemoveSpot(this); - Super::Destroy(); + Super::OnDestroy(); } // Mace spawn spot ---------------------------------------------------------- diff --git a/src/g_shared/a_specialspot.h b/src/g_shared/a_specialspot.h index 57a643bdd..3b1e772d1 100644 --- a/src/g_shared/a_specialspot.h +++ b/src/g_shared/a_specialspot.h @@ -11,7 +11,7 @@ class ASpecialSpot : public AActor public: void BeginPlay(); - void Destroy() override; + void OnDestroy() override; }; @@ -28,7 +28,7 @@ public: DSpotState (); - void Destroy() override; + void OnDestroy() override; void Tick (); static DSpotState *GetSpotState(bool create = true); FSpotList *FindSpotList(PClassActor *type); diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 7b7a2849a..d681eebad 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -341,7 +341,7 @@ public: }; DBaseStatusBar (int reltop, int hres=320, int vres=200); - void Destroy() override; + void OnDestroy() override; void SetScaled (bool scale, bool force=false); diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index cb3ada8e9..009b480b7 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -258,7 +258,7 @@ DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres) // //--------------------------------------------------------------------------- -void DBaseStatusBar::Destroy () +void DBaseStatusBar::OnDestroy () { for (size_t i = 0; i < countof(Messages); ++i) { @@ -271,7 +271,7 @@ void DBaseStatusBar::Destroy () } Messages[i] = NULL; } - Super::Destroy(); + Super::OnDestroy(); } //--------------------------------------------------------------------------- diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index 5f0d31552..98b5d1315 100644 --- a/src/gl/dynlights/a_dynlight.cpp +++ b/src/gl/dynlights/a_dynlight.cpp @@ -805,10 +805,10 @@ void ADynamicLight::UnlinkLight () while (touching_sector) touching_sector = DeleteLightNode(touching_sector); } -void ADynamicLight::Destroy() +void ADynamicLight::OnDestroy() { UnlinkLight(); - Super::Destroy(); + Super::OnDestroy(); } diff --git a/src/gl/dynlights/gl_dynlight.h b/src/gl/dynlights/gl_dynlight.h index f71f0dfdf..25d091150 100644 --- a/src/gl/dynlights/gl_dynlight.h +++ b/src/gl/dynlights/gl_dynlight.h @@ -108,7 +108,7 @@ public: void BeginPlay(); void SetOrigin (double x, double y, double z, bool moving = false); void PostBeginPlay(); - void Destroy(); + void OnDestroy() override; void Activate(AActor *activator); void Deactivate(AActor *activator); void SetOffset(const DVector3 &pos); diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 2416f01c4..2612bdd63 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -204,7 +204,7 @@ void DIntermissionScreen::Drawer () if (!mFlatfill) screen->FillBorder (NULL); } -void DIntermissionScreen::Destroy() +void DIntermissionScreen::OnDestroy() { if (mPaletteChanged) { @@ -222,7 +222,7 @@ void DIntermissionScreen::Destroy() M_EnableMenu(true); } S_StopSound(CHAN_VOICE); - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== @@ -874,9 +874,9 @@ void DIntermissionController::Drawer () } } -void DIntermissionController::Destroy () +void DIntermissionController::OnDestroy () { - Super::Destroy(); + Super::OnDestroy(); if (mScreen != NULL) mScreen->Destroy(); if (mDeleteDesc) delete mDesc; mDesc = NULL; diff --git a/src/intermission/intermission.h b/src/intermission/intermission.h index 25b369a3a..0f2c38dde 100644 --- a/src/intermission/intermission.h +++ b/src/intermission/intermission.h @@ -176,7 +176,7 @@ public: virtual int Responder (event_t *ev); virtual int Ticker (); virtual void Drawer (); - void Destroy() override; + void OnDestroy() override; FTextureID GetBackground(bool *fill) { *fill = mFlatfill; @@ -301,7 +301,7 @@ public: bool Responder (event_t *ev); void Ticker (); void Drawer (); - void Destroy() override; + void OnDestroy() override; friend void F_AdvanceIntermission(); }; diff --git a/src/menu/colorpickermenu.cpp b/src/menu/colorpickermenu.cpp index e1ee3566d..0d92e1e45 100644 --- a/src/menu/colorpickermenu.cpp +++ b/src/menu/colorpickermenu.cpp @@ -95,7 +95,7 @@ public: desc->CalcIndent(); } - void Destroy() override + void OnDestroy() override { if (mStartItem >= 0) { diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 73183ca22..457b020b4 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -103,7 +103,7 @@ protected: char savegamestring[SAVESTRINGSIZE]; DLoadSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); - void Destroy() override; + void OnDestroy() override; int RemoveSaveSlot (int index); void UnloadSaveData (); @@ -461,12 +461,12 @@ DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc) commentBottom = commentTop + commentHeight; } -void DLoadSaveMenu::Destroy() +void DLoadSaveMenu::OnDestroy() { if (currentSavePic != nullptr) delete currentSavePic; currentSavePic = nullptr; ClearSaveStuff (); - Super::Destroy(); + Super::OnDestroy(); } //============================================================================= @@ -928,7 +928,7 @@ class DSaveMenu : public DLoadSaveMenu public: DSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); - void Destroy() override; + void OnDestroy() override; void DoSave (FSaveGameNode *node); bool Responder (event_t *ev); bool MenuEvent (int mkey, bool fromcontroller); @@ -968,7 +968,7 @@ DSaveMenu::DSaveMenu(DMenu *parent, FListMenuDescriptor *desc) // //============================================================================= -void DSaveMenu::Destroy() +void DSaveMenu::OnDestroy() { if (SaveGames[0] == &NewSaveNode) { @@ -976,7 +976,7 @@ void DSaveMenu::Destroy() if (Selected == 0) Selected = -1; else Selected--; } - Super::Destroy(); + Super::OnDestroy(); } //============================================================================= diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index c406fc701..86b7c3bfe 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -63,7 +63,7 @@ class DMessageBoxMenu : public DMenu public: DMessageBoxMenu(DMenu *parent = NULL, const char *message = NULL, int messagemode = 0, bool playsound = false, FName action = NAME_None); - void Destroy() override; + void OnDestroy() override; void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false); void Drawer(); bool Responder(event_t *ev); @@ -124,11 +124,11 @@ void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, // //============================================================================= -void DMessageBoxMenu::Destroy() +void DMessageBoxMenu::OnDestroy() { if (mMessage != NULL) V_FreeBrokenLines(mMessage); mMessage = NULL; - Super::Destroy(); + Super::OnDestroy(); } //============================================================================= diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 4f7f2fea7..0de02656d 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -829,12 +829,12 @@ public: // //============================================================================= - void Destroy() + void OnDestroy() override { V_FreeBrokenLines(mDialogueLines); mDialogueLines = NULL; I_SetMusicVolume (1.f); - Super::Destroy(); + Super::OnDestroy(); } bool DimAllowed() diff --git a/src/p_floor.cpp b/src/p_floor.cpp index d81ec8bf4..2fd205a9d 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -869,7 +869,7 @@ void DElevator::Serialize(FSerializer &arc) // //========================================================================== -void DElevator::Destroy() +void DElevator::OnDestroy() { if (m_Interp_Ceiling != NULL) { @@ -881,7 +881,7 @@ void DElevator::Destroy() m_Interp_Floor->DelRef(); m_Interp_Floor = NULL; } - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 80545bb14..54dbca780 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1770,7 +1770,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) } } - // play the sound before changing the state, so that AActor::Destroy can call S_RelinkSounds on it and the death state can override it. + // play the sound before changing the state, so that AActor::OnDestroy can call S_RelinkSounds on it and the death state can override it. if (mo->DeathSound) { S_Sound (mo, CHAN_VOICE, mo->DeathSound, 1, @@ -4920,7 +4920,7 @@ void AActor::CallDeactivate(AActor *activator) // //=========================================================================== -void AActor::Destroy () +void AActor::OnDestroy () { ClearRenderSectorList(); ClearRenderLineList(); @@ -4938,7 +4938,7 @@ void AActor::Destroy () // Transform any playing sound into positioned, non-actor sounds. S_RelinkSound (this, NULL); - Super::Destroy (); + Super::OnDestroy(); } //=========================================================================== diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index d603edc8a..77316ad2c 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -52,7 +52,7 @@ DPillar::DPillar () { } -void DPillar::Destroy() +void DPillar::OnDestroy() { if (m_Interp_Ceiling != NULL) { @@ -64,7 +64,7 @@ void DPillar::Destroy() m_Interp_Floor->DelRef(); m_Interp_Floor = NULL; } - Super::Destroy(); + Super::OnDestroy(); } void DPillar::Serialize(FSerializer &arc) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 4349a7c02..66ae0207a 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -1665,7 +1665,7 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, SetSafeFlash) // //------------------------------------------------------------------------ -void DPSprite::Destroy() +void DPSprite::OnDestroy() { // Do not crash if this gets called on partially initialized objects. if (Owner != nullptr && Owner->psprites != nullptr) @@ -1688,7 +1688,7 @@ void DPSprite::Destroy() GC::WriteBarrier(Next); } } - Super::Destroy(); + Super::OnDestroy(); } //------------------------------------------------------------------------ diff --git a/src/p_pspr.h b/src/p_pspr.h index 9c535e7d0..130e27ce2 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -75,6 +75,7 @@ public: AActor* GetCaller() { return Caller; } void SetCaller(AActor *newcaller) { Caller = newcaller; } void ResetInterpolation() { oldx = x; oldy = y; } + void OnDestroy() override; double x, y; double oldx, oldy; @@ -87,7 +88,6 @@ private: void Serialize(FSerializer &arc); void Tick(); - void Destroy() override; public: // must be public to be able to generate the field export tables. Grrr... TObjPtr Caller; diff --git a/src/p_scroll.cpp b/src/p_scroll.cpp index 403eb3087..11de6023f 100644 --- a/src/p_scroll.cpp +++ b/src/p_scroll.cpp @@ -45,7 +45,7 @@ public: DScroller (EScroll type, double dx, double dy, int control, int affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all); DScroller (double dx, double dy, const line_t *l, int control, int accel, EScrollPos scrollpos = EScrollPos::scw_all); - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer &arc); void Tick (); @@ -306,7 +306,7 @@ DScroller::DScroller (EScroll type, double dx, double dy, } } -void DScroller::Destroy () +void DScroller::OnDestroy () { for(int i=0;i<3;i++) { @@ -316,7 +316,7 @@ void DScroller::Destroy () m_Interpolations[i] = NULL; } } - Super::Destroy(); + Super::OnDestroy(); } //----------------------------------------------------------------------------- diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 614ed92bd..c7c59aaa9 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4188,6 +4188,11 @@ static void P_Shutdown () P_FreeLevelData (); P_FreeExtraLevelData (); ST_Clear(); + FS_Close(); + for (auto &p : players) + { + if (p.psprites != nullptr) p.psprites->Destroy(); + } } #if 0 diff --git a/src/p_spec.h b/src/p_spec.h index a2fd0727a..c5e7b2f5c 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -243,7 +243,7 @@ public: void Serialize(FSerializer &arc); void Tick (); - void Destroy() override; + void OnDestroy() override; protected: EPillar m_Type; @@ -574,7 +574,7 @@ public: DElevator (sector_t *sec); - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer &arc); void Tick (); diff --git a/src/po_man.cpp b/src/po_man.cpp index e8c1cbbb8..c2c8f5a7d 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -187,7 +187,7 @@ DPolyAction::DPolyAction (int polyNum) SetInterpolation (); } -void DPolyAction::Destroy() +void DPolyAction::OnDestroy() { FPolyObj *poly = PO_GetPolyobj (m_PolyObj); @@ -197,7 +197,7 @@ void DPolyAction::Destroy() } StopInterpolation(); - Super::Destroy(); + Super::OnDestroy(); } void DPolyAction::Stop() diff --git a/src/po_man.h b/src/po_man.h index 4d78fa179..34a735f05 100644 --- a/src/po_man.h +++ b/src/po_man.h @@ -12,7 +12,7 @@ class DPolyAction : public DThinker public: DPolyAction(int polyNum); void Serialize(FSerializer &arc); - void Destroy() override; + void OnDestroy() override; void Stop(); double GetSpeed() const { return m_Speed; } diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 92dc683a8..2c7197a44 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -62,7 +62,7 @@ public: DSectorPlaneInterpolation() {} DSectorPlaneInterpolation(sector_t *sector, bool plane, bool attach); - void Destroy() override; + void OnDestroy() override; void UpdateInterpolation(); void Restore(); void Interpolate(double smoothratio); @@ -91,7 +91,7 @@ public: DSectorScrollInterpolation() {} DSectorScrollInterpolation(sector_t *sector, bool plane); - void Destroy() override; + void OnDestroy() override; void UpdateInterpolation(); void Restore(); void Interpolate(double smoothratio); @@ -119,7 +119,7 @@ public: DWallScrollInterpolation() {} DWallScrollInterpolation(side_t *side, int part); - void Destroy() override; + void OnDestroy() override; void UpdateInterpolation(); void Restore(); void Interpolate(double smoothratio); @@ -146,7 +146,7 @@ public: DPolyobjInterpolation() {} DPolyobjInterpolation(FPolyObj *poly); - void Destroy() override; + void OnDestroy() override; void UpdateInterpolation(); void Restore(); void Interpolate(double smoothratio); @@ -364,11 +364,11 @@ int DInterpolation::DelRef(bool force) // //========================================================================== -void DInterpolation::Destroy() +void DInterpolation::OnDestroy() { interpolator.RemoveInterpolation(this); refcount = 0; - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== @@ -419,7 +419,7 @@ DSectorPlaneInterpolation::DSectorPlaneInterpolation(sector_t *_sector, bool _pl // //========================================================================== -void DSectorPlaneInterpolation::Destroy() +void DSectorPlaneInterpolation::OnDestroy() { if (sector != nullptr) { @@ -437,7 +437,7 @@ void DSectorPlaneInterpolation::Destroy() { attached[i]->DelRef(); } - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== @@ -597,7 +597,7 @@ DSectorScrollInterpolation::DSectorScrollInterpolation(sector_t *_sector, bool _ // //========================================================================== -void DSectorScrollInterpolation::Destroy() +void DSectorScrollInterpolation::OnDestroy() { if (sector != nullptr) { @@ -611,7 +611,7 @@ void DSectorScrollInterpolation::Destroy() } sector = nullptr; } - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== @@ -702,14 +702,14 @@ DWallScrollInterpolation::DWallScrollInterpolation(side_t *_side, int _part) // //========================================================================== -void DWallScrollInterpolation::Destroy() +void DWallScrollInterpolation::OnDestroy() { if (side != nullptr) { side->textures[part].interpolation = nullptr; side = nullptr; } - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== @@ -800,13 +800,13 @@ DPolyobjInterpolation::DPolyobjInterpolation(FPolyObj *po) // //========================================================================== -void DPolyobjInterpolation::Destroy() +void DPolyobjInterpolation::OnDestroy() { if (poly != nullptr) { poly->interpolation = nullptr; } - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== diff --git a/src/r_data/r_interpolate.h b/src/r_data/r_interpolate.h index 44ff9bed0..bcb584d02 100644 --- a/src/r_data/r_interpolate.h +++ b/src/r_data/r_interpolate.h @@ -27,7 +27,7 @@ public: int AddRef(); int DelRef(bool force = false); - void Destroy() override; + void OnDestroy() override; virtual void UpdateInterpolation() = 0; virtual void Restore() = 0; virtual void Interpolate(double smoothratio) = 0; diff --git a/src/r_defs.h b/src/r_defs.h index f2c089900..cea9078d2 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -283,7 +283,7 @@ class ASectorAction : public AActor DECLARE_CLASS (ASectorAction, AActor) public: ASectorAction (bool activatedByUse = false); - void Destroy () override; + void OnDestroy() override; void BeginPlay (); void Activate (AActor *source); void Deactivate (AActor *source); diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index 31ed314b7..a8d2dc7d7 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -106,7 +106,7 @@ class DSeqActorNode : public DSeqNode HAS_OBJECT_POINTERS public: DSeqActorNode(AActor *actor, int sequence, int modenum); - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer &arc); void MakeSound(int loop, FSoundID id) { @@ -134,7 +134,7 @@ class DSeqPolyNode : public DSeqNode DECLARE_CLASS(DSeqPolyNode, DSeqNode) public: DSeqPolyNode(FPolyObj *poly, int sequence, int modenum); - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer &arc); void MakeSound(int loop, FSoundID id) { @@ -162,7 +162,7 @@ class DSeqSectorNode : public DSeqNode DECLARE_CLASS(DSeqSectorNode, DSeqNode) public: DSeqSectorNode(sector_t *sec, int chan, int sequence, int modenum); - void Destroy() override; + void OnDestroy() override; void Serialize(FSerializer &arc); void MakeSound(int loop, FSoundID id) { @@ -379,7 +379,7 @@ void DSeqNode::Serialize(FSerializer &arc) } } -void DSeqNode::Destroy() +void DSeqNode::OnDestroy() { // If this sequence was launched by a parent sequence, advance that // sequence now. @@ -405,7 +405,7 @@ void DSeqNode::Destroy() GC::WriteBarrier(m_Next, m_Prev); } ActiveSequences--; - Super::Destroy(); + Super::OnDestroy(); } void DSeqNode::StopAndDestroy () @@ -1041,31 +1041,31 @@ void SN_DoStop (void *source) } } -void DSeqActorNode::Destroy () +void DSeqActorNode::OnDestroy () { if (m_StopSound >= 0) S_StopSound (m_Actor, CHAN_BODY); if (m_StopSound >= 1) MakeSound (0, m_StopSound); - Super::Destroy(); + Super::OnDestroy(); } -void DSeqSectorNode::Destroy () +void DSeqSectorNode::OnDestroy () { if (m_StopSound >= 0) S_StopSound (m_Sector, Channel & 7); if (m_StopSound >= 1) MakeSound (0, m_StopSound); - Super::Destroy(); + Super::OnDestroy(); } -void DSeqPolyNode::Destroy () +void DSeqPolyNode::OnDestroy () { if (m_StopSound >= 0) S_StopSound (m_Poly, CHAN_BODY); if (m_StopSound >= 1) MakeSound (0, m_StopSound); - Super::Destroy(); + Super::OnDestroy(); } //========================================================================== diff --git a/src/s_sndseq.h b/src/s_sndseq.h index 13444f862..57e21caa1 100644 --- a/src/s_sndseq.h +++ b/src/s_sndseq.h @@ -22,7 +22,7 @@ class DSeqNode : public DObject public: void Serialize(FSerializer &arc); void StopAndDestroy (); - void Destroy() override; + void OnDestroy() override; void Tick (); void ChangeData (int seqOffset, int delayTics, float volume, FSoundID currentSoundID); void AddChoice (int seqnum, seqtype_t type); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 232becccc..5751aceac 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -17,8 +17,10 @@ class Object native native static void SetMusicVolume(float vol); native Name GetClassName(); + native void Destroy(); - /*virtual*/ native void Destroy(); + // This does not call into the native method of the same name to avoid problems with objects that get garbage collected late on shutdown. + virtual void OnDestroy() {} } class Thinker : Object native