using System;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
using XNode;
namespace Stary.Evo.StoryEditor
{
[Serializable,CreateNodeMenu("")]
public class NodeBase : Node
{
[Serializable] public class Enter { }
[Serializable] public class Exit { }
///
/// 默认节点位置间隔(x轴)
///
public const float DefaultNodeXInterval = 250;
///
/// 默认节点位置间隔(y轴)
///
public const float DefaultNodeYInterval = 0;
///
/// 创建新的节点
///
/// 所在的块
/// 节点名称
/// 节点位置
public static T Create(NodeGraph graph, string name = null, Vector2 position = default) where T : NodeBase
{
// 创建节点
var node = graph.AddNode();
if (node == null)
{
Debug.LogError("节点创建失败");
return null;
}
#if UNITY_EDITOR
// 将节点落盘
UnityEditor.AssetDatabase.AddObjectToAsset(node, graph);
UnityEditor.EditorUtility.SetDirty(graph);
#endif
// 设置节点变量
node.position = position;
node.name = name ?? $"{name}_para_sample";
// 初始化节点
node.Init();
return node;
}
///
/// 移除自身
///
public void DestroySelf()
{
// 清理连接
ClearConnections();
// 移除与Graph之间的联系
if (graph)
{
graph.nodes.Remove(this);
#if UNITY_EDITOR
UnityEditor.AssetDatabase.RemoveObjectFromAsset(this);
#endif
}
// 销毁自身
DestroyImmediate(this);
}
public UniTask Export()
{
NodeData nodeData = new();
nodeData.name = name;
return UniTask.FromResult(nodeData);
}
#region 工具方法
///
/// 将端口A的连接传递给端口B
///
/// 端口A
/// 端口B
/// 移除端口A的连接
public static void GiveConnectionToOtherPort(NodePort portA, NodePort portB, bool deleteA = false)
{
// 排除端口A与端口B重合的情况
if (portA == portB)
return;
// 获取当前Enter端口的所有连接
var enterPorts = portA.GetConnections();
enterPorts.ForEach(port =>
{
// 将Enter端口与该端口断开
if (deleteA)
port.Disconnect(portA);
// 将指定的端口与该端口连接
port.Connect(portB);
});
}
///
/// 对所有之后的节点执行动作
///
/// 指定动作
public void DoActionToAllNodesAfter(Action action)
{
// 所有出口端口
Ports.Where(p => p.IsOutput).ToList().ForEach(port =>
{
// 所有出口端口连接的所有端口
port.GetConnections().ForEach(otherSide =>
{
// 所有出口端口连接的所有端口的是NodeBase的节点
if (otherSide.node is NodeBase baseNode)
{
action?.Invoke(this, baseNode);
baseNode.DoActionToAllNodesAfter(action);
}
});
});
}
#endregion
}
}