From 2676079c24b5d2001ba6ec3c044b265c24915a84 Mon Sep 17 00:00:00 2001
From: taoria <445625470@qq.com>
Date: Wed, 27 Jul 2022 14:21:19 +0800
Subject: [PATCH] refactor: add some comments to help to understand runtime
graph
---
.../Runtime/Components/RuntimeGraph.cs | 90 +++++++++++++++++--
1 file changed, 81 insertions(+), 9 deletions(-)
diff --git a/TNode/TNodeCore/Runtime/Components/RuntimeGraph.cs b/TNode/TNodeCore/Runtime/Components/RuntimeGraph.cs
index 2ac7881..f890154 100644
--- a/TNode/TNodeCore/Runtime/Components/RuntimeGraph.cs
+++ b/TNode/TNodeCore/Runtime/Components/RuntimeGraph.cs
@@ -7,22 +7,53 @@ using UnityEngine;
namespace TNodeCore.Components{
public class RuntimeGraph:MonoBehaviour{
+ ///
+ /// Graph data reference to be used in runtime
+ ///
public GraphData graphData;
+ ///
+ /// Runtime copy of scene node data to hold references to scene objects
+ ///
public List sceneNodes;
+
+ ///
+ /// Map of node id to runtime node
+ ///
public readonly Dictionary RuntimeNodes = new Dictionary();
+ ///
+ /// The graph tool the current runtime graph is using
+ ///
private GraphTool _graphTool;
-
+ ///
+ /// Inner graph tool to help with graph operations
+ ///
private class GraphTool{
+
+ ///
+ /// Topological order of the graph nodes
+ ///
[NonSerialized]
public readonly List TopologicalOrder = new List();
+
+ ///
+ /// Entry nodes of the graph. These are the nodes that has no input.
+ ///
public readonly List EntryNodes = new List();
+ ///
+ /// Cached data for Dependency traversal.
+ ///
public readonly Dictionary OutputCached = new Dictionary();
+
+ ///
+ /// Ssed to detect if the graph tool is caching the output data of the node
+ ///
private bool _isCachingOutput = false;
///
/// elements are read only ,do not modify them
///
public readonly Dictionary 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
+
+ ///
+ /// 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.
+ ///
public void StartCachingPort(){
_isCachingOutput = true;
}
@@ -40,11 +76,17 @@ namespace TNodeCore.Components{
_isCachingOutput = false;
OutputCached.Clear();
}
- public void ResolveDependency(RuntimeNode runtimeNode,int dependencyLevel=0){
+ ///
+ /// 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.
+ ///
+ /// The node you want to resolve dependency
+ /// search depth,no need provide a number when use outside
+ 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{
}
-
+ ///
+ /// Max depth of dependency traversal,in case of some special situation. the dependency level bigger than this number will be considered as a loop.
+ ///
private const int DependencyLevelMax = 1145;
-
+ ///
+ /// Handling a node link to transfer data from it's output side to the input side
+ ///
+ /// Link you want to process
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);
}
+ ///
+ /// Constructor of the graph tool,it will traverse the graph and build the topological order of the graph.
+ ///
+ /// List of nodes you need to traversal to build graph tool
+ /// Map stores the mapping of node data id to runtime node
+
public GraphTool(List list, Dictionary graphNodes){
RuntimeNodes = graphNodes;
if (list == null) return;
@@ -117,10 +170,20 @@ namespace TNodeCore.Components{
}
+ ///
+ /// Holding the reference of the blackboard ,but it will be override by the runtime graph
+ ///
[SerializeReference]
public BlackboardData runtimeBlackboardData;
+ ///
+ /// Check if the runtime graph is build .a built graph has a graph tool set up
+ ///
[NonSerialized]
private bool _build = false;
+
+ ///
+ /// Build the graph tool and other dependencies for the runtime graph
+ ///
public void Build(){
var link = graphData.NodeLinks;
@@ -139,6 +202,11 @@ namespace TNodeCore.Components{
_build = true;
}
+ ///
+ /// Cast the node data to a runtime node
+ ///
+ /// Node data you provided
+ ///
public RuntimeNode Get(NodeData nodeData){
if(!_build)
Build();
@@ -147,20 +215,24 @@ namespace TNodeCore.Components{
}
return null;
}
-
+ ///
+ /// Get the runtime node from an id
+ ///
+ ///
+ ///
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(){