mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Serialize script fields in "array" + more forgiving deserialization
This commit is contained in:
@@ -60,33 +60,35 @@ extension ScriptFieldType
|
||||
case .Long:
|
||||
return typeof(int64);
|
||||
|
||||
|
||||
case .Byte:
|
||||
return typeof(uint8);
|
||||
return typeof(uint8);
|
||||
case .UShort:
|
||||
return typeof(uint16);
|
||||
return typeof(uint16);
|
||||
case .UInt:
|
||||
return typeof(uint32);
|
||||
return typeof(uint32);
|
||||
case .ULong:
|
||||
return typeof(uint64);
|
||||
return typeof(uint64);
|
||||
|
||||
case .Float:
|
||||
return typeof(float);
|
||||
return typeof(float);
|
||||
case .float2:
|
||||
return typeof(float2);
|
||||
return typeof(float2);
|
||||
case .float3:
|
||||
return typeof(float3);
|
||||
return typeof(float3);
|
||||
case .float4:
|
||||
return typeof(float4);
|
||||
return typeof(float4);
|
||||
|
||||
case .Double:
|
||||
return typeof(double);
|
||||
return typeof(double);
|
||||
case .Double2:
|
||||
return typeof(double2);
|
||||
return typeof(double2);
|
||||
case .Double3:
|
||||
return typeof(double3);
|
||||
return typeof(double3);
|
||||
case .Double4:
|
||||
return typeof(double4);
|
||||
return typeof(double4);
|
||||
|
||||
case .Entity:
|
||||
return typeof(UUID);
|
||||
|
||||
default:
|
||||
return null;
|
||||
|
||||
@@ -195,15 +195,29 @@ class SceneSerializer
|
||||
{
|
||||
let fields = ScriptEngine.GetScriptFieldMap(entity);
|
||||
|
||||
for (var (fieldName, fieldInstance) in fields)
|
||||
writer.Identifier("Fields");
|
||||
|
||||
using (writer.ArrayBlock())
|
||||
{
|
||||
switch (fieldInstance.Field.FieldType)
|
||||
for (var (fieldName, fieldInstance) in fields)
|
||||
{
|
||||
case .Entity, .Enum, .Class, .Struct:
|
||||
// TODO: implement
|
||||
default:
|
||||
writer.Identifier(fieldName);
|
||||
Serialize.Value(writer, ValueView(fieldInstance.Field.FieldType.GetBeefType(), &fieldInstance.[Friend]_data), gBonEnv);
|
||||
if (fieldInstance.Field.FieldType == .None)
|
||||
continue;
|
||||
|
||||
|
||||
switch (fieldInstance.Field.FieldType)
|
||||
{
|
||||
case .Enum, .Class, .Struct:
|
||||
// TODO: implement
|
||||
default:
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -567,28 +581,72 @@ class SceneSerializer
|
||||
|
||||
Try!(reader.EntryEnd());
|
||||
|
||||
bool first = true;
|
||||
|
||||
while (reader.ObjectHasMore())
|
||||
if (Try!(reader.Identifier()) == "Fields")
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
Try!(reader.EntryEnd());
|
||||
Try!(reader.ArrayBlock());
|
||||
|
||||
// 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.
|
||||
bool dontRemoveComma = true;
|
||||
|
||||
StringView fieldName = Try!(reader.Identifier());
|
||||
|
||||
if (fields.ContainsKey(fieldName))
|
||||
// Remove whitespace before the check
|
||||
while (reader..ConsumeEmpty().ArrayHasMore())
|
||||
{
|
||||
var field = ref fields[fieldName];
|
||||
if (dontRemoveComma)
|
||||
dontRemoveComma = false;
|
||||
else
|
||||
{
|
||||
if (reader.[Friend]Check(',', false))
|
||||
reader.EntryEnd();
|
||||
else
|
||||
reader..FileEntrySkip(1).ConsumeEmpty();
|
||||
}
|
||||
|
||||
void* data = &field.[Friend]_data;
|
||||
// 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.
|
||||
// It does matter... in case of an error we should try to skip to the next entry.
|
||||
|
||||
Try!(Deserialize.Value(reader, ValueView(field.Field.FieldType.GetBeefType(), data), gBonEnv));
|
||||
StringView fieldName = Try!(reader.Identifier());
|
||||
|
||||
if (fields.ContainsKey(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;
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user