- more cleanup to reduce references to FArchive.

This commit is contained in:
Christoph Oelckers 2016-09-20 10:59:48 +02:00
parent af6404f763
commit 42e38f6cc1
9 changed files with 159 additions and 565 deletions

View file

@ -453,14 +453,18 @@ void PType::SkipValue(FArchive &ar, int tag)
case VAL_Object:
{
#if 0
DObject *skipper;
ar << skipper;
#endif
break;
}
case VAL_State:
{
#if 0
FState *skipper;
ar << skipper;
#endif
break;
}
case VAL_String:
@ -1739,7 +1743,7 @@ int PStatePointer::GetRegType() const
void PStatePointer::WriteValue(FArchive &ar, const void *addr) const
{
ar.WriteByte(VAL_State);
ar << *(FState **)addr;
//ar << *(FState **)addr;
}
//==========================================================================
@ -1754,7 +1758,7 @@ bool PStatePointer::ReadValue(FArchive &ar, void *addr) const
ar << tag;
if (tag == VAL_State)
{
ar << *(FState **)addr;
//ar << *(FState **)addr;
return true;
}
SkipValue(ar, tag);
@ -1856,6 +1860,7 @@ void PPointer::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
void PPointer::WriteValue(FArchive &ar, const void *addr) const
{
#if 0
if (PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
{
ar.WriteByte(VAL_Object);
@ -1866,6 +1871,7 @@ void PPointer::WriteValue(FArchive &ar, const void *addr) const
assert(0 && "Pointer points to a type we don't handle");
I_Error("Attempt to save pointer to unhandled type");
}
#endif
}
//==========================================================================
@ -1876,6 +1882,7 @@ void PPointer::WriteValue(FArchive &ar, const void *addr) const
bool PPointer::ReadValue(FArchive &ar, void *addr) const
{
#if 0
BYTE tag;
ar << tag;
if (tag == VAL_Object && PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
@ -1884,6 +1891,7 @@ bool PPointer::ReadValue(FArchive &ar, void *addr) const
return true;
}
SkipValue(ar, tag);
#endif
return false;
}

View file

@ -1021,267 +1021,6 @@ FArchive &FArchive::operator<< (FName &n)
return *this;
}
FArchive &FArchive::SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize)
{
DWORD w;
if (m_Storing)
{
if (*(void **)ptr)
{
w = DWORD(((size_t)*ptr - (size_t)ptrbase) / elemSize);
}
else
{
w = ~0u;
}
WriteCount (w);
}
else
{
w = ReadCount ();
if (w != ~0u)
{
*(void **)ptr = (BYTE *)ptrbase + w * elemSize;
}
else
{
*(void **)ptr = NULL;
}
}
return *this;
}
FArchive &FArchive::SerializeObject (DObject *&object, PClass *type)
{
if (!m_ThinkersAllowed && type->IsDescendantOf(RUNTIME_CLASS(DThinker)))
{
assert(true);
I_Error("Tried to serialize a thinker before P_SerializeThinkers");
}
if (!type->IsDescendantOf(RUNTIME_CLASS(PClass)))
{ // a regular object
if (IsStoring())
{
return WriteObject(object);
}
else
{
return ReadObject(object, type);
}
}
else
{ // a class object
if (IsStoring())
{
UserWriteClass((PClass *)object);
}
else
{
UserReadClass(object);
}
return *this;
}
}
FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype)
{
#if 0
BYTE objHead;
const PClass *type;
BYTE playerNum;
DWORD index;
DObject *newobj;
operator<< (objHead);
switch (objHead)
{
case NULL_OBJ:
obj = NULL;
break;
case M1_OBJ:
obj = (DObject *)~0;
break;
case OLD_OBJ:
index = ReadCount();
if (index >= ArchiveToObject.Size())
{
I_Error ("Object reference too high (%u; max is %u)\n", index, ArchiveToObject.Size());
}
obj = ArchiveToObject[index];
break;
case NEW_PLYR_CLS_OBJ:
operator<< (playerNum);
if (m_HubTravel)
{
// If travelling inside a hub, use the existing player actor
type = ReadClass (wanttype);
// Printf ("New player class: %s (%u)\n", type->Name, m_File->Tell());
obj = players[playerNum].mo;
// But also create a new one so that we can get past the one
// stored in the archive.
AActor *tempobj = static_cast<AActor *>(type->CreateNew ());
MapObject (obj != NULL ? obj : tempobj);
tempobj->SerializeUserVars (*this);
tempobj->Serialize (*this);
tempobj->CheckIfSerialized ();
// If this player is not present anymore, keep the new body
// around just so that the load will succeed.
if (obj != NULL)
{
// When the temporary player's inventory items were loaded,
// they became owned by the real player. Undo that now.
for (AInventory *item = tempobj->Inventory; item != NULL; item = item->Inventory)
{
item->Owner = tempobj;
}
tempobj->Destroy ();
}
else
{
obj = tempobj;
players[playerNum].mo = static_cast<APlayerPawn *>(obj);
}
break;
}
/* fallthrough when not travelling to a previous level */
case NEW_CLS_OBJ:
type = ReadClass (wanttype);
// Printf ("New class: %s (%u)\n", type->Name, m_File->Tell());
newobj = obj = type->CreateNew ();
MapObject (obj);
newobj->SerializeUserVars (*this);
newobj->Serialize (*this);
newobj->CheckIfSerialized ();
break;
case NEW_PLYR_OBJ:
operator<< (playerNum);
if (m_HubTravel)
{
type = ReadStoredClass (wanttype);
// Printf ("Use player class: %s (%u)\n", type->Name, m_File->Tell());
obj = players[playerNum].mo;
AActor *tempobj = static_cast<AActor *>(type->CreateNew ());
MapObject (obj != NULL ? obj : tempobj);
tempobj->SerializeUserVars (*this);
tempobj->Serialize (*this);
tempobj->CheckIfSerialized ();
if (obj != NULL)
{
for (AInventory *item = tempobj->Inventory;
item != NULL; item = item->Inventory)
{
item->Owner = tempobj;
}
tempobj->Destroy ();
}
else
{
obj = tempobj;
players[playerNum].mo = static_cast<APlayerPawn *>(obj);
}
break;
}
/* fallthrough when not travelling to a previous level */
case NEW_OBJ:
type = ReadStoredClass (wanttype);
// Printf ("Use class: %s (%u)\n", type->Name, m_File->Tell());
obj = type->CreateNew ();
MapObject (obj);
obj->SerializeUserVars (*this);
obj->Serialize (*this);
obj->CheckIfSerialized ();
break;
default:
I_Error ("Unknown object code (%d) in archive\n", objHead);
}
#endif
return *this;
}
void FArchive::WriteSprite (int spritenum)
{
BYTE id;
if ((unsigned)spritenum >= (unsigned)sprites.Size())
{
spritenum = 0;
}
if (m_SpriteMap[spritenum] < 0)
{
m_SpriteMap[spritenum] = (int)(m_NumSprites++);
id = NEW_SPRITE;
Write (&id, 1);
Write (sprites[spritenum].name, 4);
// Write the current sprite number as a hint, because
// these will only change between different versions.
WriteCount (spritenum);
}
else
{
id = OLD_SPRITE;
Write (&id, 1);
WriteCount (m_SpriteMap[spritenum]);
}
}
int FArchive::ReadSprite ()
{
BYTE id;
Read (&id, 1);
if (id == OLD_SPRITE)
{
DWORD index = ReadCount ();
if (index >= m_NumSprites)
{
I_Error ("Sprite %u has not been read yet\n", index);
}
return m_SpriteMap[index];
}
else if (id == NEW_SPRITE)
{
DWORD name;
DWORD hint;
Read (&name, 4);
hint = ReadCount ();
if (hint >= NumStdSprites || sprites[hint].dwName != name)
{
for (hint = NumStdSprites; hint-- != 0; )
{
if (sprites[hint].dwName == name)
{
break;
}
}
if (hint >= sprites.Size())
{ // Don't know this sprite, so just use the first one
hint = 0;
}
}
m_SpriteMap[m_NumSprites++] = hint;
return hint;
}
else
{
I_Error ("Expected a sprite but got something else\n");
return 0;
}
}
DWORD FArchive::AddName (const char *name)
{
DWORD index;
@ -1388,13 +1127,6 @@ PClass *FArchive::ReadStoredClass (const PClass *wanttype)
return type;
}
DWORD FArchive::MapObject (DObject *obj)
{
DWORD i = ArchiveToObject.Push(obj);
ObjectToArchive[obj] = i;
return i;
}
void FArchive::UserWriteClass (PClass *type)
{
BYTE id;

View file

@ -196,16 +196,10 @@ virtual void Read (void *mem, unsigned int len);
FArchive& operator<< (char *&str);
FArchive& operator<< (FName &n);
FArchive& operator<< (FString &str);
FArchive& SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize);
FArchive& SerializeObject (DObject *&object, PClass *type);
FArchive& WriteObject (DObject *obj);
FArchive& ReadObject (DObject *&obj, PClass *wanttype);
void WriteName (const char *name);
const char *ReadName (); // The returned name disappears with the archive, unlike strings
void WriteSprite (int spritenum);
int ReadSprite ();
inline FArchive& operator<< (SBYTE &c) { return operator<< ((BYTE &)c); }
inline FArchive& operator<< (SWORD &s) { return operator<< ((WORD &)s); }
@ -214,7 +208,6 @@ inline FArchive& operator<< (SQWORD &i) { return operator<< ((QWORD &)i); }
inline FArchive& operator<< (unsigned char *&str) { return operator<< ((char *&)str); }
inline FArchive& operator<< (signed char *&str) { return operator<< ((char *&)str); }
inline FArchive& operator<< (bool &b) { return operator<< ((BYTE &)b); }
inline FArchive& operator<< (DObject* &object) { return ReadObject (object, RUNTIME_CLASS(DObject)); }
void EnableThinkers()
{
@ -229,7 +222,6 @@ inline FArchive& operator<< (DObject* &object) { return ReadObject (object, RUN
protected:
enum { EObjectHashSize = 137 };
DWORD MapObject (DObject *obj);
DWORD WriteClass (PClass *info);
PClass *ReadClass ();
PClass *ReadClass (const PClass *wanttype);
@ -283,60 +275,5 @@ public:
FPNGChunkFile Chunk;
};
inline FArchive &operator<< (FArchive &arc, PalEntry &p)
{
return arc << p.a << p.r << p.g << p.b;
}
struct FStrifeDialogueNode;
struct FSwitchDef;
struct FDoorAnimation;
struct FLinePortal;
FArchive &operator<< (FArchive &arc, FLinePortal &da);
FArchive &operator<< (FArchive &arc, FSectorPortal &da);
template<class T,class TT>
inline FArchive &operator<< (FArchive &arc, TArray<T,TT> &self)
{
if (arc.IsStoring())
{
arc.WriteCount(self.Count);
}
else
{
DWORD numStored = arc.ReadCount();
self.Resize(numStored);
}
for (unsigned int i = 0; i < self.Count; ++i)
{
arc << self.Array[i];
}
return arc;
}
struct sector_t;
struct line_t;
struct vertex_t;
struct side_t;
FArchive &operator<< (FArchive &arc, sector_t *&sec);
FArchive &operator<< (FArchive &arc, const sector_t *&sec);
FArchive &operator<< (FArchive &arc, line_t *&line);
FArchive &operator<< (FArchive &arc, vertex_t *&vert);
FArchive &operator<< (FArchive &arc, side_t *&side);
FArchive &operator<<(FArchive &arc, DAngle &ang);
FArchive &operator<<(FArchive &arc, DVector3 &vec);
FArchive &operator<<(FArchive &arc, DVector2 &vec);
template<typename T, typename TT>
FArchive& operator<< (FArchive& arc, TFlags<T, TT>& flag)
{
return flag.Serialize (arc);
}
#endif //__FARCHIVE_H__

View file

@ -168,10 +168,6 @@ struct FStateLabels
void Destroy(); // intentionally not a destructor!
};
FArchive &operator<< (FArchive &arc, FState *&state);
#include "gametype.h"
struct DmgFactors : public TMap<FName, double>

View file

@ -238,11 +238,6 @@ CCMD (playerclasses)
// 16 pixels of bob
#define MAXBOB 16.
FArchive &operator<< (FArchive &arc, player_t *&p)
{
return arc.SerializePointer (players, (BYTE **)&p, sizeof(*players));
}
// The player_t constructor. Since LogText is not a POD, we cannot just
// memset it all to 0.
player_t::player_t()

View file

@ -194,6 +194,7 @@ bool FRemapTable::operator==(const FRemapTable &o)
void FRemapTable::Serialize(FArchive &arc)
{
#if 0
int n = NumEntries;
arc << NumEntries;
@ -214,6 +215,7 @@ void FRemapTable::Serialize(FArchive &arc)
{
arc << Palette[j];
}
#endif
}
//----------------------------------------------------------------------------

View file

@ -2234,15 +2234,17 @@ FArchive &operator<<(FArchive &arc, FSoundID &sid)
static FArchive &operator<<(FArchive &arc, FSoundChan &chan)
{
arc << chan.SourceType;
#if 0
switch (chan.SourceType)
{
case SOURCE_None: break;
//case SOURCE_Actor: arc << chan.Actor; break;
case SOURCE_Actor: arc << chan.Actor; break;
case SOURCE_Sector: arc << chan.Sector; break;
case SOURCE_Polyobj: /*arc << chan.Poly;*/ break;
case SOURCE_Unattached: arc << chan.Point[0] << chan.Point[1] << chan.Point[2]; break;
default: I_Error("Unknown sound source type %d\n", chan.SourceType); break;
}
#endif
arc << chan.SoundID
<< chan.OrgID
<< chan.Volume

View file

@ -560,14 +560,27 @@ void FSerializer::WriteObjects()
if (isWriting())
{
BeginArray("objects");
// we cannot use the C++11 shorthand syntax here because the array may grow while being processed.
for (unsigned i = 0; i < w->mDObjects.Size(); i++)
{
auto obj = w->mDObjects[i];
player_t *player;
BeginObject(nullptr);
WriteKey("classtype");
w->mWriter.String(w->mDObjects[i]->GetClass()->TypeName.GetChars());
w->mDObjects[i]->SerializeUserVars(*this);
w->mDObjects[i]->Serialize(*this);
w->mDObjects[i]->CheckIfSerialized();
w->mWriter.Key("classtype");
w->mWriter.String(obj->GetClass()->TypeName.GetChars());
if (obj->IsKindOf(RUNTIME_CLASS(AActor)) &&
(player = static_cast<AActor *>(obj)->player) &&
player->mo == obj)
{
w->mWriter.Key("playerindex");
w->mWriter.Int(int(player - players));
}
obj->SerializeUserVars(*this);
obj->Serialize(*this);
obj->CheckIfSerialized();
EndObject();
}
EndArray();

View file

@ -36,223 +36,6 @@
#define OLD_SPRITE ((BYTE)12) // Reference to an old sprite name follows
FArchive &FArchive::WriteObject (DObject *obj)
{
#if 0
player_t *player;
BYTE id[2];
if (obj == NULL)
{
id[0] = NULL_OBJ;
Write (id, 1);
}
else if (obj == (DObject*)~0)
{
id[0] = M1_OBJ;
Write (id, 1);
}
else if (obj->ObjectFlags & OF_EuthanizeMe)
{
// Objects that want to die are not saved to the archive, but
// we leave the pointers to them alone.
id[0] = NULL_OBJ;
Write (id, 1);
}
else
{
PClass *type = obj->GetClass();
DWORD *classarcid;
if (type == RUNTIME_CLASS(DObject))
{
//I_Error ("Tried to save an instance of DObject.\n"
// "This should not happen.\n");
id[0] = NULL_OBJ;
Write (id, 1);
}
else if (NULL == (classarcid = ClassToArchive.CheckKey(type)))
{
// No instances of this class have been written out yet.
// Write out the class, then write out the object. If this
// is an actor controlled by a player, make note of that
// so that it can be overridden when moving around in a hub.
if (obj->IsKindOf (RUNTIME_CLASS (AActor)) &&
(player = static_cast<AActor *>(obj)->player) &&
player->mo == obj)
{
id[0] = NEW_PLYR_CLS_OBJ;
id[1] = (BYTE)(player - players);
Write (id, 2);
}
else
{
id[0] = NEW_CLS_OBJ;
Write (id, 1);
}
WriteClass (type);
// Printf ("Make class %s (%u)\n", type->Name, m_File->Tell());
MapObject (obj);
obj->SerializeUserVars (*this);
obj->Serialize (*this);
obj->CheckIfSerialized ();
}
else
{
// An instance of this class has already been saved. If
// this object has already been written, save a reference
// to the saved object. Otherwise, save a reference to the
// class, then save the object. Again, if this is a player-
// controlled actor, remember that.
DWORD *objarcid = ObjectToArchive.CheckKey(obj);
if (objarcid == NULL)
{
if (obj->IsKindOf (RUNTIME_CLASS (AActor)) &&
(player = static_cast<AActor *>(obj)->player) &&
player->mo == obj)
{
id[0] = NEW_PLYR_OBJ;
id[1] = (BYTE)(player - players);
Write (id, 2);
}
else
{
id[0] = NEW_OBJ;
Write (id, 1);
}
WriteCount (*classarcid);
// Printf ("Reuse class %s (%u)\n", type->Name, m_File->Tell());
MapObject (obj);
obj->SerializeUserVars (*this);
obj->Serialize (*this);
obj->CheckIfSerialized ();
}
else
{
id[0] = OLD_OBJ;
Write (id, 1);
WriteCount (*objarcid);
}
}
}
#endif
return *this;
}
FArchive &operator<< (FArchive &arc, sector_t *&sec)
{
return arc.SerializePointer (sectors, (BYTE **)&sec, sizeof(*sectors));
}
FArchive &operator<< (FArchive &arc, const sector_t *&sec)
{
return arc.SerializePointer (sectors, (BYTE **)&sec, sizeof(*sectors));
}
FArchive &operator<< (FArchive &arc, line_t *&line)
{
return arc.SerializePointer (lines, (BYTE **)&line, sizeof(*lines));
}
FArchive &operator<< (FArchive &arc, vertex_t *&vert)
{
return arc.SerializePointer (vertexes, (BYTE **)&vert, sizeof(*vertexes));
}
FArchive &operator<< (FArchive &arc, side_t *&side)
{
return arc.SerializePointer (sides, (BYTE **)&side, sizeof(*sides));
}
FArchive &operator<<(FArchive &arc, DAngle &ang)
{
arc << ang.Degrees;
return arc;
}
FArchive &operator<<(FArchive &arc, DVector3 &vec)
{
arc << vec.X << vec.Y << vec.Z;
return arc;
}
FArchive &operator<<(FArchive &arc, DVector2 &vec)
{
arc << vec.X << vec.Y;
return arc;
}
//==========================================================================
//
//
//==========================================================================
FArchive &operator<< (FArchive &arc, FState *&state)
{
PClassActor *info;
if (arc.IsStoring ())
{
if (state == NULL)
{
arc.UserWriteClass (RUNTIME_CLASS(AActor));
arc.WriteCount (NULL_STATE_INDEX);
return arc;
}
info = FState::StaticFindStateOwner (state);
if (info != NULL)
{
arc.UserWriteClass (info);
arc.WriteCount ((DWORD)(state - info->OwnedStates));
}
else
{
/* this was never working as intended.
I_Error ("Cannot find owner for state %p:\n"
"%s %c%c %3d [%p] -> %p", state,
sprites[state->sprite].name,
state->GetFrame() + 'A',
state->GetFullbright() ? '*' : ' ',
state->GetTics(),
state->GetAction(),
state->GetNextState());
*/
}
}
else
{
PClassActor *info;
DWORD ofs;
arc.UserReadClass<PClassActor>(info);
ofs = arc.ReadCount ();
if (ofs == NULL_STATE_INDEX && info == RUNTIME_CLASS(AActor))
{
state = NULL;
}
else
{
state = info->OwnedStates + ofs;
}
}
return arc;
}
FArchive &operator<< (FArchive &arc, secplane_t &plane)
{
arc << plane.normal << plane.D;
if (plane.normal.Z != 0)
{ // plane.c should always be non-0. Otherwise, the plane
// would be perfectly vertical. (But then, don't let this crash on a broken savegame...)
plane.negiC = -1 / plane.normal.Z;
}
return arc;
}
void P_SerializeACSScriptNumber(FArchive &arc, int &scriptnum, bool was2byte)
{
@ -272,3 +55,129 @@ void P_SerializeACSScriptNumber(FArchive &arc, int &scriptnum, bool was2byte)
}
}
}
#if 0
// still needed as reference.
FArchive &FArchive::ReadObject(DObject* &obj, PClass *wanttype)
{
BYTE objHead;
const PClass *type;
BYTE playerNum;
DWORD index;
DObject *newobj;
operator<< (objHead);
switch (objHead)
{
case NULL_OBJ:
obj = NULL;
break;
case M1_OBJ:
obj = (DObject *)~0;
break;
case OLD_OBJ:
index = ReadCount();
if (index >= ArchiveToObject.Size())
{
I_Error("Object reference too high (%u; max is %u)\n", index, ArchiveToObject.Size());
}
obj = ArchiveToObject[index];
break;
case NEW_PLYR_CLS_OBJ:
operator<< (playerNum);
if (m_HubTravel)
{
// If travelling inside a hub, use the existing player actor
type = ReadClass(wanttype);
// Printf ("New player class: %s (%u)\n", type->Name, m_File->Tell());
obj = players[playerNum].mo;
// But also create a new one so that we can get past the one
// stored in the archive.
AActor *tempobj = static_cast<AActor *>(type->CreateNew());
MapObject(obj != NULL ? obj : tempobj);
tempobj->SerializeUserVars(*this);
tempobj->Serialize(*this);
tempobj->CheckIfSerialized();
// If this player is not present anymore, keep the new body
// around just so that the load will succeed.
if (obj != NULL)
{
// When the temporary player's inventory items were loaded,
// they became owned by the real player. Undo that now.
for (AInventory *item = tempobj->Inventory; item != NULL; item = item->Inventory)
{
item->Owner = tempobj;
}
tempobj->Destroy();
}
else
{
obj = tempobj;
players[playerNum].mo = static_cast<APlayerPawn *>(obj);
}
break;
}
/* fallthrough when not travelling to a previous level */
case NEW_CLS_OBJ:
type = ReadClass(wanttype);
// Printf ("New class: %s (%u)\n", type->Name, m_File->Tell());
newobj = obj = type->CreateNew();
MapObject(obj);
newobj->SerializeUserVars(*this);
newobj->Serialize(*this);
newobj->CheckIfSerialized();
break;
case NEW_PLYR_OBJ:
operator<< (playerNum);
if (m_HubTravel)
{
type = ReadStoredClass(wanttype);
// Printf ("Use player class: %s (%u)\n", type->Name, m_File->Tell());
obj = players[playerNum].mo;
AActor *tempobj = static_cast<AActor *>(type->CreateNew());
MapObject(obj != NULL ? obj : tempobj);
tempobj->SerializeUserVars(*this);
tempobj->Serialize(*this);
tempobj->CheckIfSerialized();
if (obj != NULL)
{
for (AInventory *item = tempobj->Inventory;
item != NULL; item = item->Inventory)
{
item->Owner = tempobj;
}
tempobj->Destroy();
}
else
{
obj = tempobj;
players[playerNum].mo = static_cast<APlayerPawn *>(obj);
}
break;
}
/* fallthrough when not travelling to a previous level */
case NEW_OBJ:
type = ReadStoredClass(wanttype);
// Printf ("Use class: %s (%u)\n", type->Name, m_File->Tell());
obj = type->CreateNew();
MapObject(obj);
obj->SerializeUserVars(*this);
obj->Serialize(*this);
obj->CheckIfSerialized();
break;
default:
I_Error("Unknown object code (%d) in archive\n", objHead);
}
return *this;
}
#endif