Skip to content

Commit

Permalink
serialize cvars
Browse files Browse the repository at this point in the history
  • Loading branch information
RicardoLuis0 authored and madame-rachelle committed Nov 26, 2023
1 parent 74ace89 commit aed85a2
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/common/console/c_cvars.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ class FBaseCVar

void* GetExtraDataPointer();

int pnum = -1;
FName userinfoName;

protected:
virtual void DoSet (UCVarValue value, ECVarType type) = 0;
virtual void InstantiateZSCVar()
Expand Down
13 changes: 13 additions & 0 deletions src/common/engine/serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1757,6 +1757,19 @@ void SerializeFunctionPointer(FSerializer &arc, const char *key, FunctionPointer
}
}

bool FSerializer::ReadOptionalInt(const char * key, int &into)
{
if(!isReading()) return false;

auto val = r->FindKey(key);
if(val && val->IsInt())
{
into = val->GetInt();
return true;
}
return false;
}

#include "renderstyle.h"
FSerializer& Serialize(FSerializer& arc, const char* key, FRenderStyle& style, FRenderStyle* def)
{
Expand Down
4 changes: 4 additions & 0 deletions src/common/engine/serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ class FSerializer
FSerializer &AddString(const char *key, const char *charptr);
const char *GetString(const char *key);
FSerializer &ScriptNum(const char *key, int &num);


bool ReadOptionalInt(const char * key, int &into);

bool isReading() const
{
return r != nullptr;
Expand Down
8 changes: 5 additions & 3 deletions src/d_netinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ void D_SetupUserInfo ()
// Reset everybody's userinfo to a default state.
for (i = 0; i < MAXPLAYERS; i++)
{
players[i].userinfo.Reset();
players[i].userinfo.Reset(i);
}
// Initialize the console player's user info
coninfo = &players[consoleplayer].userinfo;
Expand Down Expand Up @@ -426,7 +426,7 @@ void D_SetupUserInfo ()
R_BuildPlayerTranslation(consoleplayer);
}

void userinfo_t::Reset()
void userinfo_t::Reset(int pnum)
{
// Clear this player's userinfo.
TMapIterator<FName, FBaseCVar *> it(*this);
Expand Down Expand Up @@ -469,6 +469,9 @@ void userinfo_t::Reset()
newcvar->SetExtraDataPointer(cvar); // store backing cvar
}

newcvar->pnum = pnum;
newcvar->userinfoName = cvarname;

Insert(cvarname, newcvar);
}
}
Expand Down Expand Up @@ -981,7 +984,6 @@ void ReadUserInfo(FSerializer &arc, userinfo_t &info, FString &skin)
const char *key;
const char *str;

info.Reset();
skin = "";
if (arc.BeginObject("userinfo"))
{
Expand Down
5 changes: 5 additions & 0 deletions src/g_game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1981,8 +1981,12 @@ void C_SerializeCVars(FSerializer& arc, const char* label, uint32_t filter)
}


void SetupLoadingCVars();
void FinishLoadingCVars();

void G_DoLoadGame ()
{
SetupLoadingCVars();
bool hidecon;

if (gameaction != ga_autoloadgame)
Expand Down Expand Up @@ -2125,6 +2129,7 @@ void G_DoLoadGame ()
// load a base level
bool demoplaybacksave = demoplayback;
G_InitNew(map.GetChars(), false);
FinishLoadingCVars();
demoplayback = demoplaybacksave;
savegamerestore = false;

Expand Down
2 changes: 1 addition & 1 deletion src/playsim/bots/b_bot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ void FCajunMaster::ClearPlayer (int i, bool keepTeam)
}
players[i].~player_t();
::new(&players[i]) player_t;
players[i].userinfo.Reset();
players[i].userinfo.Reset(i);
playeringame[i] = false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/playsim/d_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
return *static_cast<FBoolCVar *>(*CheckKey(NAME_Wi_NoAutostartMap));
}

void Reset();
void Reset(int pnum);
int TeamChanged(int team);
int SkinChanged(const char *skinname, int playerclass);
int SkinNumChanged(int skinnum);
Expand Down
1 change: 1 addition & 0 deletions src/playsim/p_user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1620,6 +1620,7 @@ void player_t::Serialize(FSerializer &arc)

if (arc.isReading())
{
userinfo.Reset(mo->Level->PlayerNum(this));
ReadUserInfo(arc, userinfo, skinname);
}
else
Expand Down
82 changes: 82 additions & 0 deletions src/scripting/thingdef_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,15 @@ static int propcmp(const void * a, const void * b)
//==========================================================================
void InitImports();

struct UserInfoCVarNamePlayer
{
FBaseCVar** addr;
FString name;
int pnum;
};

TArray<UserInfoCVarNamePlayer> LoadGameUserInfoCVars;

void InitThingdef()
{
// Some native types need size and serialization information added before the scripts get compiled.
Expand Down Expand Up @@ -803,6 +812,79 @@ void InitThingdef()
auto fspp = NewStruct("FSpawnParticleParams", nullptr);
fspp->Size = sizeof(FSpawnParticleParams);
fspp->Align = alignof(FSpawnParticleParams);

auto cvst = NewStruct("CVar", nullptr, true);
NewPointer(cvst, false)->InstallHandlers(
[](FSerializer &arc, const char *key, const void *addr)
{
const FBaseCVar * self = *(const FBaseCVar**)addr;

if(self)
{
arc.BeginObject(key);


if(self->pnum != -1)
{
int32_t pnum = self->pnum;
FName name = self->userinfoName;
arc("name", name);
arc("player", pnum);
}
else
{
FString name = self->GetName();
arc("name", name);
}

arc.EndObject();
}
},
[](FSerializer &arc, const char *key, void *addr)
{
FBaseCVar ** self = (FBaseCVar**)addr;

FString name;
arc.BeginObject(key);

arc("name", name);

FBaseCVar * backing = FindCVar(name.GetChars(), nullptr);
if(!backing)
{
I_Error("Attempt to load pointer to inexisted CVar '%s'", name.GetChars());
}
else if((backing->GetFlags() & (CVAR_USERINFO|CVAR_IGNORE)) == CVAR_USERINFO)
{
if(int pnum; arc.ReadOptionalInt("player", pnum))
{
*self = nullptr;
LoadGameUserInfoCVars.Push({self, name, pnum}); // this needs to be done later, since userinfo isn't loaded yet
arc.EndObject();
return true;
}
}

*self = backing;

arc.EndObject();

return true;
}
);
}

void SetupLoadingCVars()
{
LoadGameUserInfoCVars.Clear();
}

void FinishLoadingCVars()
{
for(UserInfoCVarNamePlayer &cvar : LoadGameUserInfoCVars)
{
(*cvar.addr) = GetCVar(cvar.pnum, cvar.name.GetChars());
}
}

void SynthesizeFlagFields()
Expand Down

0 comments on commit aed85a2

Please sign in to comment.