diff --git a/scripts/inventory/Packsack.cs b/scripts/inventory/Packsack.cs index 8c48f65..e8c9740 100644 --- a/scripts/inventory/Packsack.cs +++ b/scripts/inventory/Packsack.cs @@ -11,8 +11,7 @@ namespace ColdMint.scripts.inventory; /// public partial class Packsack : PickAbleTemplate { - private PackedScene? _packedScene; - private PacksackUi? _packsackUi; + private const string Path = "res://prefab/ui/packsackUI.tscn"; [Export] public int NumberSlots { get; set; } /// @@ -31,36 +30,14 @@ public partial class Packsack : PickAbleTemplate public override void Use(Node2D? owner, Vector2 targetGlobalPosition) { - if (_packedScene == null) + GameSceneDepend.DynamicUiGroup?.ShowControl(Path, control => { - return; - } - - if (_packsackUi == null) - { - _packsackUi = NodeUtils.InstantiatePackedScene(_packedScene); - if (_packsackUi != null) + if (control is PacksackUi packsackUi) { - var containerNode = NodeUtils.FindContainerNode(_packsackUi, this); - if (containerNode is UiGroup uiGroup) - { - uiGroup.RegisterControl(_packsackUi); - } - else - { - NodeUtils.CallDeferredAddChild(containerNode, _packsackUi); - } - - _packsackUi.Title = Name; - _packsackUi.ItemContainer = ItemContainer; - _packsackUi.Hide(); + packsackUi.Title = Name; + packsackUi.ItemContainer = ItemContainer; } - } - - if (_packsackUi != null) - { - GameSceneDepend.DynamicUiGroup?.ShowControl(_packsackUi); - } + }); } public IItemContainer? ItemContainer { get; private set; } @@ -84,6 +61,10 @@ public partial class Packsack : PickAbleTemplate itemSlotNode.Hide(); } - _packedScene = GD.Load("res://prefab/ui/packsackUI.tscn"); + GameSceneDepend.DynamicUiGroup?.RegisterControl(Path, () => + { + var packedScene = GD.Load(Path); + return NodeUtils.InstantiatePackedScene(packedScene); + }); } } \ No newline at end of file diff --git a/scripts/utils/UiGroup.cs b/scripts/utils/UiGroup.cs index 6bd7d1a..192568a 100644 --- a/scripts/utils/UiGroup.cs +++ b/scripts/utils/UiGroup.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Godot; @@ -10,24 +11,60 @@ namespace ColdMint.scripts.utils; public partial class UiGroup : Control { private readonly HashSet _visibleControls = []; - private readonly HashSet _allControls = []; + private readonly Dictionary> _controlFunc = new(); /// - /// How many nodes are visible - /// 有多少个节点处于可见状态 + /// Holds the node that has been instantiated + /// 持有已实例化的节点 /// - public int VisibleControlsCount => _visibleControls.Count; + private readonly Dictionary _instantiatedControl = new(); /// - /// Register nodes in the UI group. For registered nodes, do not use or to change the visible state. Call the and methods instead. - /// 注册节点到UI组内,对于已注册的节点,不要直接使用方法来改变可见状态,请调用方法来替代他们。 + /// Registered control node + /// 注册控制节点 /// - /// - public void RegisterControl(Control control) + /// + ///key + ///控制节点的key + /// + /// + ///Creates a function to control the node. UiGroup delays calling this function to create the node. + ///创建控制节点的函数,UiGroup会延迟调用这个函数创建节点。 + /// + public void RegisterControl(string key, Func func) { - control.TreeExited += () => { OnTreeExited(control); }; + _controlFunc.TryAdd(key, func); + } + + + /// + /// Obtain or create a controller node + /// 获取或者创建控制节点 + /// + /// + /// + private Control? GetOrCreateControl(string key) + { + if (_instantiatedControl.TryGetValue(key, out var instantiatedControl)) + { + return instantiatedControl; + } + + if (!_controlFunc.TryGetValue(key, out var func)) + { + return null; + } + + var control = func.Invoke(); + if (control == null) + { + return null; + } + control.Hide(); + control.TreeExited += () => { OnTreeExited(key, control); }; NodeUtils.CallDeferredAddChild(this, control); - _allControls.Add(control); + _instantiatedControl.Add(key, control); + return control; } /// @@ -50,6 +87,22 @@ public partial class UiGroup : Control Hide(); } + /// + /// Hide a node + /// 隐藏某个节点 + /// + /// + /// + public bool HideControl(string key) + { + if (!_instantiatedControl.TryGetValue(key, out var control)) + { + return false; + } + + return HideControl(control); + } + /// /// Hide a node /// 隐藏某个节点 @@ -63,11 +116,6 @@ public partial class UiGroup : Control return false; } - if (!_allControls.Contains(control)) - { - return false; - } - control.Hide(); _visibleControls.Remove(control); ChangeSelfVisibility(); @@ -78,18 +126,28 @@ public partial class UiGroup : Control /// Show node /// 显示某个节点 /// - /// + /// + /// + ///A callback function before the display node where you can generate rendered page content. For example, set the title + ///在显示节点之前的回调函数,您可以在此函数内生成渲染页面内容。例如:设置标题 + /// /// - public bool ShowControl(Control control) + public bool ShowControl(string key, Action? beforeDisplayControl = null) { + var control = GetOrCreateControl(key); + if (control == null) + { + return false; + } + if (control.IsVisible()) { return false; } - if (!_allControls.Contains(control)) + if (beforeDisplayControl != null) { - return false; + beforeDisplayControl.Invoke(control); } control.Show(); @@ -114,11 +172,11 @@ public partial class UiGroup : Control } } - private void OnTreeExited(Control control) + private void OnTreeExited(string key, Control control) { //The Hide method is not called when a node exits from the tree, so remove the node here to prevent empty references. //当节点从节点树内退出时,并不会调用Hide方法,所以在这里移除节点,防止产生空引用。 _visibleControls.Remove(control); - _allControls.Remove(control); + _instantiatedControl.Remove(key); } } \ No newline at end of file