mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-01 06:10:42 +00:00
serialize cvars
This commit is contained in:
parent
74ace89d6e
commit
aed85a25a2
9 changed files with 115 additions and 5 deletions
|
@ -218,6 +218,9 @@ public:
|
|||
|
||||
void* GetExtraDataPointer();
|
||||
|
||||
int pnum = -1;
|
||||
FName userinfoName;
|
||||
|
||||
protected:
|
||||
virtual void DoSet (UCVarValue value, ECVarType type) = 0;
|
||||
virtual void InstantiateZSCVar()
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -108,6 +108,10 @@ public:
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -469,6 +469,9 @@ void userinfo_t::Reset()
|
|||
newcvar->SetExtraDataPointer(cvar); // store backing cvar
|
||||
}
|
||||
|
||||
newcvar->pnum = pnum;
|
||||
newcvar->userinfoName = cvarname;
|
||||
|
||||
Insert(cvarname, newcvar);
|
||||
}
|
||||
}
|
||||
|
@ -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"))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
@ -2125,6 +2129,7 @@ void G_DoLoadGame ()
|
|||
// load a base level
|
||||
bool demoplaybacksave = demoplayback;
|
||||
G_InitNew(map.GetChars(), false);
|
||||
FinishLoadingCVars();
|
||||
demoplayback = demoplaybacksave;
|
||||
savegamerestore = false;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1620,6 +1620,7 @@ void player_t::Serialize(FSerializer &arc)
|
|||
|
||||
if (arc.isReading())
|
||||
{
|
||||
userinfo.Reset(mo->Level->PlayerNum(this));
|
||||
ReadUserInfo(arc, userinfo, skinname);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -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.
|
||||
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue