- fixed: To get the final error handling from the serializer, Close must be called before the destructor gets invoked.

- added line feeds to all error messages in the serializer.
This commit is contained in:
Christoph Oelckers 2017-02-27 15:16:03 +01:00
parent 78538ed9ef
commit cc598dfdde
3 changed files with 34 additions and 30 deletions

View file

@ -1624,6 +1624,7 @@ void G_UnSnapshotLevel (bool hubLoad)
} }
} }
} }
arc.Close();
} }
// No reason to keep the snapshot around once the level's been entered. // No reason to keep the snapshot around once the level's been entered.
level.info->Snapshot.Clean(); level.info->Snapshot.Clean();

View file

@ -486,6 +486,8 @@ bool FSerializer::OpenReader(FCompressedBuffer *input)
void FSerializer::Close() void FSerializer::Close()
{ {
if (w == nullptr && r == nullptr) return; // double close? This should skip the I_Error at the bottom.
if (w != nullptr) if (w != nullptr)
{ {
delete w; delete w;
@ -590,7 +592,7 @@ bool FSerializer::BeginObject(const char *name)
} }
else else
{ {
Printf(TEXTCOLOR_RED "Object expected for '%s'", name); Printf(TEXTCOLOR_RED "Object expected for '%s'\n", name);
mErrors++; mErrors++;
return false; return false;
} }
@ -656,7 +658,7 @@ bool FSerializer::BeginArray(const char *name)
} }
else else
{ {
Printf(TEXTCOLOR_RED "Array expected for '%s'", name); Printf(TEXTCOLOR_RED "Array expected for '%s'\n", name);
mErrors++; mErrors++;
return false; return false;
} }
@ -748,7 +750,7 @@ FSerializer &FSerializer::Args(const char *key, int *args, int *defargs, int spe
else else
{ {
assert(false && "Integer expected"); assert(false && "Integer expected");
Printf(TEXTCOLOR_RED "Integer expected for '%s[%d]'", key, i); Printf(TEXTCOLOR_RED "Integer expected for '%s[%d]'\n", key, i);
mErrors++; mErrors++;
} }
} }
@ -756,7 +758,7 @@ FSerializer &FSerializer::Args(const char *key, int *args, int *defargs, int spe
else else
{ {
assert(false && "array expected"); assert(false && "array expected");
Printf(TEXTCOLOR_RED "array expected for '%s'", key); Printf(TEXTCOLOR_RED "array expected for '%s'\n", key);
mErrors++; mErrors++;
} }
} }
@ -800,7 +802,7 @@ FSerializer &FSerializer::ScriptNum(const char *key, int &num)
else else
{ {
assert(false && "Integer expected"); assert(false && "Integer expected");
Printf(TEXTCOLOR_RED "Integer expected for '%s'", key); Printf(TEXTCOLOR_RED "Integer expected for '%s'\n", key);
mErrors++; mErrors++;
} }
} }
@ -1005,7 +1007,7 @@ void FSerializer::ReadObjects(bool hubtravel)
PClass *cls = PClass::FindClass(clsname); PClass *cls = PClass::FindClass(clsname);
if (cls == nullptr) if (cls == nullptr)
{ {
Printf("Unknown object class '%s' in savegame", clsname.GetChars()); Printf(TEXTCOLOR_RED "Unknown object class '%s' in savegame\n", clsname.GetChars());
founderrors = true; founderrors = true;
r->mDObjects[i] = RUNTIME_CLASS(AActor)->CreateNew(); // make sure we got at least a valid pointer for the duration of the loading process. r->mDObjects[i] = RUNTIME_CLASS(AActor)->CreateNew(); // make sure we got at least a valid pointer for the duration of the loading process.
r->mDObjects[i]->Destroy(); // but we do not want to keep this around, so destroy it right away. r->mDObjects[i]->Destroy(); // but we do not want to keep this around, so destroy it right away.
@ -1041,7 +1043,7 @@ void FSerializer::ReadObjects(bool hubtravel)
catch (CRecoverableError &err) catch (CRecoverableError &err)
{ {
// In case something in here throws an error, let's continue and deal with it later. // In case something in here throws an error, let's continue and deal with it later.
Printf(TEXTCOLOR_RED "'%s'\n while restoring %s", err.GetMessage(), obj ? obj->GetClass()->TypeName.GetChars() : "invalid object"); Printf(TEXTCOLOR_RED "'%s'\n while restoring %s\n", err.GetMessage(), obj ? obj->GetClass()->TypeName.GetChars() : "invalid object");
mErrors++; mErrors++;
} }
} }
@ -1055,7 +1057,7 @@ void FSerializer::ReadObjects(bool hubtravel)
assert(!founderrors); assert(!founderrors);
if (founderrors) if (founderrors)
{ {
Printf(TEXTCOLOR_RED "Failed to restore all objects in savegame"); Printf(TEXTCOLOR_RED "Failed to restore all objects in savegame\n");
mErrors++; mErrors++;
} }
} }
@ -1064,7 +1066,7 @@ void FSerializer::ReadObjects(bool hubtravel)
// nuke all objects we created here. // nuke all objects we created here.
for (auto obj : r->mDObjects) for (auto obj : r->mDObjects)
{ {
obj->Destroy(); if (!(obj->ObjectFlags & OF_EuthanizeMe)) obj->Destroy();
} }
r->mDObjects.Clear(); r->mDObjects.Clear();
@ -1182,7 +1184,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, bool &value, bool *def
} }
else else
{ {
Printf(TEXTCOLOR_RED "boolean type expected for '%s'", key); Printf(TEXTCOLOR_RED "boolean type expected for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
} }
} }
@ -1218,7 +1220,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, int64_t &value, int64_
} }
else else
{ {
Printf(TEXTCOLOR_RED "integer type expected for '%s'", key); Printf(TEXTCOLOR_RED "integer type expected for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
} }
} }
@ -1254,7 +1256,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, uint64_t &value, uint6
} }
else else
{ {
Printf(TEXTCOLOR_RED "integer type expected for '%s'", key); Printf(TEXTCOLOR_RED "integer type expected for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
} }
} }
@ -1291,7 +1293,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, int32_t &value, int32_
} }
else else
{ {
Printf(TEXTCOLOR_RED "integer type expected for '%s'", key); Printf(TEXTCOLOR_RED "integer type expected for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
} }
} }
@ -1327,7 +1329,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, uint32_t &value, uint3
} }
else else
{ {
Printf(TEXTCOLOR_RED "integer type expected for '%s'", key); Printf(TEXTCOLOR_RED "integer type expected for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
} }
} }
@ -1405,7 +1407,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, double &value, double
} }
else else
{ {
Printf(TEXTCOLOR_RED "float type expected for '%s'", key); Printf(TEXTCOLOR_RED "float type expected for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
} }
} }
@ -1548,7 +1550,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe
} }
else else
{ {
Printf(TEXTCOLOR_RED "object does not represent a texture for '%s'", key); Printf(TEXTCOLOR_RED "object does not represent a texture for '%s'\n", key);
value.SetNull(); value.SetNull();
arc.mErrors++; arc.mErrors++;
} }
@ -1564,7 +1566,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe
else else
{ {
assert(false && "not a texture"); assert(false && "not a texture");
Printf(TEXTCOLOR_RED "object does not represent a texture for '%s'", key); Printf(TEXTCOLOR_RED "object does not represent a texture for '%s'\n", key);
value.SetNull(); value.SetNull();
arc.mErrors++; arc.mErrors++;
} }
@ -1649,7 +1651,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, DObject *&value, DObje
else else
{ {
assert(false && "invalid object reference"); assert(false && "invalid object reference");
Printf(TEXTCOLOR_RED "Invalid object reference for '%s'", key); Printf(TEXTCOLOR_RED "Invalid object reference for '%s'\n", key);
value = nullptr; value = nullptr;
arc.mErrors++; arc.mErrors++;
if (retcode) *retcode = false; if (retcode) *retcode = false;
@ -1698,7 +1700,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FName &value, FName *d
} }
else else
{ {
Printf(TEXTCOLOR_RED "String expected for '%s'", key); Printf(TEXTCOLOR_RED "String expected for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
value = NAME_None; value = NAME_None;
} }
@ -1746,7 +1748,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FDynamicCol
} }
} }
assert(false && "not a colormap"); assert(false && "not a colormap");
Printf(TEXTCOLOR_RED "object does not represent a colormap for '%s'", key); Printf(TEXTCOLOR_RED "object does not represent a colormap for '%s'\n", key);
cm = &NormalLight; cm = &NormalLight;
} }
} }
@ -1787,7 +1789,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundI
} }
else else
{ {
Printf(TEXTCOLOR_RED "string type expected for '%s'", key); Printf(TEXTCOLOR_RED "string type expected for '%s'\n", key);
sid = 0; sid = 0;
arc.mErrors++; arc.mErrors++;
} }
@ -1836,7 +1838,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClassActor
} }
else else
{ {
Printf(TEXTCOLOR_RED "string type expected for '%s'", key); Printf(TEXTCOLOR_RED "string type expected for '%s'\n", key);
clst = nullptr; clst = nullptr;
arc.mErrors++; arc.mErrors++;
} }
@ -1884,7 +1886,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClass *&cl
} }
else else
{ {
Printf(TEXTCOLOR_RED "string type expected for '%s'", key); Printf(TEXTCOLOR_RED "string type expected for '%s'\n", key);
clst = nullptr; clst = nullptr;
arc.mErrors++; arc.mErrors++;
} }
@ -1960,20 +1962,20 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState
{ {
// this can actually happen by changing the DECORATE so treat it as a warning, not an error. // this can actually happen by changing the DECORATE so treat it as a warning, not an error.
state = nullptr; state = nullptr;
Printf(TEXTCOLOR_ORANGE "Invalid state '%s+%d' for '%s'", cls.GetString(), ndx.GetInt(), key); Printf(TEXTCOLOR_ORANGE "Invalid state '%s+%d' for '%s'\n", cls.GetString(), ndx.GetInt(), key);
} }
} }
else else
{ {
assert(false && "not a state"); assert(false && "not a state");
Printf(TEXTCOLOR_RED "data does not represent a state for '%s'", key); Printf(TEXTCOLOR_RED "data does not represent a state for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
} }
} }
else if (!retcode) else if (!retcode)
{ {
assert(false && "not an array"); assert(false && "not an array");
Printf(TEXTCOLOR_RED "array type expected for '%s'", key); Printf(TEXTCOLOR_RED "array type expected for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
} }
} }
@ -2028,7 +2030,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FStrifeDial
} }
else else
{ {
Printf(TEXTCOLOR_RED "integer expected for '%s'", key); Printf(TEXTCOLOR_RED "integer expected for '%s'\n", key);
arc.mErrors++; arc.mErrors++;
node = nullptr; node = nullptr;
} }
@ -2077,7 +2079,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FString *&p
} }
else else
{ {
Printf(TEXTCOLOR_RED "string expected for '%s'", key); Printf(TEXTCOLOR_RED "string expected for '%s'\n", key);
pstr = nullptr; pstr = nullptr;
arc.mErrors++; arc.mErrors++;
} }
@ -2119,7 +2121,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FString &pstr, FString
} }
else else
{ {
Printf(TEXTCOLOR_RED "string expected for '%s'", key); Printf(TEXTCOLOR_RED "string expected for '%s'\n", key);
pstr = ""; pstr = "";
arc.mErrors++; arc.mErrors++;
} }
@ -2168,7 +2170,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, char *&pstr
} }
else else
{ {
Printf(TEXTCOLOR_RED "string expected for '%s'", key); Printf(TEXTCOLOR_RED "string expected for '%s'\n", key);
pstr = nullptr; pstr = nullptr;
arc.mErrors++; arc.mErrors++;
} }

View file

@ -64,6 +64,7 @@ public:
~FSerializer() ~FSerializer()
{ {
mErrors = 0; // The destructor may not throw an exception so silence the error checker.
Close(); Close();
} }
bool OpenWriter(bool pretty = true); bool OpenWriter(bool pretty = true);