diff --git a/Prowl.Editor/Assets/AssetDatabase.Core.cs b/Prowl.Editor/Assets/AssetDatabase.Core.cs index 7c88b919d..08b3e155d 100644 --- a/Prowl.Editor/Assets/AssetDatabase.Core.cs +++ b/Prowl.Editor/Assets/AssetDatabase.Core.cs @@ -5,6 +5,8 @@ using Prowl.Runtime; using Prowl.Runtime.Utils; +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Debug = Prowl.Runtime.Debug; @@ -576,7 +578,7 @@ public static void SaveAsset(EngineObject assetInstance, bool pingAsset = true) { try { - SerializedProperty serialized = Serializer.Serialize(assetInstance); + EchoObject serialized = Serializer.Serialize(assetInstance); StringTagConverter.WriteToFile(serialized, fileInfo); if(pingAsset) diff --git a/Prowl.Editor/Assets/Importers/MaterialImporter.cs b/Prowl.Editor/Assets/Importers/MaterialImporter.cs index a8e15b968..b930f1523 100644 --- a/Prowl.Editor/Assets/Importers/MaterialImporter.cs +++ b/Prowl.Editor/Assets/Importers/MaterialImporter.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Prowl.Editor.Preferences; using Prowl.Editor.ScriptedEditors; using Prowl.Runtime; @@ -41,7 +43,7 @@ public class MaterialImporterEditor : ScriptedEditor public override void OnEnable() { - SerializedProperty tag = StringTagConverter.ReadFromFile((target as MetaFile).AssetPath); + EchoObject tag = StringTagConverter.ReadFromFile((target as MetaFile).AssetPath); _editingMaterial = Serializer.Deserialize(tag); _editor = CreateEditor(_editingMaterial); diff --git a/Prowl.Editor/Assets/Importers/MeshImporter.cs b/Prowl.Editor/Assets/Importers/MeshImporter.cs index 600fae1d1..d0ccee2be 100644 --- a/Prowl.Editor/Assets/Importers/MeshImporter.cs +++ b/Prowl.Editor/Assets/Importers/MeshImporter.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Prowl.Runtime; using Prowl.Runtime.Utils; diff --git a/Prowl.Editor/Assets/Importers/PrefabImporter.cs b/Prowl.Editor/Assets/Importers/PrefabImporter.cs index 8faf616cc..8b9a3425b 100644 --- a/Prowl.Editor/Assets/Importers/PrefabImporter.cs +++ b/Prowl.Editor/Assets/Importers/PrefabImporter.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Prowl.Runtime; using Prowl.Runtime.Utils; diff --git a/Prowl.Editor/Assets/Importers/SceneImporter.cs b/Prowl.Editor/Assets/Importers/SceneImporter.cs index 9a7006b9f..842f9ceae 100644 --- a/Prowl.Editor/Assets/Importers/SceneImporter.cs +++ b/Prowl.Editor/Assets/Importers/SceneImporter.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Prowl.Runtime; using Prowl.Runtime.Utils; diff --git a/Prowl.Editor/Assets/Importers/ScriptableObjectImporter.cs b/Prowl.Editor/Assets/Importers/ScriptableObjectImporter.cs index 83320e235..910e89a5c 100644 --- a/Prowl.Editor/Assets/Importers/ScriptableObjectImporter.cs +++ b/Prowl.Editor/Assets/Importers/ScriptableObjectImporter.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Prowl.Editor.Preferences; using Prowl.Editor.ScriptedEditors; using Prowl.Runtime; @@ -28,7 +30,7 @@ public class ScriptableObjectImporterEditor : ScriptedEditor public override void OnEnable() { - SerializedProperty tag = StringTagConverter.ReadFromFile((target as MetaFile).AssetPath); + EchoObject tag = StringTagConverter.ReadFromFile((target as MetaFile).AssetPath); _editingObject = Serializer.Deserialize(tag); _objectEditor = null; // Replace this to load a Scripta } diff --git a/Prowl.Editor/Assets/MetaFile.cs b/Prowl.Editor/Assets/MetaFile.cs index 5ae54cfef..c647167d7 100644 --- a/Prowl.Editor/Assets/MetaFile.cs +++ b/Prowl.Editor/Assets/MetaFile.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Prowl.Runtime; namespace Prowl.Editor.Assets; @@ -43,7 +45,7 @@ public void Save() { FileInfo file = new(AssetPath.FullName + ".meta"); version = MetaVersion; - SerializedProperty tag = Serializer.Serialize(this); + EchoObject tag = Serializer.Serialize(this); StringTagConverter.WriteToFile(tag, file); } @@ -54,7 +56,7 @@ public void Save() { FileInfo file = new(assetFile + ".meta"); if (!File.Exists(file.FullName)) return null; // Doesnt Exist - SerializedProperty tag = StringTagConverter.ReadFromFile(file); + EchoObject tag = StringTagConverter.ReadFromFile(file); MetaFile? meta = Serializer.Deserialize(tag); meta!.AssetPath = assetFile; meta.lastModified = DateTime.UtcNow; diff --git a/Prowl.Editor/Build/DesktopPlayerBuilder.cs b/Prowl.Editor/Build/DesktopPlayerBuilder.cs index 9edb2bfee..8bea2bd4c 100644 --- a/Prowl.Editor/Build/DesktopPlayerBuilder.cs +++ b/Prowl.Editor/Build/DesktopPlayerBuilder.cs @@ -10,6 +10,7 @@ using Prowl.Runtime; using Prowl.Runtime.Utils; using Prowl.Runtime.Rendering; +using Prowl.Echo; namespace Prowl.Editor.Build; @@ -260,7 +261,7 @@ private static void PackScenes(AssetRef[] scenes, string dataPath) { // Debug.Log($"Packing scene_{i}.prowl."); AssetRef scene = scenes[i]; - SerializedProperty tag = Serializer.Serialize(scene.Res!); + EchoObject tag = Serializer.Serialize(scene.Res!); BinaryTagConverter.WriteToFile(tag, new FileInfo(Path.Combine(dataPath, $"scene_{i}.prowl"))); } } diff --git a/Prowl.Editor/Editor/AssetsBrowserWindow.cs b/Prowl.Editor/Editor/AssetsBrowserWindow.cs index da1c847b2..2f2543da2 100644 --- a/Prowl.Editor/Editor/AssetsBrowserWindow.cs +++ b/Prowl.Editor/Editor/AssetsBrowserWindow.cs @@ -3,6 +3,8 @@ using System.Reflection; +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Prowl.Editor.Assets; using Prowl.Editor.Preferences; using Prowl.Editor.Utilities; diff --git a/Prowl.Editor/Editor/ProjectSettings/BuildProjectSettings.cs b/Prowl.Editor/Editor/ProjectSettings/BuildProjectSettings.cs index a532449cc..15acf65cf 100644 --- a/Prowl.Editor/Editor/ProjectSettings/BuildProjectSettings.cs +++ b/Prowl.Editor/Editor/ProjectSettings/BuildProjectSettings.cs @@ -3,6 +3,7 @@ using Prowl.Runtime; using Prowl.Runtime.Utils; +using Prowl.Echo; namespace Prowl.Editor.ProjectSettings; diff --git a/Prowl.Editor/EditorGuiManager.cs b/Prowl.Editor/EditorGuiManager.cs index 3849da32d..f7a6372e0 100644 --- a/Prowl.Editor/EditorGuiManager.cs +++ b/Prowl.Editor/EditorGuiManager.cs @@ -4,6 +4,8 @@ using System.ComponentModel.DataAnnotations; using System.Reflection; +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Prowl.Editor.Assets; using Prowl.Editor.Docking; using Prowl.Editor.Preferences; diff --git a/Prowl.Editor/Utilities/CreateAssetMenu.cs b/Prowl.Editor/Utilities/CreateAssetMenu.cs index c337c4e5d..63c25ca25 100644 --- a/Prowl.Editor/Utilities/CreateAssetMenu.cs +++ b/Prowl.Editor/Utilities/CreateAssetMenu.cs @@ -3,6 +3,8 @@ using System.Reflection; +using Prowl.Echo; +using Prowl.Echo.FileFormats; using Prowl.Editor.Assets; using Prowl.Runtime; using Prowl.Runtime.Utils; diff --git a/Prowl.Editor/Utilities/ProjectCache.cs b/Prowl.Editor/Utilities/ProjectCache.cs index d09fe0fcd..42634c416 100644 --- a/Prowl.Editor/Utilities/ProjectCache.cs +++ b/Prowl.Editor/Utilities/ProjectCache.cs @@ -3,6 +3,7 @@ using Prowl.Runtime; using Prowl.Runtime.Utils; +using Prowl.Echo; namespace Prowl.Editor; diff --git a/Prowl.Players/Prowl.Desktop/DesktopPlayer.cs b/Prowl.Players/Prowl.Desktop/DesktopPlayer.cs index 765c484a4..adcdd9471 100644 --- a/Prowl.Players/Prowl.Desktop/DesktopPlayer.cs +++ b/Prowl.Players/Prowl.Desktop/DesktopPlayer.cs @@ -1,5 +1,6 @@ using Prowl.Runtime; using Prowl.Runtime.SceneManagement; +using Prowl.Echo; namespace Prowl.Desktop; diff --git a/Prowl.Runtime.Test/Boolean32MatrixTests.cs b/Prowl.Runtime.Test/Boolean32MatrixTests.cs index 0d3fba0ad..4f9105379 100644 --- a/Prowl.Runtime.Test/Boolean32MatrixTests.cs +++ b/Prowl.Runtime.Test/Boolean32MatrixTests.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading.Tasks; +using Prowl.Echo; using Prowl.Runtime.Utils; using Xunit; diff --git a/Prowl.Runtime.Test/SerializerTests.cs b/Prowl.Runtime.Test/SerializerTests.cs deleted file mode 100644 index 4386b8ad7..000000000 --- a/Prowl.Runtime.Test/SerializerTests.cs +++ /dev/null @@ -1,832 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using Xunit; - -namespace Prowl.Runtime.Test; - -public class SerializerTests -{ - #region Classes - - // Test classes - public enum TestEnum2 - { - None = 0, - One = 1, - Two = 2, - Large = 1000000, - Negative = -1 - } - - public class SimpleObject - { - public string StringField = "Hello"; - public int IntField = 42; - public float FloatField = 3.14f; - public bool BoolField = true; - } - - public class ComplexObject - { - public SimpleObject Object = new(); - public List Numbers = new() { 1, 2, 3 }; - public Dictionary Values = new() { { "one", 1.0f }, { "two", 2.0f } }; - } - - public class CircularObject - { - public string Name = "Parent"; - public CircularObject? Child; - } - - public class CustomSerializableObject : ISerializable - { - public int Value = 42; - public string Text = "Custom"; - - public SerializedProperty Serialize(Serializer.SerializationContext ctx) - { - var compound = SerializedProperty.NewCompound(); - compound.Add("customValue", new SerializedProperty(PropertyType.Int, Value)); - compound.Add("customText", new SerializedProperty(PropertyType.String, Text)); - return compound; - } - - public void Deserialize(SerializedProperty tag, Serializer.SerializationContext ctx) - { - Value = tag.Get("customValue").IntValue; - Text = tag.Get("customText").StringValue; - } - } - - private class ObjectWithAttributes - { - [FormerlySerializedAs("oldName")] - public string NewName = "Test"; - - [IgnoreOnNull] - public string? OptionalField = null; - } - - private class ObjectWithReadOnlyFields - { - public readonly string ReadOnlyField = "Readonly"; - public const string ConstField = "Const"; - public string NormalField = "Normal"; - } - - private abstract class AbstractClass - { - public string Name = "Abstract"; - } - - private class ConcreteClass : AbstractClass - { - public int Value = 42; - } - - private struct TestStruct - { - public int X; - public int Y; - } - - private class ObjectWithNestedTypes - { - public class NestedClass - { - public string Value = "Nested"; - } - - public NestedClass Nested = new(); - } - - private class ObjectWithTuple - { - public (int, string) SimpleTuple = (1, "One"); - public ValueTuple NamedTuple = (1, "One", 1.0f); - } - - private class ObjectWithGenericField - { - public T? Value; - } - - private class ObjectWithEvent - { - public event EventHandler? TestEvent; - public string Name = "EventTest"; - } - - private record TestRecord(string Name, int Value); - - private class ObjectWithIndexer - { - private readonly Dictionary _storage = new(); - public object this[string key] - { - get => _storage[key]; - set => _storage[key] = value; - } - } - - #endregion - - #region Basic Tests - - [Fact] - public void TestPrimitives() - { - // String - Assert.Equal("test", Serializer.Deserialize(Serializer.Serialize("test"))); - Assert.Equal(string.Empty, Serializer.Deserialize(Serializer.Serialize(string.Empty))); - - // Numeric types - Assert.Equal((byte)255, Serializer.Deserialize(Serializer.Serialize((byte)255))); - Assert.Equal((sbyte)-128, Serializer.Deserialize(Serializer.Serialize((sbyte)-128))); - Assert.Equal((short)-32768, Serializer.Deserialize(Serializer.Serialize((short)-32768))); - Assert.Equal((ushort)65535, Serializer.Deserialize(Serializer.Serialize((ushort)65535))); - Assert.Equal(42, Serializer.Deserialize(Serializer.Serialize(42))); - Assert.Equal(42u, Serializer.Deserialize(Serializer.Serialize(42u))); - Assert.Equal(42L, Serializer.Deserialize(Serializer.Serialize(42L))); - Assert.Equal(42uL, Serializer.Deserialize(Serializer.Serialize(42uL))); - Assert.Equal(3.14f, Serializer.Deserialize(Serializer.Serialize(3.14f))); - Assert.Equal(3.14159, Serializer.Deserialize(Serializer.Serialize(3.14159))); - Assert.Equal(3.14159m, Serializer.Deserialize(Serializer.Serialize(3.14159m))); - - // Boolean - Assert.True(Serializer.Deserialize(Serializer.Serialize(true))); - Assert.False(Serializer.Deserialize(Serializer.Serialize(false))); - - // Byte array - var byteArray = new byte[] { 1, 2, 3, 4, 5 }; - var deserializedArray = Serializer.Deserialize(Serializer.Serialize(byteArray)); - Assert.Equal(byteArray, deserializedArray); - } - - [Fact] - public void TestNullValues() - { - string? nullString = null; - var serialized = Serializer.Serialize(nullString); - var deserialized = Serializer.Deserialize(serialized); - Assert.Null(deserialized); - } - - [Fact] - public void TestDateTime() - { - // Current time - var now = DateTime.Now; - var serialized = Serializer.Serialize(now); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(now, deserialized); - - // Minimum value - var min = DateTime.MinValue; - serialized = Serializer.Serialize(min); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(min, deserialized); - - // Maximum value - var max = DateTime.MaxValue; - serialized = Serializer.Serialize(max); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(max, deserialized); - - // UTC time - var utc = DateTime.UtcNow; - serialized = Serializer.Serialize(utc); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(utc, deserialized); - - // Specific date - var specific = new DateTime(2024, 1, 1, 12, 0, 0, DateTimeKind.Local); - serialized = Serializer.Serialize(specific); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(specific, deserialized); - } - - [Fact] - public void TestGuid() - { - // Empty Guid - var empty = Guid.Empty; - var serialized = Serializer.Serialize(empty); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(empty, deserialized); - - // New Guid - var guid = Guid.NewGuid(); - serialized = Serializer.Serialize(guid); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(guid, deserialized); - - // Specific Guid - var specific = new Guid("A1A2A3A4-B1B2-C1C2-D1D2-E1E2E3E4E5E6"); - serialized = Serializer.Serialize(specific); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(specific, deserialized); - } - - [Flags] - public enum TestFlags - { - None = 0, - Flag1 = 1, - Flag2 = 2, - Flag3 = 4, - All = Flag1 | Flag2 | Flag3 - } - - [Fact] - public void TestEnum() - { - // Basic enum values - var none = TestEnum2.None; - var serialized = Serializer.Serialize(none); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(none, deserialized); - - var large = TestEnum2.Large; - serialized = Serializer.Serialize(large); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(large, deserialized); - - var negative = TestEnum2.Negative; - serialized = Serializer.Serialize(negative); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(negative, deserialized); - } - - [Fact] - public void TestFlagsEnum() - { - // Single flag - var flag1 = TestFlags.Flag1; - var serialized = Serializer.Serialize(flag1); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(flag1, deserialized); - - // Combined flags - var combined = TestFlags.Flag1 | TestFlags.Flag2; - serialized = Serializer.Serialize(combined); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(combined, deserialized); - - // All flags - var all = TestFlags.All; - serialized = Serializer.Serialize(all); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(all, deserialized); - - // No flags - var none = TestFlags.None; - serialized = Serializer.Serialize(none); - deserialized = Serializer.Deserialize(serialized); - Assert.Equal(none, deserialized); - } - - #endregion - - #region Attribute Tests - [Fact] - public void TestFormerlySerializedAs() - { - var original = new ObjectWithAttributes { NewName = "Updated" }; - var serialized = Serializer.Serialize(original); - serialized.Remove("NewName"); - serialized.Add("oldName", new SerializedProperty(PropertyType.String, "Updated")); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(original.NewName, deserialized.NewName); - } - - [Fact] - public void TestIgnoreOnNull() - { - var original = new ObjectWithAttributes { OptionalField = null }; - var serialized = Serializer.Serialize(original); - Assert.False(serialized.Tags.ContainsKey("OptionalField")); - } - #endregion - - #region Collection Tests - [Fact] - public void TestArrays() - { - var original = new int[] { 1, 2, 3, 4, 5 }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestJaggedArrays() - { - var original = new int[][] - { - new int[] { 1, 2 }, - new int[] { 3, 4, 5 } - }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - - Assert.Equal(original.Length, deserialized.Length); - for (int i = 0; i < original.Length; i++) - { - Assert.Equal(original[i], deserialized[i]); - } - } - - [Fact] - public void TestMultidimensionalArrays() - { - var original = new int[,] { { 1, 2 }, { 3, 4 } }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(original, deserialized); - - } - - [Fact] - public void TestHashSet() - { - var original = new HashSet { 1, 2, 3 }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - Assert.Equal(original, deserialized); - } - #endregion - - [Fact] - public void TestSimpleObject() - { - var original = new SimpleObject(); - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - - Assert.NotNull(deserialized); - Assert.Equal(original.StringField, deserialized.StringField); - Assert.Equal(original.IntField, deserialized.IntField); - Assert.Equal(original.FloatField, deserialized.FloatField); - Assert.Equal(original.BoolField, deserialized.BoolField); - } - - [Fact] - public void TestComplexObject() - { - var original = new ComplexObject(); - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - - Assert.NotNull(deserialized); - Assert.Equal(original.Object.StringField, deserialized.Object.StringField); - Assert.Equal(original.Numbers, deserialized.Numbers); - Assert.Equal(original.Values, deserialized.Values); - } - - [Fact] - public void TestCircularReferences() - { - var original = new CircularObject(); - original.Child = new CircularObject { Name = "Child" }; - original.Child.Child = original; // Create circular reference - - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - - Assert.NotNull(deserialized); - Assert.Equal("Parent", deserialized.Name); - Assert.NotNull(deserialized.Child); - Assert.Equal("Child", deserialized.Child.Name); - Assert.Same(deserialized, deserialized.Child.Child); // Verify circular reference is preserved - } - - [Fact] - public void TestCustomSerializable() - { - var original = new CustomSerializableObject(); - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - - Assert.NotNull(deserialized); - Assert.Equal(original.Value, deserialized.Value); - Assert.Equal(original.Text, deserialized.Text); - } - - [Fact] - public void TestDictionary() - { - var original = new Dictionary - { - { "one", 1 }, - { "two", 2 }, - { "three", 3 } - }; - - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestStringKeyDictionary() - { - var original = new Dictionary - { - { "one", 1 }, - { "two", 2 }, - { "three", 3 } - }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestIntKeyDictionary() - { - var original = new Dictionary - { - { 1, "one" }, - { 2, "two" }, - { 3, "three" } - }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestEnumKeyDictionary() - { - var original = new Dictionary - { - { DayOfWeek.Monday, 1 }, - { DayOfWeek.Wednesday, 3 }, - { DayOfWeek.Friday, 5 } - }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestGuidKeyDictionary() - { - var original = new Dictionary - { - { Guid.NewGuid(), "first" }, - { Guid.NewGuid(), "second" }, - { Guid.NewGuid(), "third" } - }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestNestedDictionary() - { - var original = new Dictionary> - { - { - 1, new Dictionary - { - { "true", true }, - { "false", false } - } - }, - { - 2, new Dictionary - { - { "yes", true }, - { "no", false } - } - } - }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>>(serialized); - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestEmptyDictionary() - { - var original = new Dictionary(); - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - Assert.Empty(deserialized); - } - - [Fact] - public void TestDictionaryWithNullValues() - { - var original = new Dictionary - { - { 1, "one" }, - { 2, null }, - { 3, "three" } - }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - Assert.Equal(original, deserialized); - } - - // Test with a custom type as key - public class CustomKey - { - public int Id; - public string Name = ""; - - public override bool Equals(object? obj) - { - if (obj is CustomKey other) - return Id == other.Id && Name == other.Name; - return false; - } - - public override int GetHashCode() - { - return HashCode.Combine(Id, Name); - } - } - - [Fact] - public void TestCustomTypeKeyDictionary() - { - var original = new Dictionary - { - { new CustomKey { Id = 1, Name = "first" }, 1 }, - { new CustomKey { Id = 2, Name = "second" }, 2 }, - { new CustomKey { Id = 3, Name = "third" }, 3 } - }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestMixedNestedDictionaries() - { - var original = new Dictionary>> - { - { - 1, new Dictionary> - { - { - "first", new Dictionary - { - { Guid.NewGuid(), true }, - { Guid.NewGuid(), false } - } - } - } - } - }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>>>(serialized); - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestList() - { - var original = new List { "one", "two", "three" }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize>(serialized); - - Assert.Equal(original, deserialized); - } - - [Fact] - public void TestAbstractClass() - { - AbstractClass original = new ConcreteClass { Name = "Test", Value = 42 }; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(((ConcreteClass)original).Value, deserialized.Value); - } - - [Fact] - public void TestIndexer() - { - var original = new ObjectWithIndexer(); - original["test"] = "value"; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - // Indexers aren't serialized by default - Assert.Throws(() => deserialized["test"]); - } - - [Fact] - public void TestDeepNesting() - { - var obj = new CircularObject(); - var current = obj; - // Create a deeply nested structure - for (int i = 0; i < 1000; i++) - { - current.Child = new CircularObject { Name = $"Level {i}" }; - current = current.Child; - } - - var serialized = Serializer.Serialize(obj); - var deserialized = Serializer.Deserialize(serialized); - - // Verify a few levels - Assert.Equal("Level 0", deserialized.Child?.Name); - Assert.Equal("Level 1", deserialized.Child?.Child?.Name); - } - - [Fact] - public void TestLargeData() - { - var largeString = new string('a', 1_000_000); - var serialized = Serializer.Serialize(largeString); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(largeString, deserialized); - } - - [Theory] - [InlineData(0)] - [InlineData(42)] - [InlineData(-1)] - [InlineData(int.MaxValue)] - [InlineData(int.MinValue)] - public void TestIntegerValues(int value) - { - var serialized = Serializer.Serialize(value); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(value, deserialized); - } - - [Theory] - [InlineData("")] - [InlineData("Hello")] - [InlineData("Special\nCharacters\t\r")] - [InlineData("Unicode 🎮 Characters")] - public void TestStringValues(string value) - { - var serialized = Serializer.Serialize(value); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(value, deserialized); - } - - [Theory] - [InlineData(double.NaN)] - [InlineData(double.PositiveInfinity)] - [InlineData(double.NegativeInfinity)] - [InlineData(double.Epsilon)] - public void TestSpecialFloatingPointValues(double value) - { - var serialized = Serializer.Serialize(value); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(value, deserialized); - } - - [Fact] - public void TestNullableInt() - { - // Non-null value - int? original = 42; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(original, deserialized); - - // Null value - int? nullValue = null; - serialized = Serializer.Serialize(nullValue); - deserialized = Serializer.Deserialize(serialized); - Assert.Null(deserialized); - } - - [Fact] - public void TestNullableDateTime() - { - // Non-null value - DateTime? original = DateTime.Now; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(original, deserialized); - - // Null value - DateTime? nullValue = null; - serialized = Serializer.Serialize(nullValue); - deserialized = Serializer.Deserialize(serialized); - Assert.Null(deserialized); - } - - [Fact] - public void TestNullableGuid() - { - // Non-null value - Guid? original = Guid.NewGuid(); - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(original, deserialized); - - // Null value - Guid? nullValue = null; - serialized = Serializer.Serialize(nullValue); - deserialized = Serializer.Deserialize(serialized); - Assert.Null(deserialized); - } - - [Fact] - public void TestNullableEnum() - { - // Non-null value - TestEnum2? original = TestEnum2.Two; - var serialized = Serializer.Serialize(original); - var deserialized = Serializer.Deserialize(serialized); - Assert.Equal(original, deserialized); - - // Null value - TestEnum2? nullValue = null; - serialized = Serializer.Serialize(nullValue); - deserialized = Serializer.Deserialize(serialized); - Assert.Null(deserialized); - } - - private class NullableTestClass - { - public int? NullableInt; - public DateTime? NullableDateTime; - public Guid? NullableGuid; - public TestEnum2? NullableEnum; - - public int? NullIntValue; - public DateTime? NullDateTimeValue; - public Guid? NullGuidValue; - public TestEnum2? NullEnumValue; - } - - [Fact] - public void TestComplexNullableTypes() - { - var testClass = new NullableTestClass - { - NullableInt = 42, - NullableDateTime = DateTime.Now, - NullableGuid = Guid.NewGuid(), - NullableEnum = TestEnum2.One, - NullIntValue = null, - NullDateTimeValue = null, - NullGuidValue = null, - NullEnumValue = null - }; - - var serialized = Serializer.Serialize(testClass); - var deserialized = Serializer.Deserialize(serialized); - - // Check non-null values - Assert.Equal(testClass.NullableInt, deserialized.NullableInt); - Assert.Equal(testClass.NullableDateTime, deserialized.NullableDateTime); - Assert.Equal(testClass.NullableGuid, deserialized.NullableGuid); - Assert.Equal(testClass.NullableEnum, deserialized.NullableEnum); - - // Check null values - Assert.Null(deserialized.NullIntValue); - Assert.Null(deserialized.NullDateTimeValue); - Assert.Null(deserialized.NullGuidValue); - Assert.Null(deserialized.NullEnumValue); - } - - [Fact] - public void TestNullablePrimitives() - { - // Test all primitive nullable types - byte? byteValue = 255; - Assert.Equal(byteValue, Serializer.Deserialize(Serializer.Serialize(byteValue))); - - sbyte? sbyteValue = -128; - Assert.Equal(sbyteValue, Serializer.Deserialize(Serializer.Serialize(sbyteValue))); - - short? shortValue = -32768; - Assert.Equal(shortValue, Serializer.Deserialize(Serializer.Serialize(shortValue))); - - ushort? ushortValue = 65535; - Assert.Equal(ushortValue, Serializer.Deserialize(Serializer.Serialize(ushortValue))); - - long? longValue = long.MaxValue; - Assert.Equal(longValue, Serializer.Deserialize(Serializer.Serialize(longValue))); - - ulong? ulongValue = ulong.MaxValue; - Assert.Equal(ulongValue, Serializer.Deserialize(Serializer.Serialize(ulongValue))); - - float? floatValue = 3.14159f; - Assert.Equal(floatValue, Serializer.Deserialize(Serializer.Serialize(floatValue))); - - double? doubleValue = 3.14159265359; - Assert.Equal(doubleValue, Serializer.Deserialize(Serializer.Serialize(doubleValue))); - - decimal? decimalValue = 3.14159265359m; - Assert.Equal(decimalValue, Serializer.Deserialize(Serializer.Serialize(decimalValue))); - - bool? boolValue = true; - Assert.Equal(boolValue, Serializer.Deserialize(Serializer.Serialize(boolValue))); - } -} diff --git a/Prowl.Runtime/AnimationCurve.cs b/Prowl.Runtime/AnimationCurve.cs index 02931e49b..4f4e726c2 100644 --- a/Prowl.Runtime/AnimationCurve.cs +++ b/Prowl.Runtime/AnimationCurve.cs @@ -5,6 +5,8 @@ using System.Collections; using System.Collections.Generic; +using Prowl.Echo; + namespace Prowl.Runtime; // MIT License - Copyright (C) The Mono.Xna Team @@ -307,21 +309,21 @@ private double GetCurvePosition(double position) return 0f; } - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - var value = SerializedProperty.NewCompound(); - value.Add("PreLoop", new SerializedProperty((int)PreLoop)); - value.Add("PostLoop", new SerializedProperty((int)PostLoop)); + var value = EchoObject.NewCompound(); + value.Add("PreLoop", new EchoObject((int)PreLoop)); + value.Add("PostLoop", new EchoObject((int)PostLoop)); - var keyList = SerializedProperty.NewList(); + var keyList = EchoObject.NewList(); foreach (var key in Keys) { - var keyProp = SerializedProperty.NewCompound(); - keyProp.Add("Position", new SerializedProperty(key.Position)); - keyProp.Add("Value", new SerializedProperty(key.Value)); - keyProp.Add("TangentIn", new SerializedProperty(key.TangentIn)); - keyProp.Add("TangentOut", new SerializedProperty(key.TangentOut)); - keyProp.Add("Continuity", new SerializedProperty((int)key.Continuity)); + var keyProp = EchoObject.NewCompound(); + keyProp.Add("Position", new EchoObject(key.Position)); + keyProp.Add("Value", new EchoObject(key.Value)); + keyProp.Add("TangentIn", new EchoObject(key.TangentIn)); + keyProp.Add("TangentOut", new EchoObject(key.TangentOut)); + keyProp.Add("Continuity", new EchoObject((int)key.Continuity)); keyList.ListAdd(keyProp); } value.Add("Keys", keyList); @@ -329,7 +331,7 @@ public SerializedProperty Serialize(Serializer.SerializationContext ctx) return value; } - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { PreLoop = (CurveLoopType)value.Get("PreLoop").IntValue; PostLoop = (CurveLoopType)value.Get("PostLoop").IntValue; diff --git a/Prowl.Runtime/AssemblyManager.cs b/Prowl.Runtime/AssemblyManager.cs index 3fd190446..33eddd1d1 100644 --- a/Prowl.Runtime/AssemblyManager.cs +++ b/Prowl.Runtime/AssemblyManager.cs @@ -10,6 +10,8 @@ using System.Runtime.CompilerServices; using System.Runtime.Loader; +using Prowl.Echo; + using Prowl.Runtime.Utils; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/AssetRef.cs b/Prowl.Runtime/AssetRef.cs index 139a179a5..f8626c36d 100644 --- a/Prowl.Runtime/AssetRef.cs +++ b/Prowl.Runtime/AssetRef.cs @@ -3,6 +3,7 @@ using System; +using Prowl.Echo; using Prowl.Runtime.Cloning; namespace Prowl.Runtime; @@ -294,24 +295,24 @@ public static explicit operator T(AssetRef res) } - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - SerializedProperty compoundTag = SerializedProperty.NewCompound(); - compoundTag.Add("AssetID", new SerializedProperty(assetID.ToString())); + EchoObject compoundTag = EchoObject.NewCompound(); + compoundTag.Add("AssetID", new EchoObject(assetID.ToString())); if (assetID != Guid.Empty) ctx.AddDependency(assetID); if (fileID != 0) - compoundTag.Add("FileID", new SerializedProperty(fileID)); + compoundTag.Add("FileID", new EchoObject(fileID)); if (IsRuntimeResource) compoundTag.Add("Instance", Serializer.Serialize(instance, ctx)); return compoundTag; } - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { assetID = Guid.Parse(value["AssetID"].StringValue); - fileID = value.TryGet("FileID", out SerializedProperty fileTag) ? fileTag.UShortValue : (ushort)0; - if (assetID == Guid.Empty && value.TryGet("Instance", out SerializedProperty tag)) + fileID = value.TryGet("FileID", out EchoObject fileTag) ? fileTag.UShortValue : (ushort)0; + if (assetID == Guid.Empty && value.TryGet("Instance", out EchoObject tag)) instance = Serializer.Deserialize(tag, ctx); } } diff --git a/Prowl.Runtime/Cloning/CloneType.cs b/Prowl.Runtime/Cloning/CloneType.cs index 64066d080..4c949b924 100644 --- a/Prowl.Runtime/Cloning/CloneType.cs +++ b/Prowl.Runtime/Cloning/CloneType.cs @@ -4,6 +4,8 @@ using System.Linq.Expressions; using System.Reflection; +using Prowl.Echo; + namespace Prowl.Runtime.Cloning { /// diff --git a/Prowl.Runtime/Components/Camera.cs b/Prowl.Runtime/Components/Camera.cs index 7b041615b..6ecca6a55 100644 --- a/Prowl.Runtime/Components/Camera.cs +++ b/Prowl.Runtime/Components/Camera.cs @@ -5,6 +5,7 @@ using System.Linq; using Prowl.Icons; +using Prowl.Echo; using Prowl.Runtime.Rendering; using Prowl.Runtime.Rendering.Pipelines; diff --git a/Prowl.Runtime/Components/MissingMonobehaviour.cs b/Prowl.Runtime/Components/MissingMonobehaviour.cs index 39f23669d..c4db293da 100644 --- a/Prowl.Runtime/Components/MissingMonobehaviour.cs +++ b/Prowl.Runtime/Components/MissingMonobehaviour.cs @@ -1,6 +1,7 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; using Prowl.Icons; namespace Prowl.Runtime; @@ -8,5 +9,5 @@ namespace Prowl.Runtime; [AddComponentMenu($"Hidden/{FontAwesome6.File} Missing Script")] public class MissingMonobehaviour : MonoBehaviour { - public SerializedProperty ComponentData; + public EchoObject ComponentData; } diff --git a/Prowl.Runtime/Components/Navmesh/NavMeshAgent.cs b/Prowl.Runtime/Components/Navmesh/NavMeshAgent.cs index 6760d5995..2bc47cccf 100644 --- a/Prowl.Runtime/Components/Navmesh/NavMeshAgent.cs +++ b/Prowl.Runtime/Components/Navmesh/NavMeshAgent.cs @@ -5,6 +5,8 @@ using DotRecast.Detour; using DotRecast.Detour.Crowd; +using Prowl.Echo; + namespace Prowl.Runtime; public class NavMeshAgent : MonoBehaviour diff --git a/Prowl.Runtime/Components/Physics/Colliders/BoxCollider.cs b/Prowl.Runtime/Components/Physics/Colliders/BoxCollider.cs index dd30fcef2..23445837f 100644 --- a/Prowl.Runtime/Components/Physics/Colliders/BoxCollider.cs +++ b/Prowl.Runtime/Components/Physics/Colliders/BoxCollider.cs @@ -4,6 +4,7 @@ using Jitter2.Collision.Shapes; using Prowl.Icons; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Components/Physics/Colliders/CapsuleCollider.cs b/Prowl.Runtime/Components/Physics/Colliders/CapsuleCollider.cs index 1803b765b..ae6eb080e 100644 --- a/Prowl.Runtime/Components/Physics/Colliders/CapsuleCollider.cs +++ b/Prowl.Runtime/Components/Physics/Colliders/CapsuleCollider.cs @@ -4,6 +4,7 @@ using Jitter2.Collision.Shapes; using Prowl.Icons; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Components/Physics/Colliders/ConeCollider.cs b/Prowl.Runtime/Components/Physics/Colliders/ConeCollider.cs index e69921e76..b9c42ea3d 100644 --- a/Prowl.Runtime/Components/Physics/Colliders/ConeCollider.cs +++ b/Prowl.Runtime/Components/Physics/Colliders/ConeCollider.cs @@ -4,6 +4,7 @@ using Jitter2.Collision.Shapes; using Prowl.Icons; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Components/Physics/Colliders/ConvexHullCollider.cs b/Prowl.Runtime/Components/Physics/Colliders/ConvexHullCollider.cs index 2504069a2..92a504afb 100644 --- a/Prowl.Runtime/Components/Physics/Colliders/ConvexHullCollider.cs +++ b/Prowl.Runtime/Components/Physics/Colliders/ConvexHullCollider.cs @@ -8,6 +8,7 @@ using Jitter2.LinearMath; using Prowl.Icons; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Components/Physics/Colliders/CylinderCollider.cs b/Prowl.Runtime/Components/Physics/Colliders/CylinderCollider.cs index 745bf7abd..650d3c79c 100644 --- a/Prowl.Runtime/Components/Physics/Colliders/CylinderCollider.cs +++ b/Prowl.Runtime/Components/Physics/Colliders/CylinderCollider.cs @@ -4,6 +4,7 @@ using Jitter2.Collision.Shapes; using Prowl.Icons; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Components/Physics/Colliders/SphereCollider.cs b/Prowl.Runtime/Components/Physics/Colliders/SphereCollider.cs index 10656fb7f..bf31380f0 100644 --- a/Prowl.Runtime/Components/Physics/Colliders/SphereCollider.cs +++ b/Prowl.Runtime/Components/Physics/Colliders/SphereCollider.cs @@ -4,6 +4,7 @@ using Jitter2.Collision.Shapes; using Prowl.Icons; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Components/Physics/Rigidbody3D.cs b/Prowl.Runtime/Components/Physics/Rigidbody3D.cs index 31d7c5307..434acee26 100644 --- a/Prowl.Runtime/Components/Physics/Rigidbody3D.cs +++ b/Prowl.Runtime/Components/Physics/Rigidbody3D.cs @@ -8,6 +8,7 @@ using Jitter2.LinearMath; using Prowl.Icons; +using Prowl.Echo; using Prowl.Runtime.Cloning; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Components/SkinnedMeshRenderer.cs b/Prowl.Runtime/Components/SkinnedMeshRenderer.cs index fd8eb546a..303f1acac 100644 --- a/Prowl.Runtime/Components/SkinnedMeshRenderer.cs +++ b/Prowl.Runtime/Components/SkinnedMeshRenderer.cs @@ -7,8 +7,7 @@ using Prowl.Runtime.Rendering.Pipelines; using Prowl.Icons; -using Veldrid; -using System; +using Prowl.Echo; namespace Prowl.Runtime; @@ -61,9 +60,9 @@ public override void Update() } - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - SerializedProperty compoundTag = SerializedProperty.NewCompound(); + EchoObject compoundTag = EchoObject.NewCompound(); compoundTag.Add("Mesh", Serializer.Serialize(Mesh, ctx)); compoundTag.Add("Material", Serializer.Serialize(Material, ctx)); compoundTag.Add("Bones", Serializer.Serialize(Bones, ctx)); @@ -72,7 +71,7 @@ public SerializedProperty Serialize(Serializer.SerializationContext ctx) } - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { Mesh = Serializer.Deserialize>(value["Mesh"], ctx); Material = Serializer.Deserialize>(value["Material"], ctx); diff --git a/Prowl.Runtime/EngineObject.cs b/Prowl.Runtime/EngineObject.cs index 5bf07145e..a8b297ad0 100644 --- a/Prowl.Runtime/EngineObject.cs +++ b/Prowl.Runtime/EngineObject.cs @@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; using System.Threading; +using Prowl.Echo; using Prowl.Runtime.Cloning; namespace Prowl.Runtime; @@ -176,24 +177,24 @@ public virtual void OnDispose() { } public override string ToString() => Name; - protected void SerializeHeader(SerializedProperty compound) + protected void SerializeHeader(EchoObject compound) { compound.Add("Name", new(Name)); if (AssetID != Guid.Empty) { - compound.Add("AssetID", new SerializedProperty(AssetID.ToString())); + compound.Add("AssetID", new EchoObject(AssetID.ToString())); if (FileID != 0) - compound.Add("FileID", new SerializedProperty(FileID)); + compound.Add("FileID", new EchoObject(FileID)); } } - protected void DeserializeHeader(SerializedProperty value) + protected void DeserializeHeader(EchoObject value) { Name = value.Get("Name")?.StringValue; - if (value.TryGet("AssetID", out SerializedProperty? assetIDTag)) + if (value.TryGet("AssetID", out EchoObject? assetIDTag)) { AssetID = Guid.Parse(assetIDTag.StringValue); diff --git a/Prowl.Runtime/GameObject/GameObject.cs b/Prowl.Runtime/GameObject/GameObject.cs index 166ba32a5..f0fe1f7d2 100644 --- a/Prowl.Runtime/GameObject/GameObject.cs +++ b/Prowl.Runtime/GameObject/GameObject.cs @@ -12,6 +12,7 @@ using Prowl.Runtime.Utilities; using SoftCircuits.Collections; +using Prowl.Echo; namespace Prowl.Runtime; @@ -1055,38 +1056,38 @@ public void SendMessage(string methodName, params object[] objs) /// /// The serialization context. /// A SerializedProperty containing the GameObject's data. - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - SerializedProperty compoundTag = SerializedProperty.NewCompound(); - compoundTag.Add("Name", new SerializedProperty(Name)); + EchoObject compoundTag = EchoObject.NewCompound(); + compoundTag.Add("Name", new EchoObject(Name)); - compoundTag.Add("Identifier", new SerializedProperty(_identifier.ToString())); - compoundTag.Add("Static", new SerializedProperty((byte)(_static ? 1 : 0))); + compoundTag.Add("Identifier", new EchoObject(_identifier.ToString())); + compoundTag.Add("Static", new EchoObject((byte)(_static ? 1 : 0))); - compoundTag.Add("Enabled", new SerializedProperty((byte)(_enabled ? 1 : 0))); - compoundTag.Add("EnabledInHierarchy", new SerializedProperty((byte)(_enabledInHierarchy ? 1 : 0))); + compoundTag.Add("Enabled", new EchoObject((byte)(_enabled ? 1 : 0))); + compoundTag.Add("EnabledInHierarchy", new EchoObject((byte)(_enabledInHierarchy ? 1 : 0))); - compoundTag.Add("TagIndex", new SerializedProperty(tagIndex)); - compoundTag.Add("LayerIndex", new SerializedProperty(layerIndex)); + compoundTag.Add("TagIndex", new EchoObject(tagIndex)); + compoundTag.Add("LayerIndex", new EchoObject(layerIndex)); - compoundTag.Add("HideFlags", new SerializedProperty((int)hideFlags)); + compoundTag.Add("HideFlags", new EchoObject((int)hideFlags)); compoundTag.Add("Transform", Serializer.Serialize(_transform, ctx)); compoundTag.Add("PrefabLink", Serializer.Serialize(prefabLink, ctx)); if (AssetID != Guid.Empty) { - compoundTag.Add("AssetID", new SerializedProperty(AssetID.ToString())); + compoundTag.Add("AssetID", new EchoObject(AssetID.ToString())); if (FileID != 0) - compoundTag.Add("FileID", new SerializedProperty(FileID)); + compoundTag.Add("FileID", new EchoObject(FileID)); } - SerializedProperty components = SerializedProperty.NewList(); + EchoObject components = EchoObject.NewList(); foreach (MonoBehaviour comp in _components) components.ListAdd(Serializer.Serialize(comp, ctx)); compoundTag.Add("Components", components); - SerializedProperty children = SerializedProperty.NewList(); + EchoObject children = EchoObject.NewList(); foreach (GameObject child in this.children) children.ListAdd(Serializer.Serialize(child, ctx)); compoundTag.Add("Children", children); @@ -1099,7 +1100,7 @@ public SerializedProperty Serialize(Serializer.SerializationContext ctx) /// /// The SerializedProperty containing the GameObject's data. /// The serialization context. - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { Name = value["Name"].StringValue; if (Guid.TryParse(value["Identifier"]?.StringValue ?? "", out var identifier)) @@ -1113,21 +1114,21 @@ public void Deserialize(SerializedProperty value, Serializer.SerializationContex _transform = Serializer.Deserialize(value["Transform"], ctx); _transform.gameObject = this; - if (value.TryGet("PrefabLink", out SerializedProperty? link)) + if (value.TryGet("PrefabLink", out EchoObject? link)) { prefabLink = Serializer.Deserialize(link, ctx); if (prefabLink != null) prefabLink.Obj = this; } - if (value.TryGet("AssetID", out SerializedProperty? guid)) + if (value.TryGet("AssetID", out EchoObject? guid)) AssetID = Guid.Parse(guid.StringValue); - if (value.TryGet("FileID", out SerializedProperty? fileID)) + if (value.TryGet("FileID", out EchoObject? fileID)) FileID = fileID.UShortValue; - SerializedProperty children = value["Children"]; + EchoObject children = value["Children"]; this.children = []; - foreach (SerializedProperty childTag in children.List) + foreach (EchoObject childTag in children.List) { GameObject? child = Serializer.Deserialize(childTag, ctx); if (child == null) continue; @@ -1135,12 +1136,12 @@ public void Deserialize(SerializedProperty value, Serializer.SerializationContex this.children.Add(child); } - SerializedProperty comps = value["Components"]; + EchoObject comps = value["Components"]; _components = []; - foreach (SerializedProperty compTag in comps.List) + foreach (EchoObject compTag in comps.List) { // Fallback for Missing Type - SerializedProperty? typeProperty = compTag.Get("$type"); + EchoObject? typeProperty = compTag.Get("$type"); // If the type is missing or string null/whitespace something is wrong, so just let the Deserializer handle it, maybe it knows what to do if (typeProperty != null && !string.IsNullOrWhiteSpace(typeProperty.StringValue)) { @@ -1175,13 +1176,13 @@ public void Deserialize(SerializedProperty value, Serializer.SerializationContex /// /// The SerializedProperty containing the component data. /// The serialization context. - private void HandleMissingComponent(SerializedProperty compTag, Serializer.SerializationContext ctx) + private void HandleMissingComponent(EchoObject compTag, SerializationContext ctx) { // Were missing! see if we can recover MissingMonobehaviour missing = Serializer.Deserialize(compTag, ctx); - SerializedProperty oldData = missing.ComponentData; + EchoObject oldData = missing.ComponentData; // Try to recover the component - if (oldData.TryGet("$type", out SerializedProperty? typeProp)) + if (oldData.TryGet("$type", out EchoObject? typeProp)) { Type oType = RuntimeUtils.FindType(typeProp.StringValue); if (oType != null) diff --git a/Prowl.Runtime/GameObject/LayerMask.cs b/Prowl.Runtime/GameObject/LayerMask.cs index f6ea3d047..8a917ee42 100644 --- a/Prowl.Runtime/GameObject/LayerMask.cs +++ b/Prowl.Runtime/GameObject/LayerMask.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime; /// diff --git a/Prowl.Runtime/GameObject/MonoBehaviour.cs b/Prowl.Runtime/GameObject/MonoBehaviour.cs index b8d6e475e..f4109c550 100644 --- a/Prowl.Runtime/GameObject/MonoBehaviour.cs +++ b/Prowl.Runtime/GameObject/MonoBehaviour.cs @@ -10,6 +10,7 @@ using Prowl.Runtime.GUI; using Prowl.Runtime.Rendering; using Prowl.Runtime.Utils; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Math/Transform.cs b/Prowl.Runtime/Math/Transform.cs index 80073094f..e3f006057 100644 --- a/Prowl.Runtime/Math/Transform.cs +++ b/Prowl.Runtime/Math/Transform.cs @@ -4,6 +4,7 @@ using System; using Prowl.Runtime.Cloning; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Prowl.Runtime.csproj b/Prowl.Runtime/Prowl.Runtime.csproj index 8bb16de6a..7654605ad 100644 --- a/Prowl.Runtime/Prowl.Runtime.csproj +++ b/Prowl.Runtime/Prowl.Runtime.csproj @@ -63,6 +63,7 @@ + diff --git a/Prowl.Runtime/Rendering/Compute/ComputeKernel.cs b/Prowl.Runtime/Rendering/Compute/ComputeKernel.cs index 27d24f5a2..d9b59573d 100644 --- a/Prowl.Runtime/Rendering/Compute/ComputeKernel.cs +++ b/Prowl.Runtime/Rendering/Compute/ComputeKernel.cs @@ -6,6 +6,7 @@ using System.Linq; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime.Rendering; diff --git a/Prowl.Runtime/Rendering/Compute/ComputeShader.cs b/Prowl.Runtime/Rendering/Compute/ComputeShader.cs index 09c7d82db..ada0e3f47 100644 --- a/Prowl.Runtime/Rendering/Compute/ComputeShader.cs +++ b/Prowl.Runtime/Rendering/Compute/ComputeShader.cs @@ -8,6 +8,7 @@ using Prowl.Runtime.Rendering; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Rendering/Compute/ComputeVariant.cs b/Prowl.Runtime/Rendering/Compute/ComputeVariant.cs index 11053e431..9aa1e6bd2 100644 --- a/Prowl.Runtime/Rendering/Compute/ComputeVariant.cs +++ b/Prowl.Runtime/Rendering/Compute/ComputeVariant.cs @@ -4,6 +4,7 @@ using System; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime.Rendering; diff --git a/Prowl.Runtime/Rendering/KeywordState.cs b/Prowl.Runtime/Rendering/KeywordState.cs index 3802a3829..68a8256d7 100644 --- a/Prowl.Runtime/Rendering/KeywordState.cs +++ b/Prowl.Runtime/Rendering/KeywordState.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Linq; +using Prowl.Echo; + namespace Prowl.Runtime.Rendering; /// diff --git a/Prowl.Runtime/Rendering/PropertyState.cs b/Prowl.Runtime/Rendering/PropertyState.cs index 1816c958d..cbf39171f 100644 --- a/Prowl.Runtime/Rendering/PropertyState.cs +++ b/Prowl.Runtime/Rendering/PropertyState.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Runtime.InteropServices; +using Prowl.Echo; + using Matrix4x4F = System.Numerics.Matrix4x4; using Vector2F = System.Numerics.Vector2; using Vector3F = System.Numerics.Vector3; diff --git a/Prowl.Runtime/Rendering/Shader/ShaderPass.cs b/Prowl.Runtime/Rendering/Shader/ShaderPass.cs index bb325c38e..520939a04 100644 --- a/Prowl.Runtime/Rendering/Shader/ShaderPass.cs +++ b/Prowl.Runtime/Rendering/Shader/ShaderPass.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Linq; +using Prowl.Echo; + using Veldrid; namespace Prowl.Runtime.Rendering; diff --git a/Prowl.Runtime/Rendering/Shader/ShaderProperty.cs b/Prowl.Runtime/Rendering/Shader/ShaderProperty.cs index 531d91c02..0e88a151d 100644 --- a/Prowl.Runtime/Rendering/Shader/ShaderProperty.cs +++ b/Prowl.Runtime/Rendering/Shader/ShaderProperty.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.Rendering; diff --git a/Prowl.Runtime/Rendering/Shader/ShaderVariant.cs b/Prowl.Runtime/Rendering/Shader/ShaderVariant.cs index 99f68d341..49cb9ae15 100644 --- a/Prowl.Runtime/Rendering/Shader/ShaderVariant.cs +++ b/Prowl.Runtime/Rendering/Shader/ShaderVariant.cs @@ -5,6 +5,7 @@ using System.Linq; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime.Rendering; diff --git a/Prowl.Runtime/Rendering/Texture/RenderTexture.cs b/Prowl.Runtime/Rendering/Texture/RenderTexture.cs index 8edd7b6a0..aed25aa82 100644 --- a/Prowl.Runtime/Rendering/Texture/RenderTexture.cs +++ b/Prowl.Runtime/Rendering/Texture/RenderTexture.cs @@ -6,6 +6,8 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; +using Prowl.Echo; + using Veldrid; namespace Prowl.Runtime.Rendering; @@ -249,9 +251,9 @@ public override void OnDispose() Framebuffer = null; } - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - SerializedProperty compoundTag = SerializedProperty.NewCompound(); + EchoObject compoundTag = EchoObject.NewCompound(); SerializeHeader(compoundTag); @@ -261,7 +263,7 @@ public SerializedProperty Serialize(Serializer.SerializationContext ctx) compoundTag.Add("DepthBufferFormat", new(DepthBuffer != null ? (int)DepthBuffer.Format : -1)); - SerializedProperty colorBuffersTag = SerializedProperty.NewList(); + EchoObject colorBuffersTag = EchoObject.NewList(); if (ColorBuffers != null) { @@ -274,7 +276,7 @@ public SerializedProperty Serialize(Serializer.SerializationContext ctx) return compoundTag; } - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { DeserializeHeader(value); diff --git a/Prowl.Runtime/Rendering/Texture/Texture.cs b/Prowl.Runtime/Rendering/Texture/Texture.cs index bb98df591..f2619c096 100644 --- a/Prowl.Runtime/Rendering/Texture/Texture.cs +++ b/Prowl.Runtime/Rendering/Texture/Texture.cs @@ -6,6 +6,7 @@ using System.Runtime.InteropServices; using Veldrid; +using Prowl.Echo; using static Prowl.Runtime.Rendering.TextureUtility; @@ -349,7 +350,7 @@ public bool Equals(Texture other, bool compareMS = true) } - public abstract SerializedProperty Serialize(Serializer.SerializationContext ctx); + public abstract EchoObject Serialize(SerializationContext ctx); - public abstract void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx); + public abstract void Deserialize(EchoObject value, SerializationContext ctx); } diff --git a/Prowl.Runtime/Rendering/Texture/Texture2D.cs b/Prowl.Runtime/Rendering/Texture/Texture2D.cs index b0fa8dda3..2c0fc2c60 100644 --- a/Prowl.Runtime/Rendering/Texture/Texture2D.cs +++ b/Prowl.Runtime/Rendering/Texture/Texture2D.cs @@ -4,6 +4,7 @@ using System; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime.Rendering; @@ -159,9 +160,9 @@ public void RecreateTexture(uint width, uint height) }); } - public override SerializedProperty Serialize(Serializer.SerializationContext ctx) + public override EchoObject Serialize(SerializationContext ctx) { - SerializedProperty compoundTag = SerializedProperty.NewCompound(); + EchoObject compoundTag = EchoObject.NewCompound(); SerializeHeader(compoundTag); @@ -179,7 +180,7 @@ public override SerializedProperty Serialize(Serializer.SerializationContext ctx return compoundTag; } - public override void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public override void Deserialize(EchoObject value, SerializationContext ctx) { DeserializeHeader(value); diff --git a/Prowl.Runtime/Rendering/Texture/Texture2DArray.cs b/Prowl.Runtime/Rendering/Texture/Texture2DArray.cs index 1b01aeccf..6e24da63e 100644 --- a/Prowl.Runtime/Rendering/Texture/Texture2DArray.cs +++ b/Prowl.Runtime/Rendering/Texture/Texture2DArray.cs @@ -4,6 +4,7 @@ using System; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime.Rendering; @@ -142,9 +143,9 @@ public uint GetSingleTextureMemoryUsage() return Width * Height * TextureUtility.PixelFormatBytes(Format); } - public override SerializedProperty Serialize(Serializer.SerializationContext ctx) + public override EchoObject Serialize(SerializationContext ctx) { - SerializedProperty compoundTag = SerializedProperty.NewCompound(); + EchoObject compoundTag = EchoObject.NewCompound(); SerializeHeader(compoundTag); @@ -156,7 +157,7 @@ public override SerializedProperty Serialize(Serializer.SerializationContext ctx compoundTag.Add("ImageFormat", new((int)Format)); compoundTag.Add("Usage", new((int)Usage)); - SerializedProperty dataTag = SerializedProperty.NewList(); + EchoObject dataTag = EchoObject.NewList(); for (uint i = 0; i < Layers; i++) { @@ -170,7 +171,7 @@ public override SerializedProperty Serialize(Serializer.SerializationContext ctx return compoundTag; } - public override void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public override void Deserialize(EchoObject value, SerializationContext ctx) { DeserializeHeader(value); diff --git a/Prowl.Runtime/Rendering/Texture/Texture3D.cs b/Prowl.Runtime/Rendering/Texture/Texture3D.cs index 02f77aea8..149e59309 100644 --- a/Prowl.Runtime/Rendering/Texture/Texture3D.cs +++ b/Prowl.Runtime/Rendering/Texture/Texture3D.cs @@ -4,6 +4,7 @@ using System; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime.Rendering; @@ -148,9 +149,9 @@ public void RecreateTexture(uint width, uint height, uint depth) }); } - public override SerializedProperty Serialize(Serializer.SerializationContext ctx) + public override EchoObject Serialize(SerializationContext ctx) { - SerializedProperty compoundTag = SerializedProperty.NewCompound(); + EchoObject compoundTag = EchoObject.NewCompound(); SerializeHeader(compoundTag); @@ -169,7 +170,7 @@ public override SerializedProperty Serialize(Serializer.SerializationContext ctx return compoundTag; } - public override void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public override void Deserialize(EchoObject value, SerializationContext ctx) { DeserializeHeader(value); diff --git a/Prowl.Runtime/Rendering/Texture/TextureSampler.cs b/Prowl.Runtime/Rendering/Texture/TextureSampler.cs index c117a2b9b..ce5427924 100644 --- a/Prowl.Runtime/Rendering/Texture/TextureSampler.cs +++ b/Prowl.Runtime/Rendering/Texture/TextureSampler.cs @@ -4,6 +4,7 @@ using System; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime.Rendering; @@ -194,9 +195,9 @@ private static bool CompareDescriptions(in SamplerDescription desc1, in SamplerD desc1.MinimumLod == desc2.MinimumLod; } - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - SerializedProperty compoundTag = SerializedProperty.NewCompound(); + EchoObject compoundTag = EchoObject.NewCompound(); compoundTag.Add("WrapModeU", new((int)WrapModeU)); compoundTag.Add("WrapModeV", new((int)WrapModeV)); @@ -211,7 +212,7 @@ public SerializedProperty Serialize(Serializer.SerializationContext ctx) return compoundTag; } - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { WrapModeU = (TextureWrapMode)value["WrapModeU"].IntValue; WrapModeV = (TextureWrapMode)value["WrapModeV"].IntValue; diff --git a/Prowl.Runtime/Resources/AnimationClip.cs b/Prowl.Runtime/Resources/AnimationClip.cs index a1186f4ac..058deeb34 100644 --- a/Prowl.Runtime/Resources/AnimationClip.cs +++ b/Prowl.Runtime/Resources/AnimationClip.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; +using Prowl.Echo; namespace Prowl.Runtime; public enum AnimationWrapMode @@ -83,7 +84,7 @@ public void EnsureQuaternionContinuity() } } - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { Name = value.Get("Name").StringValue; Duration = value.Get("Duration").DoubleValue; @@ -117,20 +118,20 @@ public void Deserialize(SerializedProperty value, Serializer.SerializationContex _boneMap = Bones.ToDictionary(b => b.BoneName); } - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - var value = SerializedProperty.NewCompound(); - value.Add("Name", new SerializedProperty(Name)); - value.Add("Duration", new SerializedProperty(Duration)); - value.Add("TicksPerSecond", new SerializedProperty(TicksPerSecond)); - value.Add("DurationInTicks", new SerializedProperty(DurationInTicks)); - value.Add("Wrap", new SerializedProperty((int)Wrap)); - - var boneList = SerializedProperty.NewList(); + var value = EchoObject.NewCompound(); + value.Add("Name", new EchoObject(Name)); + value.Add("Duration", new EchoObject(Duration)); + value.Add("TicksPerSecond", new EchoObject(TicksPerSecond)); + value.Add("DurationInTicks", new EchoObject(DurationInTicks)); + value.Add("Wrap", new EchoObject((int)Wrap)); + + var boneList = EchoObject.NewList(); foreach (var bone in Bones) { - var boneProp = SerializedProperty.NewCompound(); - boneProp.Add("BoneName", new SerializedProperty(bone.BoneName)); + var boneProp = EchoObject.NewCompound(); + boneProp.Add("BoneName", new EchoObject(bone.BoneName)); boneProp.Add("PosX", Serializer.Serialize(bone.PosX, ctx)); boneProp.Add("PosY", Serializer.Serialize(bone.PosY, ctx)); diff --git a/Prowl.Runtime/Resources/Font.cs b/Prowl.Runtime/Resources/Font.cs index 40644ff83..8b5d265e9 100644 --- a/Prowl.Runtime/Resources/Font.cs +++ b/Prowl.Runtime/Resources/Font.cs @@ -14,6 +14,7 @@ using StbTrueTypeSharp; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime; @@ -490,9 +491,9 @@ public Rect RenderText(double size, Vector2 pos, Color32 color, Vector4 clipRect } - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - var compoundTag = SerializedProperty.NewCompound(); + var compoundTag = EchoObject.NewCompound(); compoundTag.Add("Width", new(Width)); compoundTag.Add("Height", new(Height)); @@ -509,10 +510,10 @@ public SerializedProperty Serialize(Serializer.SerializationContext ctx) compoundTag.Add("Bitmap", new(memoryStream.ToArray())); } - SerializedProperty glyphsTag = SerializedProperty.NewList(); + EchoObject glyphsTag = EchoObject.NewList(); foreach (var glyph in Glyphs) { - var glyphTag = SerializedProperty.NewCompound(); + var glyphTag = EchoObject.NewCompound(); glyphTag.Add("Unicode", new(glyph.Key)); glyphTag.Add("X", new(glyph.Value.X)); glyphTag.Add("Y", new(glyph.Value.Y)); @@ -528,7 +529,7 @@ public SerializedProperty Serialize(Serializer.SerializationContext ctx) return compoundTag; } - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { Width = value["Width"].IntValue; Height = value["Height"].IntValue; diff --git a/Prowl.Runtime/Resources/Material.cs b/Prowl.Runtime/Resources/Material.cs index 98284c00e..915f9853d 100644 --- a/Prowl.Runtime/Resources/Material.cs +++ b/Prowl.Runtime/Resources/Material.cs @@ -10,6 +10,7 @@ using Vector4F = System.Numerics.Vector4; using Prowl.Runtime.Rendering; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Resources/Mesh.cs b/Prowl.Runtime/Resources/Mesh.cs index 019704021..7f2062455 100644 --- a/Prowl.Runtime/Resources/Mesh.cs +++ b/Prowl.Runtime/Resources/Mesh.cs @@ -6,6 +6,7 @@ using System.IO; using Veldrid; +using Prowl.Echo; using Prowl.Runtime.Rendering; @@ -782,9 +783,9 @@ public static Mesh CreateTriangle(Vector3 a, Vector3 b, Vector3 c) return mesh; } - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - var compoundTag = SerializedProperty.NewCompound(); + var compoundTag = EchoObject.NewCompound(); using (MemoryStream memoryStream = new()) using (BinaryWriter writer = new(memoryStream)) @@ -805,7 +806,7 @@ public SerializedProperty Serialize(Serializer.SerializationContext ctx) WriteArray(writer, _bindPoses); - compoundTag.Add("MeshData", new SerializedProperty(memoryStream.ToArray())); + compoundTag.Add("MeshData", new EchoObject(memoryStream.ToArray())); } // write bounds @@ -833,7 +834,7 @@ private static unsafe void WriteArray(BinaryWriter writer, T[]? data) where T writer.Write(new Span(dataPtr, sizeof(T) * data.Length)); } - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { using (MemoryStream memoryStream = new(value["MeshData"].ByteArrayValue)) using (BinaryReader reader = new(memoryStream)) diff --git a/Prowl.Runtime/Resources/Prefab.cs b/Prowl.Runtime/Resources/Prefab.cs index 0a52e984e..18f2cc3cf 100644 --- a/Prowl.Runtime/Resources/Prefab.cs +++ b/Prowl.Runtime/Resources/Prefab.cs @@ -9,6 +9,7 @@ using Prowl.Runtime.Cloning; using Prowl.Runtime.SceneManagement; using Prowl.Runtime.Utilities; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Resources/Scene.cs b/Prowl.Runtime/Resources/Scene.cs index e8b8e0d3a..9cdbc575e 100644 --- a/Prowl.Runtime/Resources/Scene.cs +++ b/Prowl.Runtime/Resources/Scene.cs @@ -8,6 +8,7 @@ using Prowl.Runtime.Utilities; using Vortice.Direct3D11; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Resources/ScriptableObject.cs b/Prowl.Runtime/Resources/ScriptableObject.cs index 29ff2f974..00f5e0ea5 100644 --- a/Prowl.Runtime/Resources/ScriptableObject.cs +++ b/Prowl.Runtime/Resources/ScriptableObject.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime; public abstract class ScriptableObject : EngineObject, ISerializationCallbackReceiver diff --git a/Prowl.Runtime/Resources/Shader.cs b/Prowl.Runtime/Resources/Shader.cs index 3ad87052c..be2797ef5 100644 --- a/Prowl.Runtime/Resources/Shader.cs +++ b/Prowl.Runtime/Resources/Shader.cs @@ -8,6 +8,7 @@ using Prowl.Runtime.Rendering; using Veldrid; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/SceneManager.cs b/Prowl.Runtime/SceneManager.cs index d5c64f744..55c49283a 100644 --- a/Prowl.Runtime/SceneManager.cs +++ b/Prowl.Runtime/SceneManager.cs @@ -8,6 +8,7 @@ using Prowl.Runtime.Rendering; using Prowl.Runtime.Rendering.Pipelines; using Prowl.Runtime.Utils; +using Prowl.Echo; namespace Prowl.Runtime.SceneManagement; @@ -17,7 +18,7 @@ public static class SceneManager public static Scene Scene => Current.Res!; - private static SerializedProperty? StoredScene; + private static EchoObject? StoredScene; private static Guid StoredSceneID; public static void Initialize() diff --git a/Prowl.Runtime/Serializer/FileFormats/BinaryTagConverter.cs b/Prowl.Runtime/Serializer/FileFormats/BinaryTagConverter.cs deleted file mode 100644 index 290e6cfa6..000000000 --- a/Prowl.Runtime/Serializer/FileFormats/BinaryTagConverter.cs +++ /dev/null @@ -1,126 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; -using System.IO; -using System.Linq; - -namespace Prowl.Runtime; - -/// -/// This class is responsible for converting CompoundTags to and from binary data. -/// Binary data is not human-readable, so bad for git, and doesn't work well with versioning, but it is much more compact than text data. -/// Works great for sending data over the network, or for standalone builds. -/// -public static class BinaryTagConverter -{ - - #region Writing - public static void WriteToFile(SerializedProperty tag, FileInfo file) - { - using var stream = file.OpenWrite(); - using var writer = new BinaryWriter(stream); - WriteTo(tag, writer); - } - - public static void WriteTo(SerializedProperty tag, BinaryWriter writer) => WriteCompound(tag, writer); - - private static void WriteCompound(SerializedProperty tag, BinaryWriter writer) - { - writer.Write(tag.GetAllTags().Count()); - foreach (var subTag in tag.Tags) - { - writer.Write(subTag.Key); // Compounds always need tag names - WriteTag(subTag.Value, writer); - } - } - - private static void WriteTag(SerializedProperty tag, BinaryWriter writer) - { - var type = tag.TagType; - writer.Write((byte)type); - if (type == PropertyType.Null) { } // Nothing for Null - else if (type == PropertyType.Byte) writer.Write(tag.ByteValue); - else if (type == PropertyType.sByte) writer.Write(tag.sByteValue); - else if (type == PropertyType.Short) writer.Write(tag.ShortValue); - else if (type == PropertyType.Int) writer.Write(tag.IntValue); - else if (type == PropertyType.Long) writer.Write(tag.LongValue); - else if (type == PropertyType.UShort) writer.Write(tag.UShortValue); - else if (type == PropertyType.UInt) writer.Write(tag.UIntValue); - else if (type == PropertyType.ULong) writer.Write(tag.ULongValue); - else if (type == PropertyType.Float) writer.Write(tag.FloatValue); - else if (type == PropertyType.Double) writer.Write(tag.DoubleValue); - else if (type == PropertyType.Decimal) writer.Write(tag.DecimalValue); - else if (type == PropertyType.String) writer.Write(tag.StringValue); - else if (type == PropertyType.ByteArray) - { - writer.Write(tag.ByteArrayValue.Length); - writer.Write(tag.ByteArrayValue); - } - else if (type == PropertyType.Bool) writer.Write(tag.BoolValue); - else if (type == PropertyType.List) - { - var listTag = tag; - writer.Write(listTag.Count); - foreach (var subTag in listTag.List) - WriteTag(subTag, writer); // Lists dont care about names, so dont need to write Tag Names inside a List - } - else if (type == PropertyType.Compound) WriteCompound(tag, writer); - else throw new Exception($"Unknown tag type: {type}"); - } - - #endregion - - - #region Reading - public static SerializedProperty ReadFromFile(FileInfo file) - { - using var stream = file.OpenRead(); - using var reader = new BinaryReader(stream); - return ReadFrom(reader); - } - - public static SerializedProperty ReadFrom(BinaryReader reader) => ReadCompound(reader); - - private static SerializedProperty ReadCompound(BinaryReader reader) - { - SerializedProperty tag = SerializedProperty.NewCompound(); - var tagCount = reader.ReadInt32(); - for (int i = 0; i < tagCount; i++) - tag.Add(reader.ReadString(), ReadTag(reader)); - return tag; - } - - private static SerializedProperty ReadTag(BinaryReader reader) - { - var type = (PropertyType)reader.ReadByte(); - if (type == PropertyType.Null) return new(PropertyType.Null, null); - else if (type == PropertyType.Byte) return new(PropertyType.Byte, reader.ReadByte()); - else if (type == PropertyType.sByte) return new(PropertyType.sByte, reader.ReadSByte()); - else if (type == PropertyType.Short) return new(PropertyType.Short, reader.ReadInt16()); - else if (type == PropertyType.Int) return new(PropertyType.Int, reader.ReadInt32()); - else if (type == PropertyType.Long) return new(PropertyType.Long, reader.ReadInt64()); - else if (type == PropertyType.UShort) return new(PropertyType.UShort, reader.ReadUInt16()); - else if (type == PropertyType.UInt) return new(PropertyType.UInt, reader.ReadUInt32()); - else if (type == PropertyType.ULong) return new(PropertyType.ULong, reader.ReadUInt64()); - else if (type == PropertyType.Float) return new(PropertyType.Float, reader.ReadSingle()); - else if (type == PropertyType.Double) return new(PropertyType.Double, reader.ReadDouble()); - else if (type == PropertyType.Decimal) return new(PropertyType.Decimal, reader.ReadDecimal()); - else if (type == PropertyType.String) return new(PropertyType.String, reader.ReadString()); - else if (type == PropertyType.ByteArray) return new(PropertyType.ByteArray, reader.ReadBytes(reader.ReadInt32())); - else if (type == PropertyType.Bool) return new(PropertyType.Bool, reader.ReadBoolean()); - else if (type == PropertyType.List) - { - var listTag = SerializedProperty.NewList(); - var tagCount = reader.ReadInt32(); - for (int i = 0; i < tagCount; i++) - listTag.ListAdd(ReadTag(reader)); - return listTag; - } - else if (type == PropertyType.Compound) return ReadCompound(reader); - else throw new Exception($"Unknown tag type: {type}"); - } - - #endregion - -} diff --git a/Prowl.Runtime/Serializer/FileFormats/StringTagConverter.cs b/Prowl.Runtime/Serializer/FileFormats/StringTagConverter.cs deleted file mode 100644 index 87a5c5d53..000000000 --- a/Prowl.Runtime/Serializer/FileFormats/StringTagConverter.cs +++ /dev/null @@ -1,459 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; - -namespace Prowl.Runtime; - -public static partial class StringTagConverter -{ - // Writing: - - public static void WriteToFile(SerializedProperty tag, FileInfo file) - { - string json = Write(tag); - File.WriteAllText(file.FullName, json); - } - - public static string Write(SerializedProperty prop) - { - using var writer = new StringWriter(); - Serialize(prop, writer, 0); - return writer.ToString(); - } - - public static SerializedProperty ReadFromFile(FileInfo file) - { - string json = File.ReadAllText(file.FullName); - return Read(json); - } - - public static SerializedProperty Read(string input) - { - StringTagTokenizer parser = new(input.ToCharArray()); - - if (!parser.MoveNext()) - throw new InvalidDataException("Empty input"); - - try - { - return ReadTag(parser); - } - catch (Exception e) - { - e.Data[nameof(parser.TokenPosition)] = parser.TokenPosition; - throw; - } - } - - private static void Serialize(SerializedProperty prop, TextWriter writer, int indentLevel) - { - var indent = new string(' ', indentLevel * 2); - - switch (prop.TagType) - { - case PropertyType.Null: - writer.Write("NULL"); - break; - case PropertyType.Byte: - writer.Write(prop.ByteValue); - writer.Write('B'); - break; - case PropertyType.sByte: - writer.Write(prop.sByteValue); - writer.Write('N'); - break; - case PropertyType.Short: - writer.Write(prop.ShortValue); - writer.Write('S'); - break; - case PropertyType.Int: - writer.Write(prop.IntValue); - break; - case PropertyType.Long: - writer.Write(prop.LongValue); - writer.Write('L'); - break; - case PropertyType.UShort: - writer.Write(prop.UShortValue); - writer.Write('V'); - break; - case PropertyType.UInt: - writer.Write(prop.UIntValue); - writer.Write('U'); - break; - case PropertyType.ULong: - writer.Write(prop.ULongValue); - writer.Write('C'); - break; - case PropertyType.Float: - writer.Write(prop.FloatValue.ToString(CultureInfo.InvariantCulture)); - writer.Write('F'); - break; - case PropertyType.Double: - writer.Write(prop.DoubleValue.ToString(CultureInfo.InvariantCulture)); - writer.Write('D'); - break; - case PropertyType.Decimal: - writer.Write(prop.DecimalValue.ToString(CultureInfo.InvariantCulture)); - writer.Write('M'); - break; - case PropertyType.String: - WriteString(writer, prop.StringValue); - break; - case PropertyType.ByteArray: - WriteByteArray(writer, prop.ByteArrayValue); - break; - case PropertyType.Bool: - writer.Write(prop.BoolValue ? "true" : "false"); - break; - case PropertyType.List: - writer.WriteLine("["); - var list = (List)prop.Value!; - for (int i = 0; i < list.Count; i++) - { - writer.Write(indent); - writer.Write(" "); - Serialize(list[i], writer, indentLevel + 1); - if (i < list.Count - 1) - { - writer.Write(","); - writer.WriteLine(); - } - } - writer.WriteLine(); - writer.Write(indent); - writer.Write("]"); - break; - case PropertyType.Compound: - WriteCompound(writer, (Dictionary)prop.Value!, indentLevel); - break; - } - } - - private static void WriteString(TextWriter writer, string value) - { - writer.Write('"'); - foreach (var c in value) - { - switch (c) - { - case '"': - writer.Write("\\\""); - break; - case '\\': - writer.Write("\\\\"); - break; - case '\n': - writer.Write("\\n"); - break; - case '\r': - writer.Write("\\r"); - break; - case '\t': - writer.Write("\\t"); - break; - default: - writer.Write(c); - break; - } - } - writer.Write('"'); - } - - private static void WriteByteArray(TextWriter writer, byte[] value) - { - writer.Write("[B;"); - writer.Write(Convert.ToBase64String(value)); - writer.Write(']'); - } - - private static void WriteCompound(TextWriter writer, Dictionary dict, int indentLevel) - { - var indent = new string(' ', indentLevel * 2); - - writer.WriteLine("{"); - - // Write "$id" and "$type" keys first, if they exist - if (dict.ContainsKey("$id")) - { - WriteCompoundElement("$id", writer, dict, indentLevel, indent); - writer.Write(","); - writer.WriteLine(); - } - - if (dict.ContainsKey("$type")) - { - WriteCompoundElement("$type", writer, dict, indentLevel, indent); - writer.Write(","); - writer.WriteLine(); - } - - if (dict.ContainsKey("$dependencies")) - { - WriteCompoundElement("$dependencies", writer, dict, indentLevel, indent); - writer.Write(","); - writer.WriteLine(); - } - - // Write the remaining key-value pairs - var skipNextComma = true; - foreach (var kvp in dict) - { - if (kvp.Key == "$id" || kvp.Key == "$type" || kvp.Key == "$dependencies") - continue; - - if (!skipNextComma) - { - skipNextComma = false; - writer.Write(","); - writer.WriteLine(); - } - skipNextComma = false; - - WriteCompoundElement(kvp.Key, writer, dict, indentLevel, indent); - } - - writer.WriteLine(); - writer.Write(indent); - writer.Write("}"); - } - - private static void WriteCompoundElement(string key, TextWriter writer, Dictionary dict, int indentLevel, string indent) - { - writer.Write(indent); - writer.Write(" "); - WriteString(writer, key); - writer.Write(": "); - Serialize(dict[key], writer, indentLevel + 1); - } - - // Reading: - - public enum TextTokenType - { - None, - BeginCompound, - EndCompound, - BeginList, - BeginArray, - EndList, - Separator, - NameValueSeparator, - Value - } - - private static SerializedProperty ReadTag(StringTagTokenizer parser) - { - return parser.TokenType switch - { - TextTokenType.BeginCompound => ReadCompoundTag(parser), - TextTokenType.BeginList => ReadListTag(parser), - TextTokenType.BeginArray => ReadArrayTag(parser), - TextTokenType.Value => ReadValueTag(parser), - _ => throw new InvalidDataException( - $"Invalid token \"{parser.Token}\" found while reading a property at position {parser.TokenPosition}") - }; - } - - private static SerializedProperty ReadCompoundTag(StringTagTokenizer parser) - { - var startPosition = parser.TokenPosition; - - var dict = new Dictionary(); - while (parser.MoveNext()) - { - switch (parser.TokenType) - { - case TextTokenType.EndCompound: - return new SerializedProperty(PropertyType.Compound, dict); - case TextTokenType.Separator: - continue; - case TextTokenType.Value: - var name = parser.Token[0] is '"' or '\'' ? parser.ParseQuotedStringValue() : new string(parser.Token); - - if (!parser.MoveNext()) - throw new InvalidDataException($"End of input reached while reading a compound property starting at position {startPosition}"); - - if (parser.TokenType != TextTokenType.NameValueSeparator) - throw new InvalidDataException($"Invalid token \"{parser.Token}\" found while reading a compound property at position {parser.TokenPosition}"); - - if (!parser.MoveNext()) - throw new InvalidDataException($"End of input reached while reading a compound property starting at position {startPosition}"); - - var value = ReadTag(parser); - - dict.Add(name, value); - - continue; - default: - throw new InvalidDataException($"Invalid token \"{parser.Token}\" found while reading a compound property at position {parser.TokenPosition}"); - } - } - - throw new InvalidDataException($"End of input reached while reading a compound property starting at position {startPosition}"); - } - - private static SerializedProperty ReadListTag(StringTagTokenizer parser) - { - var startPosition = parser.TokenPosition; - - var items = new List(); - - while (parser.MoveNext()) - { - switch (parser.TokenType) - { - case TextTokenType.EndList: - return new SerializedProperty(PropertyType.List, items); - case TextTokenType.Separator: - continue; - } - - var tag = ReadTag(parser); - - items.Add(tag); - } - - throw new InvalidDataException($"End of input reached while reading a list property starting at position {startPosition}"); - } - - private static SerializedProperty ReadArrayTag(StringTagTokenizer parser) - { - return parser.Token[1] switch - { - 'B' => ReadByteArrayTag(parser), - _ => throw new InvalidDataException($"Invalid array type \"{parser.Token[1]}\" at position {parser.TokenPosition}") - }; - } - - private static SerializedProperty ReadByteArrayTag(StringTagTokenizer parser) - { - var startPosition = parser.TokenPosition; - - byte[] arr = null; - while (parser.MoveNext()) - { - switch (parser.TokenType) - { - case TextTokenType.EndList: - return new SerializedProperty(arr!); - case TextTokenType.Separator: - continue; - case TextTokenType.Value: - arr = Convert.FromBase64String(parser.Token.ToString()); - continue; - default: - throw new InvalidDataException($"Invalid token \"{parser.Token}\" found while reading a byte array at position {parser.TokenPosition}"); - } - } - - throw new InvalidDataException($"End of input reached while reading a byte array starting at position {startPosition}"); - } - - private static SerializedProperty ReadValueTag(StringTagTokenizer parser) - { - // null - if (parser.Token.SequenceEqual("NULL")) return new SerializedProperty(PropertyType.Null, null); - - // boolean - if (parser.Token.SequenceEqual("false")) return new SerializedProperty(false); - if (parser.Token.SequenceEqual("true")) return new SerializedProperty(true); - - // string - if (parser.Token[0] is '"' or '\'') - return new SerializedProperty(parser.ParseQuotedStringValue()); - - if (char.IsLetter(parser.Token[0])) - return new SerializedProperty(new string(parser.Token)); - - // number - if (parser.Token[0] >= '0' && parser.Token[0] <= '9' || parser.Token[0] is '+' or '-' or '.') - return ReadNumberTag(parser); - - throw new InvalidDataException($"Invalid value \"{parser.Token}\" found while reading a tag at position {parser.TokenPosition}"); - } - - private static SerializedProperty ReadNumberTag(StringTagTokenizer parser) - { - static T ParsePrimitive(StringTagTokenizer parser) where T : unmanaged - => (T)Convert.ChangeType(new string(parser.Token[..^1]), typeof(T)); - - return parser.Token[^1] switch - { - 'B' => new SerializedProperty(ParsePrimitive(parser)), - 'N' => new SerializedProperty(ParsePrimitive(parser)), - 'S' => new SerializedProperty(ParsePrimitive(parser)), - 'I' => new SerializedProperty(ParsePrimitive(parser)), - 'L' => new SerializedProperty(ParsePrimitive(parser)), - 'V' => new SerializedProperty(ParsePrimitive(parser)), - 'U' => new SerializedProperty(ParsePrimitive(parser)), - 'C' => new SerializedProperty(ParsePrimitive(parser)), - 'F' => new SerializedProperty(ParsePrimitive(parser)), - 'D' => new SerializedProperty(ParsePrimitive(parser)), - 'M' => new SerializedProperty(ParsePrimitive(parser)), - >= '0' and <= '9' => new SerializedProperty((int)Convert.ChangeType(new string(parser.Token), typeof(int))), - _ => throw new InvalidDataException($"Invalid number type indicator found while reading a number \"{parser.Token}\" at position {parser.TokenPosition}") - }; - } - - public class StringTagTokenizer - { - private readonly Utils.Tokenizer _tokenizer; - - public StringTagTokenizer(ReadOnlyMemory input) - { - var symbolHandlers = new Dictionary> - { - {'{', () => HandleSingleCharToken(TextTokenType.BeginCompound)}, - {'}', () => HandleSingleCharToken(TextTokenType.EndCompound)}, - {'[', () => HandleOpenBracket()}, - {']', () => HandleSingleCharToken(TextTokenType.EndList)}, - {',', () => HandleSingleCharToken(TextTokenType.Separator)}, - {':', () => HandleSingleCharToken(TextTokenType.NameValueSeparator)} - }; - - _tokenizer = new Utils.Tokenizer( - input, - symbolHandlers, - c => c is '{' or '}' or ',' or ';' or ':' or '[' or ']', - TextTokenType.Value, - TextTokenType.None - ); - } - - private TextTokenType HandleSingleCharToken(TextTokenType tokenType) - { - _tokenizer.TokenMemory = _tokenizer.Input.Slice(_tokenizer.TokenPosition, 1); - _tokenizer.IncrementInputPosition(); - return tokenType; - } - - private TextTokenType HandleOpenBracket() - { - if (_tokenizer.InputPosition + 2 < _tokenizer.Input.Length && - _tokenizer.Input.Span[_tokenizer.InputPosition + 2] == ';') - { - _tokenizer.TokenMemory = _tokenizer.Input.Slice(_tokenizer.TokenPosition, 3); - _tokenizer.IncrementInputPosition(3); - return TextTokenType.BeginArray; - } - - return HandleSingleCharToken(TextTokenType.BeginList); - } - - public bool MoveNext() => _tokenizer.MoveNext(); - - public string ParseQuotedStringValue() => _tokenizer.ParseQuotedStringValue(); - - public TextTokenType TokenType => _tokenizer.TokenType; - public ReadOnlySpan Token => _tokenizer.Token; - public int TokenPosition => _tokenizer.TokenPosition; - public int InputPosition => _tokenizer.InputPosition; - } - - -} diff --git a/Prowl.Runtime/Serializer/Formatters/AnyObjectFormat.cs b/Prowl.Runtime/Serializer/Formatters/AnyObjectFormat.cs deleted file mode 100644 index 984aecab5..000000000 --- a/Prowl.Runtime/Serializer/Formatters/AnyObjectFormat.cs +++ /dev/null @@ -1,144 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; -using System.Linq; - -namespace Prowl.Runtime.Serialization.Formatters; - -// DO NOT CACHE REFLECTION! It actually makes it slower! (Atleast with every attempt i've made) -// Modern .NET have internal caching for reflection as well as Source Generators - -public class AnyObjectFormat : ISerializationFormat -{ - public bool CanHandle(Type type) => true; // Fallback format for any object - - public SerializedProperty Serialize(object value, Serializer.SerializationContext context) - { - var compound = SerializedProperty.NewCompound(); - Type type = value.GetType(); - - if (context.objectToId.TryGetValue(value, out int id)) - { - compound["$id"] = new(PropertyType.Int, id); - return compound; - } - - id = context.nextId++; - context.objectToId[value] = id; - context.idToObject[id] = value; - - context.BeginDependencies(); - - if (value is ISerializationCallbackReceiver callback) - callback.OnBeforeSerialize(); - - if (value is ISerializable serializable) - { - compound = serializable.Serialize(context); - } - else - { - foreach (System.Reflection.FieldInfo field in value.GetSerializableFields()) - { - try - { - object? propValue = field.GetValue(value); - if (propValue == null) - { - if (Attribute.GetCustomAttribute(field, typeof(IgnoreOnNullAttribute)) != null) - continue; - compound.Add(field.Name, new(PropertyType.Null, null)); - } - else - { - SerializedProperty tag = Serializer.Serialize(propValue, context); - compound.Add(field.Name, tag); - } - } - catch (Exception ex) - { - Debug.LogException(new Exception($"Failed to serialize field {field.Name}", ex)); - // We don't want to stop the serialization process because of a single field, so we just skip it and continue - } - } - } - - compound["$id"] = new(PropertyType.Int, id); - compound["$type"] = new(PropertyType.String, type.FullName); - context.EndDependencies(); - - return compound; - } - - public object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context) - { - if (value.TryGet("$id", out SerializedProperty? id) && - context.idToObject.TryGetValue(id.IntValue, out object? existingObj)) - return existingObj; - - if (!value.TryGet("$type", out SerializedProperty? typeProperty)) - { - Debug.LogError($"Failed to deserialize object, missing type info"); - return null; - } - - Type? objectType = RuntimeUtils.FindType(typeProperty.StringValue); - if (objectType == null) - { - Debug.LogError($"Couldn't find Type: {typeProperty.StringValue}"); - return null; - } - - object result = Activator.CreateInstance(objectType, true) - ?? throw new InvalidOperationException($"Failed to create instance of type: {objectType}"); - - if (id != null) - context.idToObject[id.IntValue] = result; - - if (result is ISerializable serializable) - { - serializable.Deserialize(value, context); - } - else - { - foreach (System.Reflection.FieldInfo field in result.GetSerializableFields()) - { - if (!TryGetFieldValue(value, field, out SerializedProperty? fieldValue)) - continue; - - try - { - object? deserializedValue = Serializer.Deserialize(fieldValue, field.FieldType, context); - - field.SetValue(result, deserializedValue); - } - catch (Exception ex) - { - Debug.LogException(new Exception($"Failed to deserialize field {field.Name}", ex)); - // We don't want to stop the deserialization process because of a single field, so we just skip it and continue - } - } - } - - if (result is ISerializationCallbackReceiver callback) - callback.OnAfterDeserialize(); - - return result; - } - - private bool TryGetFieldValue(SerializedProperty compound, System.Reflection.FieldInfo field, out SerializedProperty value) - { - if (compound.TryGet(field.Name, out value)) - return true; - - Attribute[] formerNames = Attribute.GetCustomAttributes(field, typeof(FormerlySerializedAsAttribute)); - foreach (FormerlySerializedAsAttribute formerName in formerNames.Cast()) - { - if (compound.TryGet(formerName.oldName, out value)) - return true; - } - - return false; - } -} diff --git a/Prowl.Runtime/Serializer/Formatters/CollectionFormat.cs b/Prowl.Runtime/Serializer/Formatters/CollectionFormat.cs deleted file mode 100644 index 039aa57a4..000000000 --- a/Prowl.Runtime/Serializer/Formatters/CollectionFormat.cs +++ /dev/null @@ -1,138 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Prowl.Runtime.Serialization.Formatters; - -public class CollectionFormat : ISerializationFormat -{ - public bool CanHandle(Type type) => - type.IsArray || - (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)); - - public SerializedProperty Serialize(object value, Serializer.SerializationContext context) - { - if (value is Array array) - { - if (array.Rank == 1) - { - // Single dimensional array - List tags = []; - foreach (var item in array) - tags.Add(Serializer.Serialize(item, context)); - return new SerializedProperty(tags); - } - else - { - // Multi-dimensional array - var compound = SerializedProperty.NewCompound(); - - // Store dimensions - var dimensions = new int[array.Rank]; - for (int i = 0; i < array.Rank; i++) - dimensions[i] = array.GetLength(i); - - compound["dimensions"] = Serializer.Serialize(dimensions, context); - - // Store elements - List elements = []; - SerializeMultiDimensionalArray(array, new int[array.Rank], 0, elements, context); - compound["elements"] = new SerializedProperty(elements); - - return compound; - } - } - else - { - var list = value as IList ?? throw new InvalidOperationException("Expected IList type"); - List tags = []; - foreach (var item in list) - tags.Add(Serializer.Serialize(item, context)); - return new SerializedProperty(tags); - } - } - - private void SerializeMultiDimensionalArray(Array array, int[] indices, int dimension, List elements, Serializer.SerializationContext context) - { - if (dimension == array.Rank) - { - elements.Add(Serializer.Serialize(array.GetValue(indices), context)); - return; - } - - for (int i = 0; i < array.GetLength(dimension); i++) - { - indices[dimension] = i; - SerializeMultiDimensionalArray(array, indices, dimension + 1, elements, context); - } - } - - public object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context) - { - if (targetType.IsArray) - { - Type elementType = targetType.GetElementType() - ?? throw new InvalidOperationException("Array element type is null"); - - if (value.TagType == PropertyType.List) - { - // Single dimensional array - var array = Array.CreateInstance(elementType, value.Count); - for (int idx = 0; idx < array.Length; idx++) - array.SetValue(Serializer.Deserialize(value[idx], elementType, context), idx); - return array; - } - else if (value.TagType == PropertyType.Compound) - { - // Multi-dimensional array - var dimensionsTag = value.Get("dimensions") - ?? throw new InvalidOperationException("Missing dimensions in multi-dimensional array"); - var dimensions = (int[])Serializer.Deserialize(dimensionsTag, typeof(int[]), context)!; - - var elementsTag = value.Get("elements") - ?? throw new InvalidOperationException("Missing elements in multi-dimensional array"); - var elements = elementsTag.List; - - var array = Array.CreateInstance(elementType, dimensions); - var indices = new int[dimensions.Length]; - int elementIndex = 0; - - DeserializeMultiDimensionalArray(array, indices, 0, elements, ref elementIndex, elementType, context); - return array; - } - else - { - throw new InvalidOperationException("Invalid tag type for array deserialization"); - } - } - else - { - Type elementType = targetType.GetGenericArguments()[0]; - var list = Activator.CreateInstance(targetType) as IList - ?? throw new InvalidOperationException($"Failed to create instance of type: {targetType}"); - - foreach (var tag in value.List) - list.Add(Serializer.Deserialize(tag, elementType, context)); - return list; - } - } - - private void DeserializeMultiDimensionalArray(Array array, int[] indices, int dimension, List elements, ref int elementIndex, Type elementType, Serializer.SerializationContext context) - { - if (dimension == array.Rank) - { - array.SetValue(Serializer.Deserialize(elements[elementIndex], elementType, context), indices); - elementIndex++; - return; - } - - for (int i = 0; i < array.GetLength(dimension); i++) - { - indices[dimension] = i; - DeserializeMultiDimensionalArray(array, indices, dimension + 1, elements, ref elementIndex, elementType, context); - } - } -} diff --git a/Prowl.Runtime/Serializer/Formatters/DateTimeFormat.cs b/Prowl.Runtime/Serializer/Formatters/DateTimeFormat.cs deleted file mode 100644 index 369b424df..000000000 --- a/Prowl.Runtime/Serializer/Formatters/DateTimeFormat.cs +++ /dev/null @@ -1,26 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. -using System; - -namespace Prowl.Runtime.Serialization.Formatters; - -public class DateTimeFormat : ISerializationFormat -{ - public bool CanHandle(Type type) => type == typeof(DateTime); - - public SerializedProperty Serialize(object value, Serializer.SerializationContext context) - { - if (value is DateTime date) - return new(PropertyType.Long, date.ToBinary()); - - throw new NotSupportedException($"Type '{value.GetType()}' is not supported by DateTimeFormat."); - } - - public object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context) - { - if (value.TagType != PropertyType.Long) - throw new Exception($"Expected Long type for DateTime, got {value.TagType}"); - - return DateTime.FromBinary(value.LongValue); - } -} diff --git a/Prowl.Runtime/Serializer/Formatters/DictionaryFormat.cs b/Prowl.Runtime/Serializer/Formatters/DictionaryFormat.cs deleted file mode 100644 index 6b7323b2d..000000000 --- a/Prowl.Runtime/Serializer/Formatters/DictionaryFormat.cs +++ /dev/null @@ -1,86 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Prowl.Runtime.Serialization.Formatters; - -public class DictionaryFormat : ISerializationFormat -{ - public bool CanHandle(Type type) => - type.IsAssignableTo(typeof(IDictionary)) && - type.IsGenericType; - - public SerializedProperty Serialize(object value, Serializer.SerializationContext context) - { - var dict = (IDictionary)value; - var type = value.GetType(); - var keyType = type.GetGenericArguments()[0]; - - if (keyType == typeof(string)) - { - // string-key behavior - var tag = SerializedProperty.NewCompound(); - foreach (DictionaryEntry kvp in dict) - tag.Add((string)kvp.Key, Serializer.Serialize(kvp.Value, context)); - return tag; - } - else - { - // Non-string key behavior - var compound = SerializedProperty.NewCompound(); - var entries = new List(); - - foreach (DictionaryEntry kvp in dict) - { - var entryCompound = SerializedProperty.NewCompound(); - entryCompound.Add("key", Serializer.Serialize(kvp.Key, context)); - entryCompound.Add("value", Serializer.Serialize(kvp.Value, context)); - entries.Add(entryCompound); - } - - compound.Add("$type", new SerializedProperty(PropertyType.String, type.FullName)); - compound.Add("entries", new SerializedProperty(entries)); - return compound; - } - } - - public object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context) - { - Type keyType = targetType.GetGenericArguments()[0]; - Type valueType = targetType.GetGenericArguments()[1]; - - IDictionary dict = Activator.CreateInstance(targetType) as IDictionary - ?? throw new InvalidOperationException($"Failed to create instance of type: {targetType}"); - - if (keyType == typeof(string)) - { - // string-key behavior - foreach (KeyValuePair tag in value.Tags) - dict.Add(tag.Key, Serializer.Deserialize(tag.Value, valueType, context)); - } - else - { - // Non-string key behavior - var entries = value.Get("entries"); - if (entries == null || entries.TagType != PropertyType.List) - throw new InvalidOperationException("Invalid dictionary format"); - - foreach (var entry in entries.List) - { - if (!entry.TryGet("key", out var keyTag) || !entry.TryGet("value", out var valueTag)) - throw new InvalidOperationException("Invalid dictionary entry format"); - - var key = Serializer.Deserialize(keyTag, keyType, context); - var val = Serializer.Deserialize(valueTag, valueType, context); - - if (key != null) // Only add if we have a valid key - dict.Add(key, val); - } - } - - return dict; - } -} diff --git a/Prowl.Runtime/Serializer/Formatters/EnumFormat.cs b/Prowl.Runtime/Serializer/Formatters/EnumFormat.cs deleted file mode 100644 index 802b1d931..000000000 --- a/Prowl.Runtime/Serializer/Formatters/EnumFormat.cs +++ /dev/null @@ -1,27 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; - -namespace Prowl.Runtime.Serialization.Formatters; - -public class EnumFormat : ISerializationFormat -{ - public bool CanHandle(Type type) => type.IsEnum; - - public SerializedProperty Serialize(object value, Serializer.SerializationContext context) - { - if (value is Enum e) - return new(PropertyType.Int, Convert.ToInt32(e)); - - throw new NotSupportedException($"Type '{value.GetType()}' is not supported by EnumFormat."); - } - - public object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context) - { - if (value.TagType != PropertyType.Int) - throw new Exception($"Expected Int type for Enum, got {value.TagType}"); - - return Enum.ToObject(targetType, value.IntValue); - } -} diff --git a/Prowl.Runtime/Serializer/Formatters/GuidFormat.cs b/Prowl.Runtime/Serializer/Formatters/GuidFormat.cs deleted file mode 100644 index b9a4e9850..000000000 --- a/Prowl.Runtime/Serializer/Formatters/GuidFormat.cs +++ /dev/null @@ -1,27 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; - -namespace Prowl.Runtime.Serialization.Formatters; - -public class GuidFormat : ISerializationFormat -{ - public bool CanHandle(Type type) => type == typeof(Guid); - - public SerializedProperty Serialize(object value, Serializer.SerializationContext context) - { - if (value is Guid guid) - return new(PropertyType.String, guid.ToString()); - - throw new NotSupportedException($"Type '{value.GetType()}' is not supported by GuidFormat."); - } - - public object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context) - { - if (value.TagType != PropertyType.String) - throw new Exception($"Expected String type for Guid, got {value.TagType}"); - - return Guid.Parse(value.StringValue); - } -} diff --git a/Prowl.Runtime/Serializer/Formatters/HashSetFormat.cs b/Prowl.Runtime/Serializer/Formatters/HashSetFormat.cs deleted file mode 100644 index ec5676564..000000000 --- a/Prowl.Runtime/Serializer/Formatters/HashSetFormat.cs +++ /dev/null @@ -1,38 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Prowl.Runtime.Serialization.Formatters; - -public class HashSetFormat : ISerializationFormat -{ - public bool CanHandle(Type type) => - type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>); - - public SerializedProperty Serialize(object value, Serializer.SerializationContext context) - { - var hashSet = (IEnumerable)value; - List tags = []; - foreach (var item in hashSet) - tags.Add(Serializer.Serialize(item, context)); - return new SerializedProperty(tags); - } - - public object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context) - { - Type elementType = targetType.GetGenericArguments()[0]; - dynamic hashSet = Activator.CreateInstance(targetType) - ?? throw new InvalidOperationException($"Failed to create instance of type: {targetType}"); - - foreach (var tag in value.List) - { - var item = Serializer.Deserialize(tag, elementType, context); - if (item != null) - hashSet.Add((dynamic)item); - } - return hashSet; - } -} diff --git a/Prowl.Runtime/Serializer/Formatters/NullableFormat.cs b/Prowl.Runtime/Serializer/Formatters/NullableFormat.cs deleted file mode 100644 index 025389c42..000000000 --- a/Prowl.Runtime/Serializer/Formatters/NullableFormat.cs +++ /dev/null @@ -1,44 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; - -namespace Prowl.Runtime.Serialization.Formatters; - -public class NullableFormat : ISerializationFormat -{ - public bool CanHandle(Type type) => - Nullable.GetUnderlyingType(type) != null; - - public SerializedProperty Serialize(object value, Serializer.SerializationContext context) - { - var underlyingType = Nullable.GetUnderlyingType(value.GetType()) - ?? throw new InvalidOperationException("Not a nullable type"); - - // Create compound to store nullable info - var compound = SerializedProperty.NewCompound(); - compound.Add("value", Serializer.Serialize(value, context)); - return compound; - } - - public object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context) - { - var underlyingType = Nullable.GetUnderlyingType(targetType) - ?? throw new InvalidOperationException("Not a nullable type"); - - if (value.TagType == PropertyType.Null) - return null; - - // If it's a compound, get the value - if (value.TagType == PropertyType.Compound && value.TryGet("value", out var valueTag)) - { - if (valueTag.TagType == PropertyType.Null) - return null; - - return Serializer.Deserialize(valueTag, underlyingType, context); - } - - // Direct value case (for backwards compatibility or simpler cases) - return Serializer.Deserialize(value, underlyingType, context); - } -} diff --git a/Prowl.Runtime/Serializer/Formatters/PrimitiveFormat.cs b/Prowl.Runtime/Serializer/Formatters/PrimitiveFormat.cs deleted file mode 100644 index db419009c..000000000 --- a/Prowl.Runtime/Serializer/Formatters/PrimitiveFormat.cs +++ /dev/null @@ -1,52 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. -using System; - -namespace Prowl.Runtime.Serialization.Formatters; - -public class PrimitiveFormat : ISerializationFormat -{ - public bool CanHandle(Type type) => - type.IsPrimitive || - type == typeof(string) || - type == typeof(decimal) || - type == typeof(byte[]); - - public SerializedProperty Serialize(object value, Serializer.SerializationContext context) - { - return value switch - { - char c => new(PropertyType.Byte, (byte)c), // Char is serialized as a byte - byte b => new(PropertyType.Byte, b), - sbyte sb => new(PropertyType.sByte, sb), - short s => new(PropertyType.Short, s), - int i => new(PropertyType.Int, i), - long l => new(PropertyType.Long, l), - uint ui => new(PropertyType.UInt, ui), - ulong ul => new(PropertyType.ULong, ul), - ushort us => new(PropertyType.UShort, us), - float f => new(PropertyType.Float, f), - double d => new(PropertyType.Double, d), - decimal dec => new(PropertyType.Decimal, dec), - string str => new(PropertyType.String, str), - byte[] bArr => new(PropertyType.ByteArray, bArr), - bool bo => new(PropertyType.Bool, bo), - _ => throw new NotSupportedException($"Type '{value.GetType()}' is not supported by PrimitiveFormat.") - }; - } - - public object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context) - { - try - { - if (value.TagType == PropertyType.ByteArray && targetType == typeof(byte[])) - return value.Value; - - return Convert.ChangeType(value.Value, targetType); - } - catch - { - throw new Exception($"Failed to deserialize primitive '{targetType}' with value: {value.Value}"); - } - } -} diff --git a/Prowl.Runtime/Serializer/ISerializable.cs b/Prowl.Runtime/Serializer/ISerializable.cs deleted file mode 100644 index 3e42e65ef..000000000 --- a/Prowl.Runtime/Serializer/ISerializable.cs +++ /dev/null @@ -1,13 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using static Prowl.Runtime.Serializer; - -namespace Prowl.Runtime; - -public interface ISerializable -{ - public SerializedProperty Serialize(SerializationContext ctx); - public void Deserialize(SerializedProperty value, SerializationContext ctx); - -} diff --git a/Prowl.Runtime/Serializer/ISerializationCallbackReceiver.cs b/Prowl.Runtime/Serializer/ISerializationCallbackReceiver.cs deleted file mode 100644 index 1070c6f83..000000000 --- a/Prowl.Runtime/Serializer/ISerializationCallbackReceiver.cs +++ /dev/null @@ -1,21 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -namespace Prowl.Runtime; - -/// -/// Sometimes you dont want a Constructor to be called when deserializing, but still need todo some work after the object has been created -/// This interface allows you to do that -/// -public interface ISerializationCallbackReceiver -{ - /// - /// Called right before the Serializer serializes this object - /// - public void OnBeforeSerialize(); - - /// - /// Called right after the Serializer deserializes this object - /// - public void OnAfterDeserialize(); -} diff --git a/Prowl.Runtime/Serializer/SerializationAttributes.cs b/Prowl.Runtime/Serializer/SerializationAttributes.cs deleted file mode 100644 index 52a1a7dca..000000000 --- a/Prowl.Runtime/Serializer/SerializationAttributes.cs +++ /dev/null @@ -1,26 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; - -namespace Prowl.Runtime; - -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] -public sealed class IgnoreOnNullAttribute : Attribute { } - -[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] -public class SerializeIgnoreAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] -public class SerializeFieldAttribute : Attribute -{ -} - -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] -public class FormerlySerializedAsAttribute : Attribute -{ - public string oldName { get; set; } - public FormerlySerializedAsAttribute(string name) => oldName = name; -} diff --git a/Prowl.Runtime/Serializer/SerializedProperty.Compound.cs b/Prowl.Runtime/Serializer/SerializedProperty.Compound.cs deleted file mode 100644 index 398962f67..000000000 --- a/Prowl.Runtime/Serializer/SerializedProperty.Compound.cs +++ /dev/null @@ -1,246 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Prowl.Runtime; - -public sealed partial class SerializedProperty -{ - public Dictionary Tags => (Value as Dictionary)!; - - public SerializedProperty this[string tagName] - { - get { return Get(tagName); } - set - { - if (TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot set tag on non-compound tag"); - else if (tagName == null) - throw new ArgumentNullException(nameof(tagName)); - else if (value == null) - throw new ArgumentNullException(nameof(value)); - Tags[tagName] = value; - value.Parent = this; - } - } - - /// Gets a collection containing all tag names in this CompoundTag. - public IEnumerable GetNames() => Tags.Keys; - - /// Gets a collection containing all tags in this CompoundTag. - public IEnumerable GetAllTags() => Tags.Values; - - public SerializedProperty? Get(string tagName) - { - if (TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot get tag from non-compound tag"); - else if (tagName == null) - throw new ArgumentNullException(nameof(tagName)); - return Tags.TryGetValue(tagName, out var result) ? result : null; - } - - public bool TryGet(string tagName, out SerializedProperty? result) - { - if (TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot get tag from non-compound tag"); - return tagName != null ? Tags.TryGetValue(tagName, out result) : throw new ArgumentNullException(nameof(tagName)); - } - - public bool Contains(string tagName) - { - if (TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot get tag from non-compound tag"); - return tagName != null ? Tags.ContainsKey(tagName) : throw new ArgumentNullException(nameof(tagName)); - } - - public void Add(string name, SerializedProperty newTag) - { - if (TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot get tag from non-compound tag"); - if (newTag == null) - throw new ArgumentNullException(nameof(newTag)); - else if (newTag == this) - throw new ArgumentException("Cannot add tag to self"); - Tags.Add(name, newTag); - newTag.Parent = this; - } - - public bool Remove(string name) - { - if (TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot get tag from non-compound tag"); - if (string.IsNullOrWhiteSpace(name)) - throw new ArgumentNullException(nameof(name)); - return Tags.Remove(name); - } - - public bool TryFind(string path, out SerializedProperty? tag) - { - tag = Find(path); - return tag != null; - } - - public SerializedProperty? Find(string path) - { - if (TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot get tag from non-compound tag"); - SerializedProperty currentTag = this; - while (true) - { - var i = path.IndexOf('/'); - var name = i < 0 ? path : path[..i]; - if (!currentTag.TryGet(name, out SerializedProperty? tag) || tag == null) - return null; - - if (i < 0) - return tag; - - if (tag.TagType != PropertyType.Compound) - return null; - - currentTag = tag; - path = path[(i + 1)..]; - } - } - - /// - /// Returns a new compound with all the tags/paths combined - /// If a tag is found with identical Path/Name, and values are the same its kept, otherwise its discarded - /// NOTE: Completely Untested - /// - public static SerializedProperty Merge(List allTags) - { - SerializedProperty result = NewCompound(); - if (allTags.Count == 0) return result; - - var referenceTag = allTags[0]; - if (referenceTag.TagType != PropertyType.Compound) return result; - - foreach (var nameVal in referenceTag.Tags) - { - SerializedProperty mergedTag = null; - - if (allTags.Skip(1).All(tag => - { - if (tag.TagType != PropertyType.Compound) - return false; - - if (!tag.TryGet(nameVal.Key, out SerializedProperty? nTag)) - return false; - - if (nTag.TagType != nameVal.Value.TagType) - return false; - - switch (nameVal.Value.TagType) - { - case PropertyType.Compound: - mergedTag = Merge(allTags.Select(t => t.Get(nameVal.Key)).ToList()); - return mergedTag != null; - case PropertyType.List: - mergedTag = Merge(allTags.Select(t => t.Get(nameVal.Key)).ToList()); - return mergedTag != null; - default: - if (nameVal.Value.Value?.Equals(nTag.Value) != false) - { - mergedTag = nameVal.Value; - return true; - } - return false; - } - })) - { - result.Add(nameVal.Key, mergedTag); - } - } - - return result; - } - - /// - /// Apply the given CompoundTag to this CompoundTag - /// All tags inside the given CompoundTag will be added to this CompoundTag or replaced if they already exist - /// All instances of this CompoundTag will remain the same just their values will be updated - /// NOTE: Completely Untested - /// - /// - public void Apply(SerializedProperty toApply) - { - if (TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot apply to a non-compound tag"); - if (toApply.TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot apply a non-compound tag"); - - foreach (var applyTag in toApply.Tags) - { - if (Tags.TryGetValue(applyTag.Key, out SerializedProperty? tag)) - { - if (tag.TagType == PropertyType.Compound) - { - if (applyTag.Value.TagType == PropertyType.Compound) - tag.Apply(applyTag.Value); - else - throw new InvalidOperationException("Cannot apply a non-compound tag to a compound tag"); - } - else - { - // Clone it so that Value isnt a reference - SerializedProperty cloned = applyTag.Value.Clone(); - tag.Value = cloned.Value; - } - } - else - { - // Add the new tag - Add(applyTag.Key, applyTag.Value); - } - } - } - - /// - /// Returns a new CompoundTag that contains all the tags from us who vary from the given CompoundTag - /// For example if we have an additional tag that the given CompoundTag does not have, it will be included in the result - /// Or if we have a tag with a different value, it will be included in the result - /// This will occur recursively for CompoundTags - /// NOTE: Completely Untested - /// - /// The Given CompoundTag To Compare Against - public SerializedProperty DifferenceFrom(SerializedProperty from) - { - if (TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot get the difference with a non-compound tag"); - if (from.TagType != PropertyType.Compound) - throw new InvalidOperationException("Cannot get the difference from a non-compound tag"); - - - SerializedProperty result = NewCompound(); - - foreach (var kvp in Tags) - { - if (!from.Tags.TryGetValue(kvp.Key, out SerializedProperty? value)) - { - // Tag exists in this tag but not in the 'from' tag - result.Add(kvp.Key, kvp.Value); - } - else if (kvp.Value.TagType == PropertyType.Compound && value.TagType == PropertyType.Compound) - { - // Recursively get the difference for compound tags - SerializedProperty subDifference = kvp.Value.DifferenceFrom(value); - if (subDifference.Tags.Count > 0) - { - result.Add(kvp.Key, subDifference); - } - } - else if (!kvp.Value.Value.Equals(value.Value)) - { - // Tag values are different - result.Add(kvp.Key, kvp.Value); - } - } - - return result; - - } -} diff --git a/Prowl.Runtime/Serializer/SerializedProperty.List.cs b/Prowl.Runtime/Serializer/SerializedProperty.List.cs deleted file mode 100644 index 4c429d2b0..000000000 --- a/Prowl.Runtime/Serializer/SerializedProperty.List.cs +++ /dev/null @@ -1,40 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System.Collections.Generic; - -namespace Prowl.Runtime; - -public sealed partial class SerializedProperty -{ - public List List => (Value as List)!; - - public SerializedProperty this[int tagIdx] - { - get { return Get(tagIdx); } - set { List[tagIdx] = value; } - } - - public SerializedProperty Get(int tagIdx) - { - if (TagType != PropertyType.List) - throw new System.InvalidOperationException("Cannot get tag from non-list tag"); - return List[tagIdx]; - } - - public void ListAdd(SerializedProperty tag) - { - if (TagType != PropertyType.List) - throw new System.InvalidOperationException("Cannot add tag to non-list tag"); - List.Add(tag); - tag.Parent = this; - } - - public void ListRemove(SerializedProperty tag) - { - if (TagType != PropertyType.List) - throw new System.InvalidOperationException("Cannot remove tag from non-list tag"); - List.Remove(tag); - tag.Parent = null; - } -} diff --git a/Prowl.Runtime/Serializer/SerializedProperty.cs b/Prowl.Runtime/Serializer/SerializedProperty.cs deleted file mode 100644 index e12295d40..000000000 --- a/Prowl.Runtime/Serializer/SerializedProperty.cs +++ /dev/null @@ -1,278 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; -using System.Collections.Generic; -using System.Globalization; - -namespace Prowl.Runtime; - -public enum PropertyType -{ - Null = 0, - Byte, - sByte, - Short, - Int, - Long, - UShort, - UInt, - ULong, - Float, - Double, - Decimal, - String, - ByteArray, - Bool, - List, - Compound, -} - -public class PropertyChangeEventArgs(SerializedProperty property, object? oldValue, object? newValue) : EventArgs -{ - public SerializedProperty Property { get; } = property; - public object? OldValue { get; } = oldValue; - public object? NewValue { get; } = newValue; -} - -public sealed partial class SerializedProperty -{ - public event EventHandler? PropertyChanged; - - private object? _value; - public object? Value { get { return _value; } private set { Set(value); } } - - public PropertyType TagType { get; private set; } - - public SerializedProperty? Parent { get; private set; } - - public SerializedProperty() { } - public SerializedProperty(byte i) { _value = i; TagType = PropertyType.Byte; } - public SerializedProperty(sbyte i) { _value = i; TagType = PropertyType.sByte; } - public SerializedProperty(short i) { _value = i; TagType = PropertyType.Short; } - public SerializedProperty(int i) { _value = i; TagType = PropertyType.Int; } - public SerializedProperty(long i) { _value = i; TagType = PropertyType.Long; } - public SerializedProperty(ushort i) { _value = i; TagType = PropertyType.UShort; } - public SerializedProperty(uint i) { _value = i; TagType = PropertyType.UInt; } - public SerializedProperty(ulong i) { _value = i; TagType = PropertyType.ULong; } - public SerializedProperty(float i) { _value = i; TagType = PropertyType.Float; } - public SerializedProperty(double i) { _value = i; TagType = PropertyType.Double; } - public SerializedProperty(decimal i) { _value = i; TagType = PropertyType.Decimal; } - public SerializedProperty(string i) { _value = i; TagType = PropertyType.String; } - public SerializedProperty(byte[] i) { _value = i; TagType = PropertyType.ByteArray; } - public SerializedProperty(bool i) { _value = i; TagType = PropertyType.Bool; } - public SerializedProperty(PropertyType type, object? value) - { - TagType = type; - if (type == PropertyType.List && value == null) - _value = new List(); - else if (type == PropertyType.Compound && value == null) - _value = new Dictionary(); - else - _value = value; - } - public SerializedProperty(List tags) - { - TagType = PropertyType.List; - _value = tags; - } - - public static SerializedProperty NewCompound() => new(PropertyType.Compound, new Dictionary()); - public static SerializedProperty NewList() => new(PropertyType.List, new List()); - - public void GetAllAssetRefs(ref HashSet refs) - { - if (TagType == PropertyType.List) - { - foreach (var tag in (List)Value!) - tag.GetAllAssetRefs(ref refs); - } - else if (TagType == PropertyType.Compound) - { - var dict = (Dictionary)Value!; - if (TryGet("$type", out var typeName)) - { - // This isnt a perfect solution since maybe theres a class named AssetRefCollection or something - // But this in combination with the "AssetID" tag and Guid.TryParse should be reliable enough while being fast - if (typeName!.StringValue.Contains("Prowl.Runtime.AssetRef") && TryGet("AssetID", out var assetId)) - { - // Is an AssetRef were cloning, Spit out - if (Guid.TryParse(assetId!.StringValue, out var id) && id != Guid.Empty) - refs.Add(id); - } - } - foreach (var (_, tag) in dict) - tag.GetAllAssetRefs(ref refs); - } - } - - public SerializedProperty Clone() - { - if (TagType == PropertyType.Null) return new(PropertyType.Null, null); - else if (TagType == PropertyType.List) - { - // Value is a List - var list = (List)Value!; - var newList = new List(list.Count); - foreach (var tag in list) - newList.Add(tag.Clone()); - } - else if (TagType == PropertyType.Compound) - { - // Value is a Dictionary - var dict = (Dictionary)Value!; - var newDict = new Dictionary(dict.Count); - foreach (var (key, tag) in dict) - newDict.Add(key, tag.Clone()); - } - return new(TagType, Value); - } - - private void OnPropertyChanged(PropertyChangeEventArgs e) - { - PropertyChanged?.Invoke(this, e); - Parent?.OnPropertyChanged(e); - } - - #region Shortcuts - - /// - /// Gets the number of tags in this tag. - /// Returns 0 for all tags except Compound and List. - /// - public int Count - { - get - { - if (TagType == PropertyType.Compound) return ((Dictionary)Value!).Count; - else if (TagType == PropertyType.List) return ((List)Value!).Count; - else return 0; - } - } - - /// - /// Returns true if tags of this type have a primitive value attached. - /// All tags except Compound and List have values. - /// - public bool IsPrimitive - { - get - { - return TagType switch - { - PropertyType.Compound => false, - PropertyType.List => false, - PropertyType.Null => false, - _ => true - }; - } - } - - /// - /// Utility to set the value of this tag with safety checks. - /// - public void Set(object value) - { - if (_value == value) return; - var old = _value; - _value = TagType switch - { - PropertyType.Byte => (byte)value, - PropertyType.sByte => (sbyte)value, - PropertyType.Short => (short)value, - PropertyType.Int => (int)value, - PropertyType.Long => (long)value, - PropertyType.UShort => (ushort)value, - PropertyType.UInt => (uint)value, - PropertyType.ULong => (ulong)value, - PropertyType.Float => (float)value, - PropertyType.Double => (double)value, - PropertyType.Decimal => (decimal)value, - PropertyType.String => (string)value, - PropertyType.ByteArray => (byte[])value, - PropertyType.Bool => (bool)value, - _ => throw new InvalidOperationException("Cannot set value of " + TagType.ToString()) - }; - - OnPropertyChanged(new PropertyChangeEventArgs(this, old, value)); - } - - /// Returns the value of this tag, cast as a bool. - /// When used on a tag other than BoolTag. - public bool BoolValue { get => (bool)Value; set => Set(value); } - - /// Returns the value of this tag, cast as a byte. - /// When used on a tag other than ByteTag. - public byte ByteValue { get => Convert.ToByte(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a sbyte. - /// When used on a tag other than sByteTag. - public sbyte sByteValue { get => Convert.ToSByte(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a short. - /// When used on a tag other than ShortTag. - public short ShortValue { get => Convert.ToInt16(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a int. - /// When used on a tag other than IntTag. - public int IntValue { get => Convert.ToInt32(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a long. - /// When used on a tag other than LongTag. - public long LongValue { get => Convert.ToInt64(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a ushort. - /// When used on a tag other than UShortTag. - public ushort UShortValue { get => Convert.ToUInt16(Value); set => Set(value); } - - /// Returns the value of this tag, cast as an uint. - /// When used on a tag other than UIntTag. - public uint UIntValue { get => Convert.ToUInt32(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a ulong. - /// When used on a tag other than ULongTag. - public ulong ULongValue { get => Convert.ToUInt64(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a float. - /// When used on a tag other than FloatTag. - public float FloatValue { get => Convert.ToSingle(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a double. - /// When used on a tag other than DoubleTag. - public double DoubleValue { get => Convert.ToDouble(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a decimal. - /// Only supported by DecimalTag. - /// When used on an unsupported tag. - public decimal DecimalValue { get => Convert.ToDecimal(Value); set => Set(value); } - - /// Returns the value of this tag, cast as a string. - /// Returns exact value for StringTag, and stringified (using InvariantCulture) value for ByteTag, DoubleTag, FloatTag, IntTag, LongTag, and ShortTag. - /// Not supported by CompoundTag, ListTag, ByteArrayTag, FloatArrayTag, or IntArrayTag. - /// When used on an unsupported tag. - public string StringValue - { - get - { - return TagType switch - { - PropertyType.String => (string)Value!, - PropertyType.Byte => ((byte)Value!).ToString(CultureInfo.InvariantCulture), - PropertyType.Double => ((double)Value!).ToString(CultureInfo.InvariantCulture), - PropertyType.Float => ((float)Value!).ToString(CultureInfo.InvariantCulture), - PropertyType.Int => ((int)Value!).ToString(CultureInfo.InvariantCulture), - PropertyType.Long => ((long)Value!).ToString(CultureInfo.InvariantCulture), - PropertyType.Short => ((short)Value!).ToString(CultureInfo.InvariantCulture), - _ => throw new InvalidCastException("Cannot get StringValue from " + TagType.ToString()) - }; - } - set => Set(value); - } - - /// Returns the value of this tag, cast as a byte array. - /// When used on a tag other than ByteArrayTag. - public byte[] ByteArrayValue { get => (byte[])Value; set => Set(value); } - - #endregion - -} diff --git a/Prowl.Runtime/Serializer/Serializer.cs b/Prowl.Runtime/Serializer/Serializer.cs deleted file mode 100644 index 2cd925a3e..000000000 --- a/Prowl.Runtime/Serializer/Serializer.cs +++ /dev/null @@ -1,148 +0,0 @@ -// This file is part of the Prowl Game Engine -// Licensed under the MIT License. See the LICENSE file in the project root for details. - -using System; -using System.Collections.Generic; -using System.Linq; - -using Prowl.Runtime.Serialization.Formatters; - -namespace Prowl.Runtime; -// Classes used to test serialization -//public class TestSerialize -//{ -// public object NullField = null; -// public Guid GuidField = Guid.NewGuid(); -// public byte ByteField = 123; -// public sbyte SByteField = -123; -// public short ShortField = 12345; -// public int IntField = 123456789; -// public long LongField = 1234567890123456789; -// public ushort UShortField = 12345; -// public uint UIntField = 123456789; -// public ulong ULongField = 1234567890123456789; -// public float FloatField = 123.456f; -// public double DoubleField = 123.456789; -// public decimal DecimalField = 123.456789m; -// public string StringField = "Hello World!"; -// public byte[] ByteArrayField = new byte[] { 1, 2, 3, 4, 5 }; -// public bool BoolField = true; -// public TestSimpleSerialize ObjectField = new(); -// public List ListField = new() { new(), new() }; -// public Dictionary DictionaryField = new() { { "1", new() }, { "2", new() } }; -// -//} -// -//public class TestSimpleSerialize -//{ -// public string StringField = "Hello World!"; -// public byte[] ByteArrayField = new byte[] { 1, 2, 3, 4, 5 }; -//} -public interface ISerializationFormat -{ - bool CanHandle(Type type); - SerializedProperty Serialize(object value, Serializer.SerializationContext context); - object? Deserialize(SerializedProperty value, Type targetType, Serializer.SerializationContext context); -} - -public static class Serializer -{ - public class SerializationContext - { - private class NullKey { } - - public Dictionary objectToId = new(ReferenceEqualityComparer.Instance); - public Dictionary idToObject = []; - public int nextId = 1; - private int dependencyCounter = 0; - public HashSet dependencies = []; - - public SerializationContext() - { - objectToId.Clear(); - objectToId.Add(new NullKey(), 0); - idToObject.Clear(); - idToObject.Add(0, new NullKey()); - nextId = 1; - dependencies.Clear(); - } - - public void AddDependency(Guid guid) - { - if (dependencyCounter > 0) - dependencies.Add(guid); - else throw new InvalidOperationException("Cannot add a dependency outside of a BeginDependencies/EndDependencies block."); - } - - public void BeginDependencies() - { - dependencyCounter++; - } - - public HashSet EndDependencies() - { - dependencyCounter--; - if (dependencyCounter == 0) - return dependencies; - return []; - } - } - - private static readonly List formats = []; - - static Serializer() - { - // Register built-in formats in order of precedence - formats.Add(new PrimitiveFormat()); - formats.Add(new NullableFormat()); - formats.Add(new DateTimeFormat()); - formats.Add(new GuidFormat()); - formats.Add(new EnumFormat()); - formats.Add(new HashSetFormat()); - formats.Add(new CollectionFormat()); - formats.Add(new DictionaryFormat()); - formats.Add(new AnyObjectFormat()); // Fallback format - must be last - } - - public static void RegisterFormat(ISerializationFormat format) - { - formats.Insert(0, format); // Add to start for precedence - Also ensures ObjectFormat is last - } - - public static SerializedProperty Serialize(object? value) => Serialize(value, new SerializationContext()); - - public static SerializedProperty Serialize(object? value, SerializationContext context) - { - if (value == null) return new SerializedProperty(PropertyType.Null, null); - - if (value is SerializedProperty property) - { - SerializedProperty clone = property.Clone(); - HashSet deps = []; - clone.GetAllAssetRefs(ref deps); - foreach (Guid dep in deps) - context.AddDependency(dep); - return clone; - } - - ISerializationFormat? format = formats.FirstOrDefault(f => f.CanHandle(value.GetType())) - ?? throw new NotSupportedException($"No format handler found for type {value.GetType()}"); - - return format.Serialize(value, context); - } - - public static T? Deserialize(SerializedProperty value) => (T?)Deserialize(value, typeof(T)); - public static object? Deserialize(SerializedProperty value, Type targetType) => Deserialize(value, targetType, new SerializationContext()); - public static T? Deserialize(SerializedProperty value, SerializationContext context) => (T?)Deserialize(value, typeof(T), context); - public static object? Deserialize(SerializedProperty value, Type targetType, SerializationContext context) - { - if (value == null || value.TagType == PropertyType.Null) return null; - - if (value.GetType() == targetType) return value; - - ISerializationFormat format = formats.FirstOrDefault(f => f.CanHandle(targetType)) - ?? throw new NotSupportedException($"No format handler found for type {targetType}"); - - return format.Deserialize(value, targetType, context); - } -} diff --git a/Prowl.Runtime/Utils/Boolean32Matrix.cs b/Prowl.Runtime/Utils/Boolean32Matrix.cs index f038a4cb5..de89898fe 100644 --- a/Prowl.Runtime/Utils/Boolean32Matrix.cs +++ b/Prowl.Runtime/Utils/Boolean32Matrix.cs @@ -8,6 +8,8 @@ using System.Text; using System.Threading.Tasks; +using Prowl.Echo; + namespace Prowl.Runtime.Utils; /// @@ -173,24 +175,24 @@ public override int GetHashCode() return hash.ToHashCode(); } - public SerializedProperty Serialize(Serializer.SerializationContext ctx) + public EchoObject Serialize(SerializationContext ctx) { - var value = SerializedProperty.NewCompound(); + var value = EchoObject.NewCompound(); - var columnsList = SerializedProperty.NewList(); + var columnsList = EchoObject.NewList(); for (int i = 0; i < 32; i++) { - columnsList.ListAdd(new SerializedProperty(rows[i])); + columnsList.ListAdd(new EchoObject(rows[i])); } value.Add("Columns", columnsList); return value; } - public void Deserialize(SerializedProperty value, Serializer.SerializationContext ctx) + public void Deserialize(EchoObject value, SerializationContext ctx) { rows = new uint[32]; - List columnsList = value.Get("Columns").List; + List columnsList = value.Get("Columns").List; for (int i = 0; i < 32; i++) { rows[i] = columnsList[i].UIntValue; diff --git a/Prowl.Runtime/Utils/NodeSystem/Node.cs b/Prowl.Runtime/Utils/NodeSystem/Node.cs index 0f67f9795..c32c6c1f6 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Node.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Node.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Reflection; +using Prowl.Echo; using Prowl.Runtime.Utils; using Prowl.Runtime.Utils.NodeSystem; diff --git a/Prowl.Runtime/Utils/NodeSystem/NodeDataCache.cs b/Prowl.Runtime/Utils/NodeSystem/NodeDataCache.cs index b5ffc5529..7630544ca 100644 --- a/Prowl.Runtime/Utils/NodeSystem/NodeDataCache.cs +++ b/Prowl.Runtime/Utils/NodeSystem/NodeDataCache.cs @@ -6,6 +6,7 @@ using System.Reflection; using Prowl.Runtime.NodeSystem; +using Prowl.Echo; namespace Prowl.Runtime.Utils.NodeSystem; diff --git a/Prowl.Runtime/Utils/NodeSystem/NodeGraph.cs b/Prowl.Runtime/Utils/NodeSystem/NodeGraph.cs index 10614b373..7198952bd 100644 --- a/Prowl.Runtime/Utils/NodeSystem/NodeGraph.cs +++ b/Prowl.Runtime/Utils/NodeSystem/NodeGraph.cs @@ -7,6 +7,7 @@ using System.Reflection; using Prowl.Runtime.Rendering; +using Prowl.Echo; namespace Prowl.Runtime.NodeSystem; @@ -109,7 +110,7 @@ public virtual Node GetNode(int instanceID) /// Creates a copy of the original node in the graph public virtual Node CopyNode(Node original) { - SerializedProperty nodeTag = Serializer.Serialize(original); + EchoObject nodeTag = Serializer.Serialize(original); Node node = Serializer.Deserialize(nodeTag); node.graph = this; node.position += new Vector2(30, 30); @@ -146,13 +147,13 @@ public virtual void Clear() /// Create a new deep copy of this graph public virtual NodeGraph Copy() { - SerializedProperty graphTag = Serializer.Serialize(this); + EchoObject graphTag = Serializer.Serialize(this); NodeGraph graph = Serializer.Deserialize(graphTag); // Instantiate all nodes inside the graph for (int i = 0; i < nodes.Count; i++) { if (nodes[i] == null) continue; - SerializedProperty nodeTag = Serializer.Serialize(nodes[i]); + EchoObject nodeTag = Serializer.Serialize(nodes[i]); Node node = Serializer.Deserialize(nodeTag); node.graph = graph; graph.nodes[i] = node; diff --git a/Prowl.Runtime/Utils/NodeSystem/NodePort.cs b/Prowl.Runtime/Utils/NodeSystem/NodePort.cs index 826c31484..6d6cbf43a 100644 --- a/Prowl.Runtime/Utils/NodeSystem/NodePort.cs +++ b/Prowl.Runtime/Utils/NodeSystem/NodePort.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Reflection; +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; [Serializable] diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/BranchNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/BranchNode.cs index e77565254..67026238b 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/BranchNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/BranchNode.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; [Node("Flow Control/Branch")] diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/ChanceNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/ChanceNode.cs index 16fcadfbb..afa1b339c 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/ChanceNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/ChanceNode.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; [Node("Flow Control/Chance")] diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/CooldownNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/CooldownNode.cs index 4f1c340e9..0d3882eac 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/CooldownNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/CooldownNode.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; [Node("Flow Control/Cooldown")] diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/DoOnceNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/DoOnceNode.cs index 654f4cbab..ddbceafe3 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/DoOnceNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/DoOnceNode.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; [Node("Flow Control/Do Once")] diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/FlipFlopNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/FlipFlopNode.cs index c8040e24a..20958c6ce 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/FlipFlopNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/FlipFlopNode.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; [Node("Flow Control/FlipFlop")] diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/FlowNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/FlowNode.cs index ce7499abb..e4ea6747d 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/FlowNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/FlowNode.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; public abstract class FlowNode : Node diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/ForLoopNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/ForLoopNode.cs index 9b08b57fa..8aedbd995 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/ForLoopNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/ForLoopNode.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; [Node("Flow Control/For Loop")] diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/TryCatchNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/TryCatchNode.cs index abdd7b469..83ddec546 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/TryCatchNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/TryCatchNode.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; [Node("Flow Control/TryCatch")] diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/WhileLoopNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/WhileLoopNode.cs index 29e392870..974fca315 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/WhileLoopNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/Flow Control/WhileLoopNode.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using Prowl.Echo; + namespace Prowl.Runtime.NodeSystem; [Node("Flow Control/While Loop")] diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/ReflectedNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/ReflectedNode.cs index 17216277c..59931d546 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/ReflectedNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/ReflectedNode.cs @@ -6,6 +6,7 @@ using System.Reflection; using Prowl.Runtime.NodeSystem; +using Prowl.Echo; namespace Prowl.Runtime.Utils.NodeSystem.Nodes; diff --git a/Prowl.Runtime/Utils/RuntimeUtils.cs b/Prowl.Runtime/Utils/RuntimeUtils.cs index 5ab312c1f..5781a224b 100644 --- a/Prowl.Runtime/Utils/RuntimeUtils.cs +++ b/Prowl.Runtime/Utils/RuntimeUtils.cs @@ -12,6 +12,7 @@ using System.Threading; using Prowl.Runtime.Utils; +using Prowl.Echo; namespace Prowl.Runtime; diff --git a/Prowl.Runtime/Utils/ScriptableSingleton.cs b/Prowl.Runtime/Utils/ScriptableSingleton.cs index 461f28998..b8a4d1c93 100644 --- a/Prowl.Runtime/Utils/ScriptableSingleton.cs +++ b/Prowl.Runtime/Utils/ScriptableSingleton.cs @@ -4,6 +4,9 @@ using System; using System.IO; +using Prowl.Echo; +using Prowl.Echo.FileFormats; + namespace Prowl.Runtime.Utils; [AttributeUsage(AttributeTargets.Class)] diff --git a/Prowl.Runtime/Utils/SerializedAsset.cs b/Prowl.Runtime/Utils/SerializedAsset.cs index da123160a..9f77adf0a 100644 --- a/Prowl.Runtime/Utils/SerializedAsset.cs +++ b/Prowl.Runtime/Utils/SerializedAsset.cs @@ -6,6 +6,7 @@ using System.IO; using Prowl.Runtime.SceneManagement; +using Prowl.Echo; namespace Prowl.Runtime.Utils; @@ -34,7 +35,7 @@ public void SaveToFile(FileInfo file, out HashSet? dependencies) if (Main == null) throw new Exception("Asset does not have a main object."); file.Directory?.Create(); // Ensure the Directory exists - Serializer.SerializationContext ctx = new(); + SerializationContext ctx = new(); var tag = Serializer.Serialize(this, ctx); dependencies = ctx.dependencies;