From e35981d24627f5ca9e34fc9d990d3c7c60bf79c6 Mon Sep 17 00:00:00 2001 From: "JSD\\13999" <1399945104@qq.com> Date: Mon, 18 May 2026 14:18:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Unity=20=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=92=8C=E6=B5=8B=E8=AF=95=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E9=9B=86=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/ReactivePropertyJsonConverter.cs | 36 +++++++- .../Runtime/FlowScope.Runtime.asmdef | 4 +- ...nMenuPanel.prefab.meta => MainMenuP0.meta} | 5 +- .../MainMenuP0/Prefabs/MainMenuPanel.prefab | 14 --- .../MainMenuP0/Scripts/GameBootstrap.cs | 37 +++++++- .../EditMode/Data/DataSerializationTests.cs | 7 +- .../EditMode/FlowScope.Tests.EditMode.asmdef | 22 +++++ .../FlowScope.Tests.EditMode.asmdef.meta | 7 ++ .../PlayMode/FlowScope.Tests.PlayMode.asmdef | 20 ++++ .../FlowScope.Tests.PlayMode.asmdef.meta | 7 ++ My project/Packages/manifest.json | 13 ++- My project/Packages/packages-lock.json | 91 +++++++++++++++++++ .../PackageManagerSettings.asset | 14 ++- 13 files changed, 247 insertions(+), 30 deletions(-) rename My project/Assets/FlowScope/Samples/{MainMenuP0/Prefabs/MainMenuPanel.prefab.meta => MainMenuP0.meta} (55%) delete mode 100644 My project/Assets/FlowScope/Samples/MainMenuP0/Prefabs/MainMenuPanel.prefab create mode 100644 My project/Assets/FlowScope/Tests/EditMode/FlowScope.Tests.EditMode.asmdef create mode 100644 My project/Assets/FlowScope/Tests/EditMode/FlowScope.Tests.EditMode.asmdef.meta create mode 100644 My project/Assets/FlowScope/Tests/PlayMode/FlowScope.Tests.PlayMode.asmdef create mode 100644 My project/Assets/FlowScope/Tests/PlayMode/FlowScope.Tests.PlayMode.asmdef.meta diff --git a/My project/Assets/FlowScope/Runtime/Data/ReactivePropertyJsonConverter.cs b/My project/Assets/FlowScope/Runtime/Data/ReactivePropertyJsonConverter.cs index 6dd07d5..1fa94dc 100644 --- a/My project/Assets/FlowScope/Runtime/Data/ReactivePropertyJsonConverter.cs +++ b/My project/Assets/FlowScope/Runtime/Data/ReactivePropertyJsonConverter.cs @@ -197,7 +197,7 @@ namespace FlowScope.Data return; } - if (IsReactiveCollection(memberType)) + if (IsReactiveCollection(memberType) || IsMutableCollection(memberType, currentValue)) { PopulateCollection(currentValue, memberType, value, fieldName); return; @@ -216,7 +216,7 @@ namespace FlowScope.Data throw TypeMismatch(fieldName, collectionType, value); } - var itemType = collectionType.GetGenericArguments()[0]; + var itemType = GetCollectionItemType(collectionType); collectionType.GetMethod("Clear", Type.EmptyTypes)?.Invoke(collection, Array.Empty()); var addMethod = collectionType.GetMethod("Add", new[] { itemType }); if (addMethod == null) @@ -330,6 +330,38 @@ namespace FlowScope.Data return type.IsGenericType && type.GetGenericTypeDefinition().FullName == "R3.ReactiveCollection`1"; } + private static bool IsMutableCollection(Type type, object value) + { + return value != null && + type != typeof(string) && + GetCollectionItemType(type) != null && + type.GetMethod("Clear", Type.EmptyTypes) != null; + } + + private static Type GetCollectionItemType(Type type) + { + if (type.IsArray) + { + return type.GetElementType(); + } + + if (type.IsGenericType && type.GetGenericArguments().Length == 1) + { + return type.GetGenericArguments()[0]; + } + + foreach (var interfaceType in type.GetInterfaces()) + { + if (interfaceType.IsGenericType && + interfaceType.GetGenericTypeDefinition() == typeof(ICollection<>)) + { + return interfaceType.GetGenericArguments()[0]; + } + } + + return null; + } + private static bool IsSimple(Type type) { type = Nullable.GetUnderlyingType(type) ?? type; diff --git a/My project/Assets/FlowScope/Runtime/FlowScope.Runtime.asmdef b/My project/Assets/FlowScope/Runtime/FlowScope.Runtime.asmdef index c6285f2..81e459a 100644 --- a/My project/Assets/FlowScope/Runtime/FlowScope.Runtime.asmdef +++ b/My project/Assets/FlowScope/Runtime/FlowScope.Runtime.asmdef @@ -1,7 +1,9 @@ { "name": "FlowScope.Runtime", "rootNamespace": "FlowScope", - "references": [], + "references": [ + "R3" + ], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false, diff --git a/My project/Assets/FlowScope/Samples/MainMenuP0/Prefabs/MainMenuPanel.prefab.meta b/My project/Assets/FlowScope/Samples/MainMenuP0.meta similarity index 55% rename from My project/Assets/FlowScope/Samples/MainMenuP0/Prefabs/MainMenuPanel.prefab.meta rename to My project/Assets/FlowScope/Samples/MainMenuP0.meta index 645d056..b306f6d 100644 --- a/My project/Assets/FlowScope/Samples/MainMenuP0/Prefabs/MainMenuPanel.prefab.meta +++ b/My project/Assets/FlowScope/Samples/MainMenuP0.meta @@ -1,5 +1,6 @@ -fileFormatVersion: 2 -guid: 9841d62cd2d24cb48e23ac11adaaf5a9 +fileFormatVersion: 2 +guid: 5e5172994f0edc6468e55a5e1e742064 +folderAsset: yes DefaultImporter: externalObjects: {} userData: diff --git a/My project/Assets/FlowScope/Samples/MainMenuP0/Prefabs/MainMenuPanel.prefab b/My project/Assets/FlowScope/Samples/MainMenuP0/Prefabs/MainMenuPanel.prefab deleted file mode 100644 index 974f46a..0000000 --- a/My project/Assets/FlowScope/Samples/MainMenuP0/Prefabs/MainMenuPanel.prefab +++ /dev/null @@ -1,14 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1 &100000 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: [] - m_Layer: 0 - m_Name: MainMenuPanel - m_TagString: Untagged - m_IsActive: 1 diff --git a/My project/Assets/FlowScope/Samples/MainMenuP0/Scripts/GameBootstrap.cs b/My project/Assets/FlowScope/Samples/MainMenuP0/Scripts/GameBootstrap.cs index 7c130b7..32526a6 100644 --- a/My project/Assets/FlowScope/Samples/MainMenuP0/Scripts/GameBootstrap.cs +++ b/My project/Assets/FlowScope/Samples/MainMenuP0/Scripts/GameBootstrap.cs @@ -9,6 +9,7 @@ using FlowScope.Resources; using FlowScope.Save; using FlowScope.UI; using UnityEngine; +using UnityEngine.UI; using ContainerType = FlowScope.Container.Container; namespace FlowScope.Samples.MainMenuP0 @@ -39,10 +40,9 @@ namespace FlowScope.Samples.MainMenuP0 _gameFlow = new GameFlow(); var resources = new SampleResourceService(); - if (mainMenuPanelPrefab != null) - { - resources.Register("FlowScope/Samples/MainMenuP0/MainMenuPanel", mainMenuPanelPrefab.gameObject); - } + resources.Register( + "FlowScope/Samples/MainMenuP0/MainMenuPanel", + ResolveMainMenuPanelPrefab().gameObject); _saveService = new SaveService( new FileSaveStorage(), @@ -108,6 +108,35 @@ namespace FlowScope.Samples.MainMenuP0 return hudCanvas; } + private MainMenuPanel ResolveMainMenuPanelPrefab() + { + if (mainMenuPanelPrefab != null) + { + return mainMenuPanelPrefab; + } + + var panelObject = new GameObject("MainMenuPanel Template"); + panelObject.transform.SetParent(transform, false); + panelObject.SetActive(false); + + var panel = panelObject.AddComponent(); + + var goldObject = new GameObject("GoldText"); + goldObject.transform.SetParent(panelObject.transform, false); + var goldText = goldObject.AddComponent(); + goldText.text = defaultGold.ToString(); + goldText.alignment = TextAnchor.MiddleCenter; + + var buttonObject = new GameObject("IncrementGoldButton"); + buttonObject.transform.SetParent(panelObject.transform, false); + buttonObject.AddComponent(); + var button = buttonObject.AddComponent