mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 22:11:43 +00:00
- made TObjPtr as trivial as possible.
Mainly to avoid problems with Raze, but eliminating this constructor lets us catch erroneous local definitions via 'auto', which can cause major problems if left undetected.
This commit is contained in:
parent
71ce8aa79a
commit
d1caf3a471
9 changed files with 45 additions and 39 deletions
|
@ -180,27 +180,21 @@ class TObjPtr
|
||||||
DObject *o;
|
DObject *o;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
TObjPtr() = default;
|
|
||||||
TObjPtr(const TObjPtr<T> &q) = default;
|
|
||||||
|
|
||||||
TObjPtr(T q) noexcept
|
constexpr TObjPtr<T>& operator=(T q) noexcept
|
||||||
: pp(q)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
T operator=(T q)
|
|
||||||
{
|
{
|
||||||
pp = q;
|
pp = q;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator=(std::nullptr_t nul)
|
constexpr TObjPtr<T>& operator=(std::nullptr_t nul) noexcept
|
||||||
{
|
{
|
||||||
o = nullptr;
|
o = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// To allow NULL, too.
|
// To allow NULL, too.
|
||||||
T operator=(const int val)
|
TObjPtr<T>& operator=(const int val) noexcept
|
||||||
{
|
{
|
||||||
assert(val == 0);
|
assert(val == 0);
|
||||||
o = nullptr;
|
o = nullptr;
|
||||||
|
@ -208,42 +202,42 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// To allow NULL, too. In Clang NULL is a long.
|
// To allow NULL, too. In Clang NULL is a long.
|
||||||
T operator=(const long val)
|
TObjPtr<T>& operator=(const long val) noexcept
|
||||||
{
|
{
|
||||||
assert(val == 0);
|
assert(val == 0);
|
||||||
o = nullptr;
|
o = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
T Get() noexcept
|
constexpr T Get() noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(pp);
|
return GC::ReadBarrier(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
T ForceGet() noexcept //for situations where the read barrier needs to be skipped.
|
constexpr T ForceGet() noexcept //for situations where the read barrier needs to be skipped.
|
||||||
{
|
{
|
||||||
return pp;
|
return pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator T() noexcept
|
constexpr operator T() noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(pp);
|
return GC::ReadBarrier(pp);
|
||||||
}
|
}
|
||||||
T &operator*() noexcept
|
constexpr T &operator*() noexcept
|
||||||
{
|
{
|
||||||
T q = GC::ReadBarrier(pp);
|
T q = GC::ReadBarrier(pp);
|
||||||
assert(q != NULL);
|
assert(q != NULL);
|
||||||
return *q;
|
return *q;
|
||||||
}
|
}
|
||||||
T operator->() noexcept
|
constexpr T operator->() noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(pp);
|
return GC::ReadBarrier(pp);
|
||||||
}
|
}
|
||||||
bool operator!=(T u) noexcept
|
constexpr bool operator!=(T u) noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(o) != u;
|
return GC::ReadBarrier(o) != u;
|
||||||
}
|
}
|
||||||
bool operator==(T u) noexcept
|
constexpr bool operator==(T u) noexcept
|
||||||
{
|
{
|
||||||
return GC::ReadBarrier(o) == u;
|
return GC::ReadBarrier(o) == u;
|
||||||
}
|
}
|
||||||
|
@ -255,6 +249,17 @@ public:
|
||||||
friend class DObject;
|
friend class DObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is only needed because some parts of GCC do not treat a class with any constructor as trivial.
|
||||||
|
// TObjPtr needs to be fully trivial, though - some parts in the engine depend on it.
|
||||||
|
template<class T>
|
||||||
|
constexpr TObjPtr<T> MakeObjPtr(T t) noexcept
|
||||||
|
{
|
||||||
|
// since this exists to replace the constructor we cannot initialize in the declaration as this would require the constructor we want to avoid.
|
||||||
|
TObjPtr<T> tt;
|
||||||
|
tt = t;
|
||||||
|
return tt;
|
||||||
|
}
|
||||||
|
|
||||||
// Use barrier_cast instead of static_cast when you need to cast
|
// Use barrier_cast instead of static_cast when you need to cast
|
||||||
// the contents of a TObjPtr to a related type.
|
// the contents of a TObjPtr to a related type.
|
||||||
template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
|
template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
|
||||||
|
|
|
@ -540,7 +540,7 @@ public:
|
||||||
|
|
||||||
static const int BODYQUESIZE = 32;
|
static const int BODYQUESIZE = 32;
|
||||||
TObjPtr<AActor*> bodyque[BODYQUESIZE];
|
TObjPtr<AActor*> bodyque[BODYQUESIZE];
|
||||||
TObjPtr<DAutomapBase*> automap = nullptr;
|
TObjPtr<DAutomapBase*> automap = MakeObjPtr<DAutomapBase*>(nullptr);
|
||||||
int bodyqueslot;
|
int bodyqueslot;
|
||||||
|
|
||||||
// For now this merely points to the global player array, but with this in place, access to this array can be moved over to the level.
|
// For now this merely points to the global player array, but with this in place, access to this array can be moved over to the level.
|
||||||
|
@ -690,10 +690,10 @@ public:
|
||||||
|
|
||||||
// links to global game objects
|
// links to global game objects
|
||||||
TArray<TObjPtr<AActor *>> CorpseQueue;
|
TArray<TObjPtr<AActor *>> CorpseQueue;
|
||||||
TObjPtr<DFraggleThinker *> FraggleScriptThinker = nullptr;
|
TObjPtr<DFraggleThinker *> FraggleScriptThinker = MakeObjPtr<DFraggleThinker*>(nullptr);
|
||||||
TObjPtr<DACSThinker*> ACSThinker = nullptr;
|
TObjPtr<DACSThinker*> ACSThinker = MakeObjPtr<DACSThinker*>(nullptr);
|
||||||
|
|
||||||
TObjPtr<DSpotState *> SpotState = nullptr;
|
TObjPtr<DSpotState *> SpotState = MakeObjPtr<DSpotState*>(nullptr);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -84,7 +84,8 @@ public:
|
||||||
void CallDraw(int bottom, int visibility);
|
void CallDraw(int bottom, int visibility);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TObjPtr<DHUDMessageBase*> Next = nullptr;
|
TObjPtr<DHUDMessageBase*> Next = MakeObjPtr<DHUDMessageBase*>(nullptr);
|
||||||
|
;
|
||||||
uint32_t SBarID = 0;
|
uint32_t SBarID = 0;
|
||||||
friend class DBaseStatusBar;
|
friend class DBaseStatusBar;
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_QueueCorpse)
|
||||||
if (corpse) corpse->Destroy();
|
if (corpse) corpse->Destroy();
|
||||||
corpsequeue.Delete(0);
|
corpsequeue.Delete(0);
|
||||||
}
|
}
|
||||||
corpsequeue.Push(self);
|
corpsequeue.Push(MakeObjPtr<AActor*>(self));
|
||||||
GC::WriteBarrier(self);
|
GC::WriteBarrier(self);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -340,7 +340,7 @@ public:
|
||||||
|
|
||||||
AActor *ReadyWeapon = nullptr;
|
AActor *ReadyWeapon = nullptr;
|
||||||
AActor *PendingWeapon = nullptr; // WP_NOCHANGE if not changing
|
AActor *PendingWeapon = nullptr; // WP_NOCHANGE if not changing
|
||||||
TObjPtr<DPSprite*> psprites = nullptr; // view sprites (gun, etc)
|
TObjPtr<DPSprite*> psprites = MakeObjPtr<DPSprite*>(nullptr); // view sprites (gun, etc)
|
||||||
|
|
||||||
int cheats = 0; // bit flags
|
int cheats = 0; // bit flags
|
||||||
int timefreezer = 0; // Player has an active time freezer
|
int timefreezer = 0; // Player has an active time freezer
|
||||||
|
@ -355,8 +355,8 @@ public:
|
||||||
int poisoncount = 0; // screen flash for poison damage
|
int poisoncount = 0; // screen flash for poison damage
|
||||||
FName poisontype = NAME_None; // type of poison damage to apply
|
FName poisontype = NAME_None; // type of poison damage to apply
|
||||||
FName poisonpaintype = NAME_None; // type of Pain state to enter for poison damage
|
FName poisonpaintype = NAME_None; // type of Pain state to enter for poison damage
|
||||||
TObjPtr<AActor*> poisoner = nullptr; // NULL for non-player actors
|
TObjPtr<AActor*> poisoner = MakeObjPtr<AActor*>(nullptr); // NULL for non-player actors
|
||||||
TObjPtr<AActor*> attacker = nullptr; // who did damage (NULL for floors)
|
TObjPtr<AActor*> attacker = MakeObjPtr<AActor*>(nullptr); // who did damage (NULL for floors)
|
||||||
int extralight = 0; // so gun flashes light up areas
|
int extralight = 0; // so gun flashes light up areas
|
||||||
short fixedcolormap = 0; // can be set to REDCOLORMAP, etc.
|
short fixedcolormap = 0; // can be set to REDCOLORMAP, etc.
|
||||||
short fixedlightlevel = 0;
|
short fixedlightlevel = 0;
|
||||||
|
@ -364,19 +364,19 @@ public:
|
||||||
PClassActor *MorphedPlayerClass = nullptr; // [MH] (for SBARINFO) class # for this player instance when morphed
|
PClassActor *MorphedPlayerClass = nullptr; // [MH] (for SBARINFO) class # for this player instance when morphed
|
||||||
int MorphStyle = 0; // which effects to apply for this player instance when morphed
|
int MorphStyle = 0; // which effects to apply for this player instance when morphed
|
||||||
PClassActor *MorphExitFlash = nullptr; // flash to apply when demorphing (cache of value given to MorphPlayer)
|
PClassActor *MorphExitFlash = nullptr; // flash to apply when demorphing (cache of value given to MorphPlayer)
|
||||||
TObjPtr<AActor*> PremorphWeapon = nullptr; // ready weapon before morphing
|
TObjPtr<AActor*> PremorphWeapon = MakeObjPtr<AActor*>(nullptr); // ready weapon before morphing
|
||||||
int chickenPeck = 0; // chicken peck countdown
|
int chickenPeck = 0; // chicken peck countdown
|
||||||
int jumpTics = 0; // delay the next jump for a moment
|
int jumpTics = 0; // delay the next jump for a moment
|
||||||
bool onground = 0; // Identifies if this player is on the ground or other object
|
bool onground = 0; // Identifies if this player is on the ground or other object
|
||||||
|
|
||||||
int respawn_time = 0; // [RH] delay respawning until this tic
|
int respawn_time = 0; // [RH] delay respawning until this tic
|
||||||
TObjPtr<AActor*> camera = nullptr; // [RH] Whose eyes this player sees through
|
TObjPtr<AActor*> camera = MakeObjPtr<AActor*>(nullptr); // [RH] Whose eyes this player sees through
|
||||||
|
|
||||||
int air_finished = 0; // [RH] Time when you start drowning
|
int air_finished = 0; // [RH] Time when you start drowning
|
||||||
|
|
||||||
FName LastDamageType = NAME_None; // [RH] For damage-specific pain and death sounds
|
FName LastDamageType = NAME_None; // [RH] For damage-specific pain and death sounds
|
||||||
|
|
||||||
TObjPtr<AActor*> MUSINFOactor = nullptr; // For MUSINFO purposes
|
TObjPtr<AActor*> MUSINFOactor = MakeObjPtr<AActor*>(nullptr); // For MUSINFO purposes
|
||||||
int8_t MUSINFOtics = 0;
|
int8_t MUSINFOtics = 0;
|
||||||
|
|
||||||
bool settings_controller = false; // Player can control game settings.
|
bool settings_controller = false; // Player can control game settings.
|
||||||
|
@ -384,7 +384,7 @@ public:
|
||||||
int8_t crouchdir = 0;
|
int8_t crouchdir = 0;
|
||||||
|
|
||||||
//Added by MC:
|
//Added by MC:
|
||||||
TObjPtr<DBot*> Bot = nullptr;
|
TObjPtr<DBot*> Bot = MakeObjPtr<DBot*>(nullptr);
|
||||||
|
|
||||||
float BlendR = 0; // [RH] Final blending values
|
float BlendR = 0; // [RH] Final blending values
|
||||||
float BlendG = 0;
|
float BlendG = 0;
|
||||||
|
@ -406,7 +406,7 @@ public:
|
||||||
FWeaponSlots weapons;
|
FWeaponSlots weapons;
|
||||||
|
|
||||||
// [CW] I moved these here for multiplayer conversation support.
|
// [CW] I moved these here for multiplayer conversation support.
|
||||||
TObjPtr<AActor*> ConversationNPC = nullptr, ConversationPC = nullptr;
|
TObjPtr<AActor*> ConversationNPC = MakeObjPtr<AActor*>(nullptr), ConversationPC = MakeObjPtr<AActor*>(nullptr);
|
||||||
DAngle ConversationNPCAngle = 0.;
|
DAngle ConversationNPCAngle = 0.;
|
||||||
bool ConversationFaceTalker = false;
|
bool ConversationFaceTalker = false;
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,6 @@ void T_AddSpawnedThing(FLevelLocals *Level, AActor * ac)
|
||||||
if (Level->FraggleScriptThinker)
|
if (Level->FraggleScriptThinker)
|
||||||
{
|
{
|
||||||
auto &SpawnedThings = Level->FraggleScriptThinker->SpawnedThings;
|
auto &SpawnedThings = Level->FraggleScriptThinker->SpawnedThings;
|
||||||
SpawnedThings.Push(GC::ReadBarrier(ac));
|
SpawnedThings.Push(MakeObjPtr<AActor*>(ac));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,6 @@ DPSprite::DPSprite(player_t *owner, AActor *caller, int id)
|
||||||
Tics(0),
|
Tics(0),
|
||||||
Translation(0),
|
Translation(0),
|
||||||
Flags(0),
|
Flags(0),
|
||||||
Caller(caller),
|
|
||||||
Owner(owner),
|
Owner(owner),
|
||||||
State(nullptr),
|
State(nullptr),
|
||||||
Sprite(0),
|
Sprite(0),
|
||||||
|
@ -181,6 +180,7 @@ DPSprite::DPSprite(player_t *owner, AActor *caller, int id)
|
||||||
ID(id),
|
ID(id),
|
||||||
processPending(true)
|
processPending(true)
|
||||||
{
|
{
|
||||||
|
Caller = caller;
|
||||||
baseScale = {1.0, 1.2};
|
baseScale = {1.0, 1.2};
|
||||||
rotation = 0.;
|
rotation = 0.;
|
||||||
scale = {1.0, 1.0};
|
scale = {1.0, 1.0};
|
||||||
|
|
|
@ -17,8 +17,8 @@ class DInterpolation : public DObject
|
||||||
DECLARE_ABSTRACT_CLASS(DInterpolation, DObject)
|
DECLARE_ABSTRACT_CLASS(DInterpolation, DObject)
|
||||||
HAS_OBJECT_POINTERS
|
HAS_OBJECT_POINTERS
|
||||||
|
|
||||||
TObjPtr<DInterpolation*> Next = nullptr;
|
TObjPtr<DInterpolation*> Next;
|
||||||
TObjPtr<DInterpolation*> Prev = nullptr;
|
TObjPtr<DInterpolation*> Prev;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FLevelLocals *Level;
|
FLevelLocals *Level;
|
||||||
|
@ -46,7 +46,7 @@ public:
|
||||||
|
|
||||||
struct FInterpolator
|
struct FInterpolator
|
||||||
{
|
{
|
||||||
TObjPtr<DInterpolation*> Head = nullptr;
|
TObjPtr<DInterpolation*> Head = MakeObjPtr<DInterpolation*>(nullptr);
|
||||||
bool didInterp = false;
|
bool didInterp = false;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
|
|
@ -833,9 +833,9 @@ void DSeqNode::ActivateSequence (int sequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
DSeqActorNode::DSeqActorNode(AActor* actor, int sequence, int modenum)
|
DSeqActorNode::DSeqActorNode(AActor* actor, int sequence, int modenum)
|
||||||
: DSeqNode (actor->Level, sequence, modenum),
|
: DSeqNode(actor->Level, sequence, modenum)
|
||||||
m_Actor (actor)
|
|
||||||
{
|
{
|
||||||
|
m_Actor = actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
DSeqPolyNode::DSeqPolyNode (FPolyObj *poly, int sequence, int modenum)
|
DSeqPolyNode::DSeqPolyNode (FPolyObj *poly, int sequence, int modenum)
|
||||||
|
|
Loading…
Reference in a new issue