Add Default auto-generated member to scripting structures and improve deserialization

This commit is contained in:
Wojtek Figat
2022-08-01 18:49:54 +02:00
parent 4915e9fea0
commit fe1cab6a7f
11 changed files with 57 additions and 65 deletions

View File

@@ -1148,6 +1148,7 @@ namespace Flax.Build.Bindings
indent += " ";
// Fields
var hasDefaultMember = false;
foreach (var fieldInfo in structureInfo.Fields)
{
contents.AppendLine();
@@ -1164,6 +1165,7 @@ namespace Flax.Build.Bindings
contents.Append("const ");
else if (fieldInfo.IsStatic)
contents.Append("static ");
hasDefaultMember |= string.Equals(fieldInfo.Name, "Default", StringComparison.Ordinal);
string type;
if (fieldInfo.Type.IsArray && (fieldInfo.NoArray || structureInfo.IsPod))
@@ -1234,6 +1236,45 @@ namespace Flax.Build.Bindings
}
}
// Default value
if (!structureInfo.NoDefault && !hasDefaultMember)
{
contents.AppendLine();
contents.Append(indent).AppendLine("private static bool _defaultValid;");
contents.Append(indent).AppendLine($"private static {structureInfo.Name} _default;");
contents.AppendLine();
contents.Append(indent).AppendLine("/// <summary>");
contents.Append(indent).AppendLine($"/// The default <see cref=\"{structureInfo.Name}\"/>.");
contents.Append(indent).AppendLine("/// </summary>");
contents.Append(indent).AppendLine($"public static {structureInfo.Name} Default");
contents.Append(indent).AppendLine("{");
indent += " ";
contents.Append(indent).AppendLine("get");
contents.Append(indent).AppendLine("{");
indent += " ";
contents.Append(indent).AppendLine("if (!_defaultValid)");
contents.Append(indent).AppendLine("{");
indent += " ";
contents.Append(indent).AppendLine("_defaultValid = true;");
contents.Append(indent).AppendLine("object obj = _default;");
contents.Append(indent).AppendLine($"FlaxEngine.Utils.InitStructure(obj, typeof({structureInfo.Name}));");
contents.Append(indent).AppendLine($"_default = ({structureInfo.Name})obj;");
indent = indent.Substring(0, indent.Length - 4);
contents.Append(indent).AppendLine("}");
contents.Append(indent).AppendLine("return _default;");
indent = indent.Substring(0, indent.Length - 4);
contents.Append(indent).AppendLine("}");
indent = indent.Substring(0, indent.Length - 4);
contents.Append(indent).AppendLine("}");
contents.AppendLine();
contents.Append(indent).AppendLine("[System.Runtime.Serialization.OnDeserializing]");
contents.Append(indent).AppendLine("internal void OnDeserializing(System.Runtime.Serialization.StreamingContext context)");
contents.Append(indent).AppendLine("{");
contents.Append(indent).AppendLine(" // Initialize structure with default values to replicate C++ deserialization behavior");
contents.Append(indent).AppendLine(" this = Default;");
contents.Append(indent).AppendLine("}");
}
// Nested types
foreach (var apiTypeInfo in structureInfo.Children)
{

View File

@@ -19,7 +19,7 @@ namespace Flax.Build.Bindings
partial class BindingsGenerator
{
private static readonly Dictionary<string, Type> TypeCache = new Dictionary<string, Type>();
private const int CacheVersion = 15;
private const int CacheVersion = 16;
internal static void Write(BinaryWriter writer, string e)
{

View File

@@ -1113,6 +1113,9 @@ namespace Flax.Build.Bindings
case "nopod":
desc.ForceNoPod = true;
break;
case "nodefault":
desc.NoDefault = true;
break;
case "attributes":
desc.Attributes = tag.Value;
break;

View File

@@ -14,6 +14,7 @@ namespace Flax.Build.Bindings
public List<FieldInfo> Fields = new List<FieldInfo>();
public bool IsAutoSerialization;
public bool ForceNoPod;
public bool NoDefault;
public override bool IsStruct => true;
public override bool IsValueType => true;
@@ -72,6 +73,7 @@ namespace Flax.Build.Bindings
BindingsGenerator.Write(writer, Functions);
writer.Write(IsAutoSerialization);
writer.Write(ForceNoPod);
writer.Write(NoDefault);
base.Write(writer);
}
@@ -82,6 +84,7 @@ namespace Flax.Build.Bindings
Functions = BindingsGenerator.Read(reader, Functions);
IsAutoSerialization = reader.ReadBoolean();
ForceNoPod = reader.ReadBoolean();
NoDefault = reader.ReadBoolean();
base.Read(reader);
}