Serialize script fields in "array" + more forgiving deserialization

This commit is contained in:
Simon Lübeß
2023-07-17 04:04:01 +02:00
parent 88b393157a
commit 66d66d3308
2 changed files with 97 additions and 37 deletions
+3 -1
View File
@@ -60,7 +60,6 @@ extension ScriptFieldType
case .Long: case .Long:
return typeof(int64); return typeof(int64);
case .Byte: case .Byte:
return typeof(uint8); return typeof(uint8);
case .UShort: case .UShort:
@@ -88,6 +87,9 @@ extension ScriptFieldType
case .Double4: case .Double4:
return typeof(double4); return typeof(double4);
case .Entity:
return typeof(UUID);
default: default:
return null; return null;
} }
+66 -8
View File
@@ -195,18 +195,32 @@ class SceneSerializer
{ {
let fields = ScriptEngine.GetScriptFieldMap(entity); let fields = ScriptEngine.GetScriptFieldMap(entity);
writer.Identifier("Fields");
using (writer.ArrayBlock())
{
for (var (fieldName, fieldInstance) in fields) for (var (fieldName, fieldInstance) in fields)
{ {
if (fieldInstance.Field.FieldType == .None)
continue;
switch (fieldInstance.Field.FieldType) switch (fieldInstance.Field.FieldType)
{ {
case .Entity, .Enum, .Class, .Struct: case .Enum, .Class, .Struct:
// TODO: implement // TODO: implement
default: default:
writer.Identifier(fieldName); writer.Identifier(fieldName);
String str = scope .();
fieldInstance.Field.FieldType.ToString(str);
writer.Type(str);
Serialize.Value(writer, ValueView(fieldInstance.Field.FieldType.GetBeefType(), &fieldInstance.[Friend]_data), gBonEnv); Serialize.Value(writer, ValueView(fieldInstance.Field.FieldType.GetBeefType(), &fieldInstance.[Friend]_data), gBonEnv);
} }
} }
} }
}
}); });
} }
@@ -567,17 +581,28 @@ class SceneSerializer
Try!(reader.EntryEnd()); Try!(reader.EntryEnd());
bool first = true; if (Try!(reader.Identifier()) == "Fields")
while (reader.ObjectHasMore())
{ {
if (first) Try!(reader.ArrayBlock());
first = false;
bool dontRemoveComma = true;
// Remove whitespace before the check
while (reader..ConsumeEmpty().ArrayHasMore())
{
if (dontRemoveComma)
dontRemoveComma = false;
else else
Try!(reader.EntryEnd()); {
if (reader.[Friend]Check(',', false))
reader.EntryEnd();
else
reader..FileEntrySkip(1).ConsumeEmpty();
}
// TODO: We could think about doing the Try! a little smarter... // TODO: We could think about doing the Try! a little smarter...
// However we always might just fail to deserialize, so it doesn't really matter. // However we always might just fail to deserialize, so it doesn't really matter.
// It does matter... in case of an error we should try to skip to the next entry.
StringView fieldName = Try!(reader.Identifier()); StringView fieldName = Try!(reader.Identifier());
@@ -585,11 +610,44 @@ class SceneSerializer
{ {
var field = ref fields[fieldName]; var field = ref fields[fieldName];
Result<StringView> fieldTypeName = reader.Type();
if (fieldTypeName case .Err)
{
Log.EngineLogger.Error($"Failed to read field type for field \"{fieldName}\" in script \"{component.ScriptClass.FullName}\" of entity {entity.UUID} (\"{entity.Name}\")");
reader.FileEntrySkip(1);
dontRemoveComma = true;
continue;
}
Result<ScriptFieldType> fieldType = Enum.Parse<ScriptFieldType>(fieldTypeName, true);
if ((fieldType case .Err) || (fieldType != field.Field.FieldType))
{
Log.EngineLogger.Error($"Unexpected field type (\"{fieldTypeName}\" instead of \"{field.Field.FieldType}\" for field: \"{fieldName}\" in script \"{component.ScriptClass.FullName}\" of entity {entity.UUID} (\"{entity.Name}\")");
reader.FileEntrySkip(1);
dontRemoveComma = true;
continue;
}
void* data = &field.[Friend]_data; void* data = &field.[Friend]_data;
Try!(Deserialize.Value(reader, ValueView(field.Field.FieldType.GetBeefType(), data), gBonEnv)); if (Deserialize.Value(reader, ValueView(field.Field.FieldType.GetBeefType(), data), gBonEnv) case .Err)
{
Log.EngineLogger.Error($"Failed to deserialize data for field: \"{fieldName}\" in script \"{component.ScriptClass.FullName}\" of entity {entity.UUID} (\"{entity.Name}\")");
reader.FileEntrySkip(1);
dontRemoveComma = true;
continue;
} }
} }
else
{
Log.EngineLogger.Error($"Script \"{component.ScriptClass.FullName}\" doesn't have a field with name \"{fieldName}\". (Entity {entity.UUID} (\"{entity.Name}\"))");
}
}
Try!(reader.ArrayBlockEnd());
}
} }
return .Ok; return .Ok;