refactor: add some comments to help to understand runtime graph

main
taoria 3 years ago
parent e8947b7df4
commit 2676079c24
  1. 90
      TNode/TNodeCore/Runtime/Components/RuntimeGraph.cs

@ -7,22 +7,53 @@ using UnityEngine;
namespace TNodeCore.Components{
public class RuntimeGraph:MonoBehaviour{
/// <summary>
/// Graph data reference to be used in runtime
/// </summary>
public GraphData graphData;
/// <summary>
/// Runtime copy of scene node data to hold references to scene objects
/// </summary>
public List<SceneNodeData> sceneNodes;
/// <summary>
/// Map of node id to runtime node
/// </summary>
public readonly Dictionary<string, RuntimeNode> RuntimeNodes = new Dictionary<string, RuntimeNode>();
///<summary>
/// The graph tool the current runtime graph is using
/// </summary>
private GraphTool _graphTool;
/// <summary>
/// Inner graph tool to help with graph operations
/// </summary>
private class GraphTool{
/// <summary>
/// Topological order of the graph nodes
/// </summary>
[NonSerialized]
public readonly List<RuntimeNode> TopologicalOrder = new List<RuntimeNode>();
/// <summary>
/// Entry nodes of the graph. These are the nodes that has no input.
/// </summary>
public readonly List<RuntimeNode> EntryNodes = new List<RuntimeNode>();
/// <summary>
/// Cached data for Dependency traversal.
/// </summary>
public readonly Dictionary<string, object> OutputCached = new Dictionary<string, object>();
/// <summary>
/// Ssed to detect if the graph tool is caching the output data of the node
/// </summary>
private bool _isCachingOutput = false;
/// <summary>
/// elements are read only ,do not modify them
/// </summary>
public readonly Dictionary<string, RuntimeNode> RuntimeNodes;
//Traverse and process all nodes in a topological order,dependency of the node is already resolved.if you want to run specific node,you can use RunNodeDependently instead
public void DirectlyTraversal(){
foreach (var node in TopologicalOrder){
var links = node.InputLink;
@ -32,7 +63,12 @@ namespace TNodeCore.Components{
node.NodeData.Process();
}
}
//Cache outport info in the graph tool so that we can directly access it in the traversal
/// <summary>
/// Cache out port data in the graph tool so that we can directly access the output.
/// The two function assume there will be no change happens in scene nodes or blackboard referenced data during the running,so in a dependency traversal for some
/// batch of nodes.the nodes could directly access the output data in the graph tool instead of waiting dependency traversal resolve the result of the output.
/// </summary>
public void StartCachingPort(){
_isCachingOutput = true;
}
@ -40,11 +76,17 @@ namespace TNodeCore.Components{
_isCachingOutput = false;
OutputCached.Clear();
}
public void ResolveDependency(RuntimeNode runtimeNode,int dependencyLevel=0){
/// <summary>
/// Resolve dependencies by a deep first search,the depended nodes will be processed to satisfy the need of the the given runtime node
/// Note it's a recursive function.if you want directly traverse all nodes with dependency resolved ,use DirectlyTraversal() instead.
/// </summary>
/// <param name="runtimeNode">The node you want to resolve dependency</param>
/// <param name="dependencyLevel">search depth,no need provide a number when use outside</param>
public void RunNodeDependently(RuntimeNode runtimeNode,int dependencyLevel=0){
var links = runtimeNode.InputLink;
foreach (var link in links){
var outputNode = RuntimeNodes[link.outPort.nodeDataId];
ResolveDependency(outputNode,dependencyLevel+1);
RunNodeDependently(outputNode,dependencyLevel+1);
HandlingLink(link);
}
@ -61,9 +103,14 @@ namespace TNodeCore.Components{
}
/// <summary>
/// Max depth of dependency traversal,in case of some special situation. the dependency level bigger than this number will be considered as a loop.
/// </summary>
private const int DependencyLevelMax = 1145;
/// <summary>
/// Handling a node link to transfer data from it's output side to the input side
/// </summary>
/// <param name="nodeLink">Link you want to process</param>
public void HandlingLink(NodeLink nodeLink){
//out node is node output data
//in node is node receive data
@ -80,6 +127,12 @@ namespace TNodeCore.Components{
}
inNode.SetInput(nodeLink.inPort.portEntryName, outValue);
}
/// <summary>
/// Constructor of the graph tool,it will traverse the graph and build the topological order of the graph.
/// </summary>
/// <param name="list">List of nodes you need to traversal to build graph tool</param>
/// <param name="graphNodes">Map stores the mapping of node data id to runtime node</param>
public GraphTool(List<RuntimeNode> list, Dictionary<string, RuntimeNode> graphNodes){
RuntimeNodes = graphNodes;
if (list == null) return;
@ -117,10 +170,20 @@ namespace TNodeCore.Components{
}
/// <summary>
/// Holding the reference of the blackboard ,but it will be override by the runtime graph
/// </summary>
[SerializeReference]
public BlackboardData runtimeBlackboardData;
/// <summary>
/// Check if the runtime graph is build .a built graph has a graph tool set up
/// </summary>
[NonSerialized]
private bool _build = false;
/// <summary>
/// Build the graph tool and other dependencies for the runtime graph
/// </summary>
public void Build(){
var link = graphData.NodeLinks;
@ -139,6 +202,11 @@ namespace TNodeCore.Components{
_build = true;
}
/// <summary>
/// Cast the node data to a runtime node
/// </summary>
/// <param name="nodeData">Node data you provided</param>
/// <returns></returns>
public RuntimeNode Get(NodeData nodeData){
if(!_build)
Build();
@ -147,20 +215,24 @@ namespace TNodeCore.Components{
}
return null;
}
/// <summary>
/// Get the runtime node from an id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public RuntimeNode Get(string id){
if (RuntimeNodes.ContainsKey(id)){
return RuntimeNodes[id];
}
return null;
}
//DFS search for resolving dependency
//DFS search to run a node.
public bool RunOnDependency(NodeData startNode){
if(!_build)
Build();
if (_graphTool == null)
return false;
_graphTool.ResolveDependency(Get(startNode));
_graphTool.RunNodeDependently(Get(startNode));
return true;
}
public bool ResolveDependency(){

Loading…
Cancel
Save