From fe1cab6a7f6bda619b013b163359ba3616b0bfbf Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 1 Aug 2022 18:49:54 +0200 Subject: [PATCH] Add `Default` auto-generated member to scripting structures and improve deserialization --- Source/Engine/Physics/D6Joint.cs | 5 --- Source/Engine/Physics/HingeJoint.cs | 5 --- Source/Engine/Physics/Limits.cs | 25 ----------- Source/Engine/Platform/CreateWindowSettings.h | 2 +- Source/Engine/Platform/SettingsBase.cs | 27 +----------- Source/Engine/Render2D/TextLayoutOptions.h | 2 +- Source/Engine/Utilities/Utils.cs | 7 +++- .../Bindings/BindingsGenerator.CSharp.cs | 41 +++++++++++++++++++ .../Bindings/BindingsGenerator.Cache.cs | 2 +- .../Bindings/BindingsGenerator.Parsing.cs | 3 ++ .../Flax.Build/Bindings/StructureInfo.cs | 3 ++ 11 files changed, 57 insertions(+), 65 deletions(-) diff --git a/Source/Engine/Physics/D6Joint.cs b/Source/Engine/Physics/D6Joint.cs index c3125a470..5044ad54a 100644 --- a/Source/Engine/Physics/D6Joint.cs +++ b/Source/Engine/Physics/D6Joint.cs @@ -6,11 +6,6 @@ namespace FlaxEngine { partial struct D6JointDrive { - /// - /// The default structure. - /// - public static readonly D6JointDrive Default = new D6JointDrive(0.0f, 0.0f, float.MaxValue, false); - /// /// Initializes a new instance of the struct. /// diff --git a/Source/Engine/Physics/HingeJoint.cs b/Source/Engine/Physics/HingeJoint.cs index ddb0ed855..8b6155b63 100644 --- a/Source/Engine/Physics/HingeJoint.cs +++ b/Source/Engine/Physics/HingeJoint.cs @@ -4,11 +4,6 @@ namespace FlaxEngine { partial struct HingeJointDrive { - /// - /// The default structure. - /// - public static readonly HingeJointDrive Default = new HingeJointDrive(0.0f, float.MaxValue, 1.0f, false); - /// /// Initializes a new instance of the struct. /// diff --git a/Source/Engine/Physics/Limits.cs b/Source/Engine/Physics/Limits.cs index f067e7e77..a02a2888c 100644 --- a/Source/Engine/Physics/Limits.cs +++ b/Source/Engine/Physics/Limits.cs @@ -4,11 +4,6 @@ namespace FlaxEngine { partial struct SpringParameters { - /// - /// The default structure. - /// - public static readonly SpringParameters Default = new SpringParameters(0.0f, 0.0f); - /// /// Constructs a spring. /// @@ -23,11 +18,6 @@ namespace FlaxEngine partial struct LimitLinearRange { - /// - /// The default structure with empty limit. - /// - public static readonly LimitLinearRange Default = new LimitLinearRange(0.0f, 0.0f); - /// /// Constructs a hard limit. Once the limit is reached the movement of the attached bodies will come to a stop. /// @@ -62,11 +52,6 @@ namespace FlaxEngine partial struct LimitLinear { - /// - /// The default structure with empty limit. - /// - public static readonly LimitLinear Default = new LimitLinear(0.0f); - /// /// Constructs a hard limit. Once the limit is reached the movement of the attached bodies will come to a stop. /// @@ -97,11 +82,6 @@ namespace FlaxEngine partial struct LimitAngularRange { - /// - /// The default structure with empty limit. - /// - public static readonly LimitAngularRange Default = new LimitAngularRange(0.0f, 0.0f); - /// /// Constructs a hard limit. Once the limit is reached the movement of the attached bodies will come to a stop. /// @@ -136,11 +116,6 @@ namespace FlaxEngine partial struct LimitConeRange { - /// - /// The default structure with a 45 degree cone limit. - /// - public static readonly LimitConeRange Default = new LimitConeRange(90.0f, 90.0f); - /// /// Constructs a hard limit. Once the limit is reached the movement of the attached bodies will come to a stop. /// diff --git a/Source/Engine/Platform/CreateWindowSettings.h b/Source/Engine/Platform/CreateWindowSettings.h index 461f07458..d756b26d2 100644 --- a/Source/Engine/Platform/CreateWindowSettings.h +++ b/Source/Engine/Platform/CreateWindowSettings.h @@ -29,7 +29,7 @@ API_ENUM() enum class WindowStartPosition /// /// Settings for new window. /// -API_STRUCT() struct CreateWindowSettings +API_STRUCT(NoDefault) struct CreateWindowSettings { DECLARE_SCRIPTING_TYPE_MINIMAL(CreateWindowSettings); diff --git a/Source/Engine/Platform/SettingsBase.cs b/Source/Engine/Platform/SettingsBase.cs index 84f02129d..505195819 100644 --- a/Source/Engine/Platform/SettingsBase.cs +++ b/Source/Engine/Platform/SettingsBase.cs @@ -16,33 +16,8 @@ namespace FlaxEditor.Content.Settings /// public GraphicsSettings() { - // Initialize PostFx settings with default options (C# structs doesn't support it) + // Initialize PostFx settings with default options (C# structs don't support it) PostProcessSettings = FlaxEngine.PostProcessSettings.Default; } } } - -namespace FlaxEngine -{ - partial struct PostProcessSettings - { - private static PostProcessSettings _default; - - /// - /// The default . - /// - public static PostProcessSettings Default - { - get - { - if (!_default.AmbientOcclusion.Enabled) - { - object obj = _default; - Utils.InitStructure(obj, typeof(PostProcessSettings)); - _default = (PostProcessSettings)obj; - } - return _default; - } - } - } -} diff --git a/Source/Engine/Render2D/TextLayoutOptions.h b/Source/Engine/Render2D/TextLayoutOptions.h index c41e1306e..cccd146d7 100644 --- a/Source/Engine/Render2D/TextLayoutOptions.h +++ b/Source/Engine/Render2D/TextLayoutOptions.h @@ -49,7 +49,7 @@ API_ENUM() enum class TextWrapping /// /// Structure which describes text layout properties. /// -API_STRUCT() struct TextLayoutOptions +API_STRUCT(NoDefault) struct TextLayoutOptions { DECLARE_SCRIPTING_TYPE_MINIMAL(TextLayoutOptions); diff --git a/Source/Engine/Utilities/Utils.cs b/Source/Engine/Utilities/Utils.cs index a2eb05c58..b5213e2c3 100644 --- a/Source/Engine/Utilities/Utils.cs +++ b/Source/Engine/Utilities/Utils.cs @@ -928,7 +928,12 @@ namespace FlaxEngine stream.Write(0); } - internal static void InitStructure(object obj, Type type) + /// + /// Initializes the structure (value type) by inflating it with values from (recursive). + /// + /// The object to initialize. + /// The structure type. + public static void InitStructure(object obj, Type type) { var fields = type.GetFields(BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public); for (var i = 0; i < fields.Length; i++) diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index b8fa0b254..eaafcc615 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -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("/// "); + contents.Append(indent).AppendLine($"/// The default ."); + contents.Append(indent).AppendLine("/// "); + 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) { diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs index 32a35d1e9..ceee5c814 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs @@ -19,7 +19,7 @@ namespace Flax.Build.Bindings partial class BindingsGenerator { private static readonly Dictionary TypeCache = new Dictionary(); - private const int CacheVersion = 15; + private const int CacheVersion = 16; internal static void Write(BinaryWriter writer, string e) { diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs index e9c017692..2f3bb22f1 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs @@ -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; diff --git a/Source/Tools/Flax.Build/Bindings/StructureInfo.cs b/Source/Tools/Flax.Build/Bindings/StructureInfo.cs index a3009d9aa..0fa157506 100644 --- a/Source/Tools/Flax.Build/Bindings/StructureInfo.cs +++ b/Source/Tools/Flax.Build/Bindings/StructureInfo.cs @@ -14,6 +14,7 @@ namespace Flax.Build.Bindings public List Fields = new List(); 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); }