164 lines
7.6 KiB
C#
164 lines
7.6 KiB
C#
// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved.
|
|
// This code can only be used under the standard Unity Asset Store End User License Agreement
|
|
// A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
// ReSharper disable MemberCanBePrivate.Global
|
|
// ReSharper disable UnusedMember.Global
|
|
|
|
namespace Doozy.Runtime.Nody
|
|
{
|
|
/// <summary> Utility methods for the Nody system </summary>
|
|
public static class NodyUtils
|
|
{
|
|
/// <summary> Check if a port is connected to one of the ports of the given node </summary>
|
|
/// <param name="port"> Target port </param>
|
|
/// <param name="node"> Target node </param>
|
|
/// <returns> True if the given port (id) is found in the node's connections, false otherwise </returns>
|
|
public static bool IsPortConnectedToNode(FlowPort port, FlowNode node)
|
|
{
|
|
if (port == null) return false; //null port -> nope
|
|
if (node == null) return false; //null node -> nope
|
|
List<string> connections =
|
|
port.direction switch
|
|
{
|
|
|
|
PortDirection.Input => node.outputConnections,
|
|
PortDirection.Output => node.inputConnections,
|
|
_ => throw new ArgumentOutOfRangeException()
|
|
};
|
|
return connections.Contains(port.portId);
|
|
}
|
|
|
|
/// <summary> Check if two nodes have are connected </summary>
|
|
/// <param name="n1"> Node 1 </param>
|
|
/// <param name="n2"> Node 2 </param>
|
|
/// <returns> True if at least one port from n1 is connected to another port in n2, false otherwise </returns>
|
|
public static bool IsNodeConnectedToNode(FlowNode n1, FlowNode n2)
|
|
{
|
|
if (n1 == null) return false; //null node -> nope
|
|
if (n2 == null) return false; //null node -> nope
|
|
return
|
|
n1.ports.Any(port => IsPortConnectedToNode(port, n2)) ||
|
|
n2.ports.Any(port => IsPortConnectedToNode(port, n1));
|
|
}
|
|
|
|
/// <summary> Check if a connection can be established between two ports </summary>
|
|
/// <param name="p1"> Port 1 </param>
|
|
/// <param name="p2"> Port 2 </param>
|
|
/// <returns> True if the ports can connect, false otherwise </returns>
|
|
public static bool CanConnect(FlowPort p1, FlowPort p2)
|
|
{
|
|
if (p1 == null) return false; //port is null -> stop
|
|
if (p2 == null) return false; //port is null -> stop
|
|
if (p1 == p2) return false; //port cannot connect to itself -> stop
|
|
if (p1.IsConnectedToPort(p2.portId)) return false; //ports are already connected -> stop
|
|
if (p1.direction == p2.direction) return false; //ports have the same direction -> stop
|
|
if (p1.portId == p2.portId) return false; //ports have the same id -> stop (wtf moment)
|
|
if (p1.nodeId == p2.nodeId) return false; //ports belong to the same node -> stop
|
|
return true; //allow connection
|
|
}
|
|
|
|
/// <summary> Remove all connections for the given port </summary>
|
|
/// <param name="port"> Target port </param>
|
|
/// <param name="graph"> Parent graph </param>
|
|
/// <returns> True if the operation was successful, false otherwise </returns>
|
|
public static bool DisconnectPort(FlowPort port, FlowGraph graph)
|
|
{
|
|
if (port == null) return false; //null port -> cannot disconnect
|
|
if (graph == null) return false; //null graph -> cannot disconnect
|
|
List<FlowPort> ports =
|
|
port.direction switch
|
|
{
|
|
|
|
PortDirection.Input => graph.outputPorts,
|
|
PortDirection.Output => graph.inputPorts,
|
|
_ => throw new ArgumentOutOfRangeException()
|
|
};
|
|
|
|
ports.ForEach(p =>
|
|
{
|
|
p.RemoveConnection(port.portId);
|
|
FlowPort otherPort = graph.GetPortById(port.portId);
|
|
p.onDisconnected?.Invoke(otherPort);
|
|
otherPort.onDisconnected?.Invoke(p);
|
|
});
|
|
port.connections.Clear();
|
|
return true;
|
|
}
|
|
|
|
/// <summary> Disconnect the given ports </summary>
|
|
/// <param name="p1"> Port 1 </param>
|
|
/// <param name="p2"> Port 2 </param>
|
|
/// <returns> True if the operation was successful, false otherwise </returns>
|
|
public static bool DisconnectPortFromPort(FlowPort p1, FlowPort p2)
|
|
{
|
|
if (p1 == null) return false; //null port -> cannot disconnect
|
|
if (p2 == null) return false; //null port -> cannot disconnect
|
|
if (!p1.IsConnectedToPort(p2.portId)) return false; //not connected -> cannot disconnect
|
|
p1.RemoveConnection(p2.portId);
|
|
p1.onDisconnected?.Invoke(p2);
|
|
p2.RemoveConnection(p1.portId);
|
|
p2.onDisconnected?.Invoke(p1);
|
|
return true;
|
|
}
|
|
|
|
/// <summary> Remove all connections from the target port to the given node </summary>
|
|
/// <param name="port"> Target port </param>
|
|
/// <param name="node"> Target node </param>
|
|
/// <returns> True if the operation was successful, false otherwise </returns>
|
|
public static bool DisconnectPortFromNode(FlowPort port, FlowNode node)
|
|
{
|
|
if (port == null) return false; //null port -> cannot disconnect
|
|
if (node == null) return false; //null node -> cannot disconnect
|
|
List<FlowPort> ports =
|
|
port.direction switch
|
|
{
|
|
|
|
PortDirection.Input => node.outputPorts,
|
|
PortDirection.Output => node.inputPorts,
|
|
_ => throw new ArgumentOutOfRangeException()
|
|
};
|
|
ports.ForEach(nodePort =>
|
|
{
|
|
nodePort.RemoveConnection(port.portId);
|
|
nodePort.onDisconnected?.Invoke(port);
|
|
port.RemoveConnection(nodePort.portId);
|
|
port.onDisconnected?.Invoke(nodePort);
|
|
});
|
|
return true;
|
|
}
|
|
|
|
/// <summary> Remove all connections from the given node </summary>
|
|
/// <param name="node"> Target node </param>
|
|
/// <param name="graph"> Parent graph </param>
|
|
/// <returns> True if the operation was successful, false otherwise </returns>
|
|
public static bool DisconnectNode(FlowNode node, FlowGraph graph)
|
|
{
|
|
if (node == null) return false; //null node -> cannot disconnect
|
|
if (graph == null) return false; //null graph -> cannot disconnect
|
|
node.ports.ForEach(port =>
|
|
{
|
|
DisconnectPort(port, graph);
|
|
});
|
|
return true;
|
|
}
|
|
|
|
/// <summary> Remove all connections between the two nodes </summary>
|
|
/// <param name="n1"> Node 1 </param>
|
|
/// <param name="n2"> Node 2</param>
|
|
/// <returns> True if the operation was successful, false otherwise </returns>
|
|
public static bool DisconnectNodeFromNode(FlowNode n1, FlowNode n2)
|
|
{
|
|
if (n1 == null) return false; //null node -> cannot disconnect
|
|
if (n2 == null) return false; //null node -> cannot disconnect
|
|
n1.ports.ForEach(port => DisconnectPortFromNode(port, n2));
|
|
n2.ports.ForEach(port => DisconnectPortFromNode(port, n1));
|
|
return true;
|
|
}
|
|
|
|
}
|
|
}
|