From 02de10f65732639b0b28e1a98d7927a0708f1e0b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 19 Nov 2018 17:05:00 +0100 Subject: [PATCH] - cleaned up the PointerSubstitution code Since the only thing it gets used for is swapping out PlayerPawns it can safely skip all global variables that never point to a live player, which allowed to remove quite a bit of code here that stood in the way of scriptifying more content --- src/b_bot.h | 2 +- src/d_player.h | 1 - src/dobject.cpp | 54 +++++++++-------------------- src/dobject.h | 8 ++--- src/p_user.cpp | 32 ----------------- src/r_data/r_interpolate.cpp | 20 ----------- src/scripting/backend/vmbuilder.cpp | 2 +- 7 files changed, 23 insertions(+), 96 deletions(-) diff --git a/src/b_bot.h b/src/b_bot.h index 27433b533..a3a62b08f 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -116,7 +116,7 @@ public: botinfo_t *botinfo; int spawn_tries; int wanted_botnum; - TObjPtr firstthing; + TObjPtr firstthing; TObjPtr body1; TObjPtr body2; diff --git a/src/d_player.h b/src/d_player.h index 2a8daa4f9..ecb3a71ea 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -372,7 +372,6 @@ public: player_t &operator= (const player_t &p); void Serialize(FSerializer &arc); - size_t FixPointers (const DObject *obj, DObject *replacement); size_t PropagateMark(); void SetLogNumber (int num); diff --git a/src/dobject.cpp b/src/dobject.cpp index 64236bcba..c0139c82d 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -307,7 +307,6 @@ DObject::~DObject () if (!(ObjectFlags & OF_Released)) { // Find all pointers that reference this object and NULL them. - StaticPointerSubstitution(this, NULL); Release(); } } @@ -478,11 +477,15 @@ size_t DObject::PointerSubstitution (DObject *old, DObject *notOld) //========================================================================== // -// +// This once was the main method for pointer cleanup, but +// nowadays its only use is swapping out PlayerPawns. +// This requires pointer fixing throughout all objects and a few +// global variables, but it only needs to look at pointers that +// can point to a player. // //========================================================================== -size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld, bool scandefaults) +size_t DObject::StaticPointerSubstitution (AActor *old, AActor *notOld) { DObject *probe; size_t changed = 0; @@ -497,24 +500,12 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld, bool s last = probe; } - if (scandefaults) - { - for (auto p : PClassActor::AllActorClasses) - { - auto def = GetDefaultByType(p); - if (def != nullptr) - { - def->DObject::PointerSubstitution(old, notOld); - } - } - } - // Go through the bodyque. for (i = 0; i < BODYQUESIZE; ++i) { if (bodyque[i] == old) { - bodyque[i] = static_cast(notOld); + bodyque[i] = notOld; changed++; } } @@ -523,36 +514,25 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld, bool s for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) - changed += players[i].FixPointers (old, notOld); - } - - for (auto &s : level.sectorPortals) - { - if (s.mSkybox == old) { - s.mSkybox = static_cast(notOld); - changed++; + APlayerPawn *replacement = static_cast(notOld); + auto &p = players[i]; + + if (p.mo == old) p.mo = replacement, changed++; + if (p.poisoner.pp == old) p.poisoner = replacement, changed++; + if (p.attacker.pp == old) p.attacker = replacement, changed++; + if (p.camera.pp == old) p.camera = replacement, changed++; + if (p.ConversationNPC.pp == old) p.ConversationNPC = replacement, changed++; + if (p.ConversationPC == old) p.ConversationPC = replacement, changed++; } } // Go through sectors. for (auto &sec : level.sectors) { -#define SECTOR_CHECK(f,t) \ -if (sec.f.pp == static_cast(old)) { sec.f = static_cast(notOld); changed++; } - SECTOR_CHECK( SoundTarget, AActor ); - SECTOR_CHECK( SecActTarget, AActor ); - SECTOR_CHECK( floordata, DSectorEffect ); - SECTOR_CHECK( ceilingdata, DSectorEffect ); - SECTOR_CHECK( lightingdata, DSectorEffect ); -#undef SECTOR_CHECK + if (sec.SoundTarget == old) sec.SoundTarget = notOld; } - // Go through bot stuff. - if (bglobal.firstthing.pp == (AActor *)old) bglobal.firstthing = (AActor *)notOld, ++changed; - if (bglobal.body1.pp == (AActor *)old) bglobal.body1 = (AActor *)notOld, ++changed; - if (bglobal.body2.pp == (AActor *)old) bglobal.body2 = (AActor *)notOld, ++changed; - return changed; } diff --git a/src/dobject.h b/src/dobject.h index 7aeedc57c..fb561e2c6 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -185,6 +185,8 @@ protected: \ #include "dobjgc.h" +class AActor; + class DObject { public: @@ -249,11 +251,9 @@ public: inline FString &StringVar(FName field); template T*& PointerVar(FName field); - // If you need to replace one object with another and want to - // change any pointers from the old object to the new object, - // use this method. + // This is only needed for swapping out PlayerPawns and absolutely nothing else! virtual size_t PointerSubstitution (DObject *old, DObject *notOld); - static size_t StaticPointerSubstitution (DObject *old, DObject *notOld, bool scandefaults = false); + static size_t StaticPointerSubstitution (AActor *old, AActor *notOld); PClass *GetClass() const { diff --git a/src/p_user.cpp b/src/p_user.cpp index a601f1db2..48ad0ee67 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -396,38 +396,6 @@ player_t &player_t::operator=(const player_t &p) return *this; } -// This function supplements the pointer cleanup in dobject.cpp, because -// player_t is not derived from DObject. (I tried it, and DestroyScan was -// unable to properly determine the player object's type--possibly -// because it gets staticly allocated in an array.) -// -// This function checks all the DObject pointers in a player_t and NULLs any -// that match the pointer passed in. If you add any pointers that point to -// DObject (or a subclass), add them here too. - -size_t player_t::FixPointers (const DObject *old, DObject *rep) -{ - APlayerPawn *replacement = static_cast(rep); - size_t changed = 0; - - // The construct *& is used in several of these to avoid the read barriers - // that would turn the pointer we want to check to NULL if the old object - // is pending deletion. - if (mo == old) mo = replacement, changed++; - if (*&poisoner == old) poisoner = replacement, changed++; - if (*&attacker == old) attacker = replacement, changed++; - if (*&camera == old) camera = replacement, changed++; - if (*&Bot == old) Bot = static_cast(rep), changed++; - if (ReadyWeapon == old) ReadyWeapon = static_cast(rep), changed++; - if (PendingWeapon == old) PendingWeapon = static_cast(rep), changed++; - if (*&PremorphWeapon == old) PremorphWeapon = static_cast(rep), changed++; - if (psprites == old) psprites = static_cast(rep), changed++; - if (*&ConversationNPC == old) ConversationNPC = replacement, changed++; - if (*&ConversationPC == old) ConversationPC = replacement, changed++; - if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++; - return changed; -} - size_t player_t::PropagateMark() { GC::Mark(mo); diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 8f73fdcac..e23c012c6 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -67,7 +67,6 @@ public: void Interpolate(double smoothratio); virtual void Serialize(FSerializer &arc); - size_t PointerSubstitution (DObject *old, DObject *notOld); size_t PropagateMark(); }; @@ -535,25 +534,6 @@ void DSectorPlaneInterpolation::Serialize(FSerializer &arc) ("attached", attached); } -//========================================================================== -// -// -// -//========================================================================== - -size_t DSectorPlaneInterpolation::PointerSubstitution (DObject *old, DObject *notOld) -{ - int subst = 0; - for(unsigned i=0; i *ReturnRegs) { - int paramcount = 0; + unsigned paramcount = 0; for (auto &func : emitters) { paramcount += func(build);