Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / ui / UiNode.cs
@小李xl 小李xl on 22 Aug 2023 3 KB 完成保存与未保存状态

using Godot;

/// <summary>
/// Ui节点父类
/// </summary>
/// <typeparam name="TUi">所属Ui面板类型</typeparam>
/// <typeparam name="TNodeType">Godot中的节点类型</typeparam>
/// <typeparam name="TCloneType">克隆该对象返回的类型</typeparam>
public abstract class UiNode<TUi, TNodeType, TCloneType>
    : IUiNode, IUiCellNode, IClone<TCloneType>
    where TUi : UiBase
    where TNodeType : Node
    where TCloneType : IUiCellNode
{
    /// <summary>
    /// 当前Ui节点所属的Ui面板对象
    /// </summary>
    public TUi UiPanel { get; }
    /// <summary>
    /// Godot节点实例
    /// </summary>
    public TNodeType Instance { get; }
    /// <summary>
    /// 克隆当前对象, 并返回新的对象,
    /// 注意: 如果子节点改名或者移动层级, 那么有可能对导致属性中的子节点无法访问
    /// </summary>
    public abstract TCloneType Clone();

    public UiNode(TUi uiPanel, TNodeType node)
    {
        UiPanel = uiPanel;
        Instance = node;
        if (node is IUiNodeScript uiNodeScript)
        {
            uiPanel.RecordUiNodeScript(uiNodeScript);
            uiNodeScript.SetUiNode(this);
        }
    }
    
    //已知问题: 通过 OpenNestedUi() 打开子Ui, 然后再克隆当前节点, 被克隆出来的节点的子Ui不会被调用生命周期函数, 也就是没有被记录
    public UiBase OpenNestedUi(string uiName, UiBase prevUi = null)
    {
        var packedScene = ResourceManager.Load<PackedScene>("res://" + GameConfig.UiPrefabDir + uiName + ".tscn");
        var uiBase = packedScene.Instantiate<UiBase>();
        uiBase.PrevUi = prevUi;
        Instance.AddChild(uiBase);
        UiPanel.RecordNestedUi(uiBase, this, UiManager.RecordType.Open);
        
        uiBase.OnCreateUi();
        uiBase.OnInitNestedUi();
        if (UiPanel.IsOpen)
        {
            uiBase.ShowUi();
        }
        
        return uiBase;
    }

    public T OpenNestedUi<T>(string uiName, UiBase prevUi = null) where T : UiBase
    {
        return (T)OpenNestedUi(uiName, prevUi);
    }

    /// <summary>
    /// 克隆当前节点, 并放到同父节点下
    /// </summary>
    public TCloneType CloneAndPut()
    {
        var inst = Clone();
        Instance.GetParent().AddChild(inst.GetUiInstance());
        return inst;
    }

    public UiBase GetUiPanel()
    {
        return UiPanel;
    }

    public Node GetUiInstance()
    {
        return Instance;
    }

    public IUiCellNode CloneUiCell()
    {
        return Clone();
    }

    public void AddChild(IUiNode uiNode)
    {
        Instance.AddChild(uiNode.GetUiInstance());
    }

    public void AddChild(Node node)
    {
        Instance.AddChild(node);
    }
    
    public void RemoveChild(IUiNode uiNode)
    {
        Instance.RemoveChild(uiNode.GetUiInstance());
    }
    
    public void RemoveChild(Node node)
    {
        Instance.RemoveChild(node);
    }

    public void QueueFree()
    {
        Instance.QueueFree();
    }

    public void Reparent(IUiNode uiNode)
    {
        Instance.Reparent(uiNode.GetUiInstance());
    }
    
    public void Reparent(Node node)
    {
        Instance.Reparent(node);
    }

    public Node GetParent()
    {
        return Instance.GetParent();
    }
}