您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
201 行
4.6 KiB
201 行
4.6 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using System;
|
|
|
|
namespace GraphProcessor
|
|
{
|
|
[System.Serializable]
|
|
public class BaseGraph : ScriptableObject, ISerializationCallbackReceiver
|
|
{
|
|
static readonly int maxComputeOrderDepth = 1000;
|
|
|
|
//JSon datas contaning all elements of the graph
|
|
[SerializeField]
|
|
public List< JsonElement > serializedNodes = new List< JsonElement >();
|
|
|
|
[System.NonSerialized]
|
|
public List< BaseNode > nodes = new List< BaseNode >();
|
|
[System.NonSerialized]
|
|
public Dictionary< string, BaseNode > nodesPerGUID = new Dictionary< string, BaseNode >();
|
|
|
|
[SerializeField]
|
|
public List< SerializableEdge > edges = new List< SerializableEdge >();
|
|
[System.NonSerialized]
|
|
public Dictionary< string, SerializableEdge > edgesPerGUID = new Dictionary< string, SerializableEdge >();
|
|
|
|
[SerializeField]
|
|
public List< CommentBlock > commentBlocks = new List< CommentBlock >();
|
|
|
|
[SerializeField]
|
|
public List< PinnedElement > pinnedWindows = new List< PinnedElement >();
|
|
|
|
[System.NonSerialized]
|
|
Dictionary< BaseNode, int > computeOrderDictionary = new Dictionary< BaseNode, int >();
|
|
|
|
//graph visual properties
|
|
public Vector3 position = Vector3.zero;
|
|
public Vector3 scale = Vector3.one;
|
|
|
|
void OnEnable()
|
|
{
|
|
DestroyBrokenGraphElements();
|
|
UpdateComputeOrder();
|
|
}
|
|
|
|
public void AddNode(BaseNode node)
|
|
{
|
|
nodes.Add(node);
|
|
}
|
|
|
|
public void RemoveNode(BaseNode node)
|
|
{
|
|
nodes.Remove(node);
|
|
}
|
|
|
|
public SerializableEdge Connect(BaseNode inputNode, string inputFieldName, BaseNode outputNode, string outputFieldName)
|
|
{
|
|
var edge = SerializableEdge.CreateNewEdge(this, inputNode, inputFieldName, outputNode, outputFieldName);
|
|
|
|
edges.Add(edge);
|
|
|
|
return edge;
|
|
}
|
|
|
|
public void Disconnect(BaseNode inputNode, string inputFieldName, BaseNode outputNode, string outputFieldName)
|
|
{
|
|
edges.RemoveAll(r => r.inputNode == inputNode
|
|
&& r.outputNode == outputNode
|
|
&& r.outputFieldName == outputFieldName
|
|
&& r.inputFieldName == inputFieldName
|
|
);
|
|
}
|
|
|
|
public void Disconnect(string edgeGUID)
|
|
{
|
|
edges.RemoveAll(r => r.GUID == edgeGUID);
|
|
}
|
|
|
|
public void AddCommentBlock(CommentBlock block)
|
|
{
|
|
commentBlocks.Add(block);
|
|
}
|
|
|
|
public void RemoveCommentBlock(CommentBlock block)
|
|
{
|
|
commentBlocks.Remove(block);
|
|
}
|
|
|
|
public PinnedElement OpenPinned(Type viewType)
|
|
{
|
|
var pinned = pinnedWindows.Find(p => p.editorType.type == viewType);
|
|
|
|
if (pinned == null)
|
|
{
|
|
pinned = new PinnedElement(viewType);
|
|
pinnedWindows.Add(pinned);
|
|
}
|
|
else
|
|
pinned.opened = true;
|
|
|
|
return pinned;
|
|
}
|
|
|
|
public void ClosePinned(Type viewType)
|
|
{
|
|
var pinned = pinnedWindows.Find(p => p.editorType.type == viewType);
|
|
|
|
pinned.opened = false;
|
|
}
|
|
|
|
public void OnBeforeSerialize()
|
|
{
|
|
serializedNodes.Clear();
|
|
|
|
foreach (var node in nodes)
|
|
serializedNodes.Add(JsonSerializer.Serialize(node));
|
|
}
|
|
|
|
public void OnAfterDeserialize()
|
|
{
|
|
nodes.Clear();
|
|
|
|
foreach (var serializedNode in serializedNodes)
|
|
{
|
|
var node = JsonSerializer.DeserializeNode(serializedNode) as BaseNode;
|
|
nodes.Add(node);
|
|
nodesPerGUID[node.GUID] = node;
|
|
}
|
|
|
|
foreach (var edge in edges)
|
|
{
|
|
edge.Deserialize();
|
|
edgesPerGUID[edge.GUID] = edge;
|
|
}
|
|
}
|
|
|
|
public void UpdateComputeOrder()
|
|
{
|
|
if (nodes.Count == 0)
|
|
return ;
|
|
|
|
computeOrderDictionary.Clear();
|
|
|
|
foreach (var node in nodes)
|
|
UpdateComputeOrder(0, node);
|
|
}
|
|
|
|
int UpdateComputeOrder(int depth, BaseNode node)
|
|
{
|
|
int computeOrder = 0;
|
|
|
|
if (depth > maxComputeOrderDepth)
|
|
{
|
|
Debug.LogError("Recursion error while updating compute order");
|
|
return -1;
|
|
}
|
|
|
|
if (computeOrderDictionary.ContainsKey(node))
|
|
return node.computeOrder;
|
|
|
|
if (!node.canProcess)
|
|
{
|
|
node.computeOrder = -1;
|
|
computeOrderDictionary[node] = -1;
|
|
return -1;
|
|
}
|
|
|
|
foreach (var dep in node.GetInputNodes())
|
|
{
|
|
int c = UpdateComputeOrder(depth + 1, dep);
|
|
|
|
if (c == -1)
|
|
{
|
|
computeOrder = -1;
|
|
break ;
|
|
}
|
|
|
|
computeOrder += c;
|
|
}
|
|
|
|
if (computeOrder != -1)
|
|
computeOrder++;
|
|
|
|
node.computeOrder = computeOrder;
|
|
computeOrderDictionary[node] = computeOrder;
|
|
|
|
return computeOrder;
|
|
}
|
|
|
|
void DestroyBrokenGraphElements()
|
|
{
|
|
edges.RemoveAll(e => e.inputNode == null
|
|
|| e.outputNode == null
|
|
|| string.IsNullOrEmpty(e.outputFieldName)
|
|
|| string.IsNullOrEmpty(e.inputFieldName)
|
|
);
|
|
nodes.RemoveAll(n => n == null);
|
|
}
|
|
}
|
|
}
|