Added CRandom functions

Unique RNG namespace for client-side effects and HUDs. Identifiers for these cannot clash with identifiers that affect the playsim making them completely safe to use in HUD elements. They also won't be saved.
This commit is contained in:
Boondorl 2024-05-04 20:35:44 -04:00 committed by Ricardo Luís Vaz Silva
commit 597b06ae52
47 changed files with 214 additions and 155 deletions

View file

@ -79,11 +79,11 @@
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
FRandom pr_exrandom("EX_Random");
FRandom pr_exrandom("EX_Random", false);
// PUBLIC DATA DEFINITIONS -------------------------------------------------
FRandom M_Random;
FRandom M_Random(true);
// Global seed. This is modified predictably to initialize every RNG.
uint32_t rngseed;
@ -126,8 +126,8 @@ CCMD(rngseed)
// PRIVATE DATA DEFINITIONS ------------------------------------------------
FRandom *FRandom::RNGList;
static TDeletingArray<FRandom *> NewRNGs;
FRandom *FRandom::RNGList, *FRandom::CRNGList;
static TDeletingArray<FRandom *> NewRNGs, NewCRNGs;
// CODE --------------------------------------------------------------------
@ -139,14 +139,22 @@ static TDeletingArray<FRandom *> NewRNGs;
//
//==========================================================================
FRandom::FRandom ()
: NameCRC (0)
FRandom::FRandom (bool client)
: NameCRC (0), bClient(client)
{
#ifndef NDEBUG
Name = NULL;
#endif
Next = RNGList;
RNGList = this;
if (client)
{
Next = CRNGList;
CRNGList = this;
}
else
{
Next = RNGList;
RNGList = this;
}
Init(0);
}
@ -158,7 +166,7 @@ FRandom::FRandom ()
//
//==========================================================================
FRandom::FRandom (const char *name)
FRandom::FRandom (const char *name, bool client) : bClient(client)
{
NameCRC = CalcCRC32 ((const uint8_t *)name, (unsigned int)strlen (name));
#ifndef NDEBUG
@ -170,7 +178,7 @@ FRandom::FRandom (const char *name)
#endif
// Insert the RNG in the list, sorted by CRC
FRandom **prev = &RNGList, *probe = RNGList;
FRandom **prev = (client ? &CRNGList : &RNGList), * probe = (client ? CRNGList : RNGList);
while (probe != NULL && probe->NameCRC < NameCRC)
{
@ -205,8 +213,8 @@ FRandom::~FRandom ()
FRandom *last = NULL;
prev = &RNGList;
rng = RNGList;
prev = bClient ? &CRNGList : &RNGList;
rng = bClient ? CRNGList : RNGList;
while (rng != NULL && rng != this)
{
@ -237,6 +245,11 @@ void FRandom::StaticClearRandom ()
{
rng->Init(rngseed);
}
for (FRandom* rng = FRandom::CRNGList; rng != NULL; rng = rng->Next)
{
rng->Init(rngseed);
}
}
//==========================================================================
@ -345,15 +358,15 @@ void FRandom::StaticReadRNGState(FSerializer &arc)
//
//==========================================================================
FRandom *FRandom::StaticFindRNG (const char *name)
FRandom *FRandom::StaticFindRNG (const char *name, bool client)
{
uint32_t NameCRC = CalcCRC32 ((const uint8_t *)name, (unsigned int)strlen (name));
// Use the default RNG if this one happens to have a CRC of 0.
if (NameCRC == 0) return &pr_exrandom;
if (NameCRC == 0) return client ? &M_Random : &pr_exrandom;
// Find the RNG in the list, sorted by CRC
FRandom **prev = &RNGList, *probe = RNGList;
FRandom **prev = (client ? &CRNGList : &RNGList), *probe = (client ? CRNGList : RNGList);
while (probe != NULL && probe->NameCRC < NameCRC)
{
@ -364,10 +377,13 @@ FRandom *FRandom::StaticFindRNG (const char *name)
if (probe == NULL || probe->NameCRC != NameCRC)
{
// A matching RNG doesn't exist yet so create it.
probe = new FRandom(name);
probe = new FRandom(name, client);
// Store the new RNG for destruction when ZDoom quits.
NewRNGs.Push(probe);
if (client)
NewCRNGs.Push(probe);
else
NewRNGs.Push(probe);
}
return probe;
}