Merge pull request #20 from taoria/working-in-process

Working in process
main
taoria 3 years ago committed by GitHub
commit a4db66c3a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      Resources.meta
  2. 162
      Resources/Newtonsoft.Json-for-Unity.Converters.asset
  3. 8
      Resources/Newtonsoft.Json-for-Unity.Converters.asset.meta
  4. 8
      Sample.meta
  5. 8
      Sample/MathGraph.meta
  6. 8
      Sample/MathGraph/Editor.meta
  7. 22
      Sample/MathGraph/Editor/MathEditor.cs
  8. 14
      Sample/MathGraph/Editor/MathEditor.cs.meta
  9. 9
      Sample/MathGraph/Editor/MathGraphView.cs
  10. 11
      Sample/MathGraph/Editor/MathGraphView.cs.meta
  11. 15
      Sample/MathGraph/Editor/NodeAttribute Editor Config.asset
  12. 8
      Sample/MathGraph/Editor/NodeAttribute Editor Config.asset.meta
  13. 10
      Sample/MathGraph/MathGraph.cs
  14. 11
      Sample/MathGraph/MathGraph.cs.meta
  15. 23
      Sample/MathGraph/New MathGraph.asset
  16. 8
      Sample/MathGraph/New MathGraph.asset.meta
  17. 10
      Sample/TestExposedReference.cs
  18. 3
      Sample/TestExposedReference.cs.meta
  19. 6
      TNodeCore/Attribute/RuntimeNodeAttribute.cs
  20. 3
      TNodeCore/Attribute/RuntimeNodeAttribute.cs.meta
  21. 8
      TNodeCore/Editor/IGraphEditor.cs
  22. 3
      TNodeCore/Editor/IGraphEditor.cs.meta
  23. 3
      TNodeCore/Editor/NodeGraphView/IBaseDataGraphView.cs
  24. 9
      TNodeCore/Editor/Resources/GraphViewBackground.uss
  25. 76
      TNodeCore/Editor/Serialization/NodeDataWrapper.cs
  26. 5
      TNodeCore/Models/BlackboardData.cs
  27. 12
      TNodeCore/Models/NodeData.cs
  28. 2
      TNodeCore/Models/NodeLink.cs
  29. 139
      TNodeCore/Runtime/RuntimeGraph.cs
  30. 39
      TNodeCore/Runtime/RuntimeNode.cs
  31. 69
      TNodeCore/RuntimeCache/RuntimeCache.cs
  32. 3
      TNodeGraphViewImpl/Editor/Cache/NodeEditorExtensions.cs
  33. 7
      TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs
  34. 7
      TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardPropertyField.cs
  35. 70
      TNodeGraphViewImpl/Editor/GraphEditor.cs
  36. 14
      TNodeGraphViewImpl/Editor/Inspector/NodeInspectorInNode.cs
  37. 119
      TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
  38. 1
      TNodeGraphViewImpl/Editor/Search/BlackboardSearchWindowProvider.cs

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 630fb8569cca3804a80f2fb55f7890f2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -1,162 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ce56e4dbb13e1644aa983b6dd170e4a7, type: 3}
m_Name: Newtonsoft.Json-for-Unity.Converters
m_EditorClassIdentifier:
useUnityContractResolver: 1
useAllOutsideConverters: 0
outsideConverters:
- enabled: 0
converterName: TNode.JsonSerialize.NodeDataConverter
settings: []
- enabled: 0
converterName: TNode.JsonSerialize.UnityObjectConverter
settings: []
- enabled: 0
converterName: TNode.JsonSerialize.Vector3Converter
settings: []
useAllUnityConverters: 1
unityConverters:
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.AI.NavMesh.NavMeshQueryFilterConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.AI.NavMesh.NavMeshTriangulationConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Camera.CullingGroupEventConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.BoundsConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.BoundsIntConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.PlaneConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.RectConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.RectIntConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Geometry.RectOffsetConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Hashing.Hash128Converter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Color32Converter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.ColorConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Matrix4x4Converter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.QuaternionConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.SphericalHarmonicsL2Converter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector2Converter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector2IntConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector3Converter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector3IntConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Math.Vector4Converter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.NativeArray.NativeArrayConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics.JointDriveConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics.JointLimitsConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics.SoftJointLimitConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics2D.ColliderDistance2DConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Physics2D.ContactFilter2DConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Random.RandomStateConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Scripting.LayerMaskConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.UnityConverters.Scripting.RangeIntConverter
settings: []
useAllJsonNetConverters: 1
jsonNetConverters:
- enabled: 1
converterName: Newtonsoft.Json.Converters.StringEnumConverter
settings: []
- enabled: 1
converterName: Newtonsoft.Json.Converters.VersionConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.BinaryConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.BsonObjectIdConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.DataSetConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.DataTableConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.DiscriminatedUnionConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.EntityKeyMemberConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.ExpandoObjectConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.IsoDateTimeConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.JavaScriptDateTimeConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.KeyValuePairConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.RegexConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.UnixDateTimeConverter
settings: []
- enabled: 0
converterName: Newtonsoft.Json.Converters.XmlNodeConverter
settings: []

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 466d3febdbd656c4f9728b1116b1564f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 18f38c39496afae47ab40fb512c3ce7c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 23ebabfc8f40d2c4689dc4ec9a5786d5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 73ee98eea19fa9b42b9c7990a8161d56
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -1,22 +0,0 @@
using TNode.Editor;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;
using System;
public class MathEditor : GraphEditor<MathGraph>{
[OnOpenAsset]
public static bool OnOpenAsset(int instanceID, int line){
var graph = EditorUtility.InstanceIDToObject(instanceID) as MathGraph;
if (graph != null)
{
var wnd = GetWindow<MathEditor>();
wnd.titleContent = new GUIContent("MathGraph Editor");
wnd.CreateGUI();
wnd.GraphView.Data = graph;
return true;
}
return false;
}
}

@ -1,14 +0,0 @@
fileFormatVersion: 2
guid: c9041cb574597424fa4124edc3f99af1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- m_ViewDataDictionary: {instanceID: 0}
- mVisualTreeAsset: {fileID: 9197481963319205126, guid: b67f6dcbe2361b649ad2b7845207321b, type: 3}
- graphEditorData: {fileID: 11400000, guid: f582a62cc8e00144f97b4dff1f9ba8cc, type: 2}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

@ -1,9 +0,0 @@
using TNodeCore.Attribute;
using TNodeGraphViewImpl.Editor.NodeGraphView;
[ViewComponent]
public class MathGraphView : BaseDataGraphView<MathGraph>{
}

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7f4d84b648626d24eb29bfeb81c85e3f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

@ -1,15 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 99ad0af56b40495cb6bd6165e652266c, type: 3}
m_Name: NodeAttribute Editor Config
m_EditorClassIdentifier:
nodesData: []

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: f582a62cc8e00144f97b4dff1f9ba8cc
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

@ -1,10 +0,0 @@
using UnityEngine;
using UnityEditor;
using System;
using TNodeCore.Models;
[CreateAssetMenu(fileName = "New MathGraph", menuName = "TNode/MathGraph")]
[Serializable]
public class MathGraph : GraphData{
}

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 73baeb2c71a23da4ca06e3e3e52d5a78
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

@ -1,23 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 73baeb2c71a23da4ca06e3e3e52d5a78, type: 3}
m_Name: New MathGraph
m_EditorClassIdentifier:
nodes: []
nodeLinks: []
entryNode:
rid: -2
references:
version: 2
RefIds:
- rid: -2
type: {class: , ns: , asm: }

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 4b23c513fb78ea44b8a11a0bf7c8479e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

@ -1,10 +0,0 @@
using UnityEngine;
namespace Sample{
// Create at Asset/Test
[CreateAssetMenu(fileName = "NewData", menuName = "Test/Data", order = 1)]
public class TestExposedReference:ScriptableObject{
public ExposedReference<Camera> camera;
public ExposedReference<GameObject> go;
}
}

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: fed858872d394fb8896d48178f8a7d78
timeCreated: 1657862979

@ -0,0 +1,6 @@
using JetBrains.Annotations;
using TNodeCore.Models;
namespace TNodeCore.Attribute{
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e489ca10c5734869be9bce6e1a18297e
timeCreated: 1657952959

@ -0,0 +1,8 @@
using TNodeCore.Editor.NodeGraphView;
namespace TNodeCore.Editor{
public interface IGraphEditor{
public void SetGraphView(IBaseDataGraphView graphView);
public IBaseDataGraphView GetGraphView();
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d84e826fe49d4314b8cc1241faf38fd9
timeCreated: 1657944822

@ -10,6 +10,9 @@ namespace TNodeCore.Editor.NodeGraphView{
public GraphData GetGraphData(); public GraphData GetGraphData();
public BlackboardData GetBlackboardData(); public BlackboardData GetBlackboardData();
public bool IsRuntimeGraph{ get; set; }
public void SetGraphData(GraphData graph);
} }
} }

@ -4,3 +4,12 @@ GridBackground{
--thick-line-color: rgba(211, 211, 211, 0.2); --thick-line-color: rgba(211, 211, 211, 0.2);
--spacing:50; --spacing:50;
} }
#HintLabel{
position: absolute;
left: 45%;
top: 45%;
font-size: 14;
}

@ -4,46 +4,46 @@ using TNodeCore.Models;
using UnityEngine; using UnityEngine;
namespace TNodeCore.Editor.Serialization{ namespace TNodeCore.Editor.Serialization{
[Obsolete]
public class NodeDataWrapper<T> : ScriptableObject where T : NodeData{
public T Data;
private static readonly Dictionary<T,NodeDataWrapper<T>> Cache = new ();
public event Action<NodeDataWrapper<T>> OnValueChanged;
public static NodeDataWrapper<T> Get(T data){
if(Cache.ContainsKey(data)){
return Cache[data];
}
var wrapper = ScriptableObject.CreateInstance<NodeDataWrapper<T>>();
Cache.Add(data,wrapper);
return wrapper;
}
public NodeDataWrapper(T data){
this.Data = data;
}
public void SetValue(string path, object value){ // public class NodeDataWrapper<T> : ScriptableObject where T : NodeData{
var fieldInfo = Data.GetType().GetField(path); // public T Data;
fieldInfo.SetValue(Data,value); // private static readonly Dictionary<T,NodeDataWrapper<T>> Cache = new ();
OnValueChanged?.Invoke(this); // public event Action<NodeDataWrapper<T>> OnValueChanged;
} // public static NodeDataWrapper<T> Get(T data){
// if(Cache.ContainsKey(data)){
public object GetValue(string path){ // return Cache[data];
var fieldInfo = Data.GetType().GetField(path); // }
return fieldInfo.GetValue(Data); // var wrapper = ScriptableObject.CreateInstance<NodeDataWrapper<T>>();
} // Cache.Add(data,wrapper);
public static implicit operator T(NodeDataWrapper<T> wrapper){ // return wrapper;
if (wrapper == null) // }
return null; // public NodeDataWrapper(T data){
return wrapper.Data; // this.Data = data;
// }
} //
public static implicit operator NodeDataWrapper<T>(T unWrapper){ // public void SetValue(string path, object value){
if (unWrapper == null) // var fieldInfo = Data.GetType().GetField(path);
return null; // fieldInfo.SetValue(Data,value);
return Get(unWrapper); // OnValueChanged?.Invoke(this);
} // }
} //
// public object GetValue(string path){
// var fieldInfo = Data.GetType().GetField(path);
// return fieldInfo.GetValue(Data);
// }
// public static implicit operator T(NodeDataWrapper<T> wrapper){
// if (wrapper == null)
// return null;
// return wrapper.Data;
//
// }
// public static implicit operator NodeDataWrapper<T>(T unWrapper){
// if (unWrapper == null)
// return null;
// return Get(unWrapper);
// }
// }
public class NodeDataWrapper:DataWrapper<NodeDataWrapper,NodeData>{ public class NodeDataWrapper:DataWrapper<NodeDataWrapper,NodeData>{
} }

@ -6,6 +6,9 @@ namespace TNodeCore.Models{
/// </summary> /// </summary>
[Serializable] [Serializable]
public class BlackboardData:IModel{ public class BlackboardData:IModel,ICloneable{
public object Clone(){
return this.MemberwiseClone();
}
} }
} }

@ -1,5 +1,6 @@
using System; using System;
using TNodeCore.Attribute; using TNodeCore.Attribute;
using UnityEngine;
namespace TNodeCore.Models{ namespace TNodeCore.Models{
/// <summary> /// <summary>
@ -22,12 +23,15 @@ namespace TNodeCore.Models{
public bool entryPoint; public bool entryPoint;
public virtual void OnProcess(){ public virtual void Process(){
} }
// #if UNITY_EDITOR #if UNITY_EDITOR
// public Rect rect; [HideInInspector] public bool isTest;
// #endif public virtual void OnTest(){
}
#endif
} }
} }

@ -7,9 +7,11 @@ namespace TNodeCore.Models{
// public DialogueNodePortData From{ get; } // public DialogueNodePortData From{ get; }
public PortInfo inPort; public PortInfo inPort;
public PortInfo outPort; public PortInfo outPort;
public NodeLink(PortInfo inPort, PortInfo outPort){ public NodeLink(PortInfo inPort, PortInfo outPort){
this.inPort = inPort; this.inPort = inPort;
this.outPort = outPort; this.outPort = outPort;
} }
} }
} }

@ -1,19 +1,152 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq;
using TNodeCore.Models; using TNodeCore.Models;
using UnityEngine; using UnityEngine;
namespace TNodeCore.Runtime{ namespace TNodeCore.Runtime{
public class RuntimeGraph:MonoBehaviour{ public class RuntimeGraph:MonoBehaviour{
public GraphData graphData; public GraphData graphData;
public SortedSet<RuntimeNode> _sortedSet;
public readonly Dictionary<string, RuntimeNode> RuntimeNodes = new Dictionary<string, RuntimeNode>();
private GraphTool _graphTool;
private class GraphTool{
[NonSerialized]
public readonly List<RuntimeNode> TopologicalOrder = new List<RuntimeNode>();
public readonly List<RuntimeNode> EntryNodes = new List<RuntimeNode>();
public readonly Dictionary<string, RuntimeNode> RuntimeNodes;
public void DependencyTraversal(RuntimeNode runtimeNode){
var links = runtimeNode.InputLink;
foreach (var link in links){
var outputNode = RuntimeNodes[link.outPort.nodeDataId];
DependencyTraversal(outputNode);
HandlingLink(link);
}
runtimeNode.NodeData.Process();
}
public void HandlingLink(NodeLink nodeLink){
var inNode = RuntimeNodes[nodeLink.inPort.nodeDataId];
var outNode = RuntimeNodes[nodeLink.outPort.nodeDataId];
//out node is node output data
//in node is node receive data
var outValue = outNode.GetOutput(nodeLink.outPort.portName);
inNode.SetInput(nodeLink.inPort.portName, outValue);
}
public GraphTool(List<RuntimeNode> list, Dictionary<string, RuntimeNode> graphNodes){
RuntimeNodes = graphNodes;
if (list == null) return;
Queue<RuntimeNode> queue = new Queue<RuntimeNode>();
Dictionary<string,int> inDegreeCounterForTopologicalSort = new Dictionary<string, int>();
foreach (var runtimeNode in list){
var id = runtimeNode.NodeData.id;
if (!inDegreeCounterForTopologicalSort.ContainsKey(id)){
inDegreeCounterForTopologicalSort.Add(id,runtimeNode.InputLink.Count);
}
if (inDegreeCounterForTopologicalSort[id] == 0){
queue.Enqueue(runtimeNode);
EntryNodes.Add(runtimeNode);
}
}
//Topological sort
while (queue.Count > 0){
var node = queue.Dequeue();
TopologicalOrder.Add(node);
foreach (var outputLink in node.OutputLink){
inDegreeCounterForTopologicalSort[outputLink.inPort.nodeDataId]--;
if (inDegreeCounterForTopologicalSort[outputLink.inPort.nodeDataId] == 0){
queue.Enqueue(RuntimeNodes[outputLink.inPort.nodeDataId]);
}
}
}
if(TopologicalOrder.Count!= list.Count){
throw new Exception("Topological sort failed,circular dependency detected");
}
RuntimeNodes.Clear();
inDegreeCounterForTopologicalSort.Clear();
queue.Clear();
}
}
[SerializeReference] [SerializeReference]
public BlackboardData runtimeBlackboardData; public BlackboardData runtimeBlackboardData;
private bool _build = false;
public void Build(){
var link = graphData.NodeLinks;
//iterate links and create runtime nodes
foreach (var linkData in link){
ModifyOrCreateInNode(linkData);
ModifyOrCreateOutNode(linkData);
}
var nodeList = RuntimeNodes.Values;
_graphTool = new GraphTool(nodeList.ToList(),RuntimeNodes);
_build = true;
}
public RuntimeNode Get(NodeData nodeData){
if(!_build)
Build();
if(RuntimeNodes.ContainsKey(nodeData.id)){
return RuntimeNodes[nodeData.id];
}
return null;
}
public RuntimeNode Get(string id){
if (RuntimeNodes.ContainsKey(id)){
return RuntimeNodes[id];
}
return null;
}
//DFS search for resolving dependency
public void StartDependencyTraversal(NodeData startNode,NodeData currentNode,int level=0){
if (!_build)
Build();
if(_graphTool==null)
return;
_graphTool.DependencyTraversal(Get(startNode));
var inputNodesId = Get(currentNode).GetInputNodesId();
foreach (var s in inputNodesId){
var runtimeNode = Get(s);
}
}
private void ModifyOrCreateInNode(NodeLink linkData){
var inNodeId = linkData.inPort.nodeDataId;
var inNode = graphData.NodeDictionary[inNodeId];
if (!RuntimeNodes.ContainsKey(inNode.id)){
var runtimeInNode = new RuntimeNode(inNode);
RuntimeNodes.Add(inNode.id,runtimeInNode);
}
RuntimeNodes[inNode.id].InputLink.Add(linkData);
}
private void ModifyOrCreateOutNode(NodeLink linkData){
var outNodeId = linkData.outPort.nodeDataId;
var outNode = graphData.NodeDictionary[outNodeId];
if(!RuntimeNodes.ContainsKey(outNode.id)){
var runtimeOutNode = new RuntimeNode(outNode);
RuntimeNodes.Add(outNode.id,runtimeOutNode);
}
RuntimeNodes[outNode.id].OutputLink.Add(linkData);
}
public void OnValidate(){ public void OnValidate(){
if(runtimeBlackboardData==null||runtimeBlackboardData.GetType()==typeof(BlackboardData)){ if(runtimeBlackboardData==null||runtimeBlackboardData.GetType()==typeof(BlackboardData)){
runtimeBlackboardData = graphData?.blackboardData; if (graphData != null)
runtimeBlackboardData = graphData.blackboardData.Clone() as BlackboardData;
} }
} }
} }
public enum ProcessingStrategy{ public enum ProcessingStrategy{

@ -1,12 +1,39 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using Codice.Client.Common.TreeGrouper;
using TNodeCore.Models; using TNodeCore.Models;
using TNodeCore.RuntimeCache;
namespace TNodeCore.Runtime{ namespace TNodeCore.Runtime{
public abstract class RuntimeNode{ public class RuntimeNode{
public NodeData NodeData; public NodeData NodeData { get; set; }
public List<NodeLink> NodeLinks; //the link connect to node's in port
public void ProcessThisNode(){ public List<NodeLink> InputLink;
NodeData.OnProcess(); //the link connect to node's out port
public List<NodeLink> OutputLink;
public Type type;
public void SetInput(string portName,object value){
NodeData.SetValue(portName, value);
} }
public object GetOutput(string portName){
return NodeData.GetValue(portName);
}
public RuntimeNode(NodeData nodeData){
NodeData = nodeData;
//Caching the type of the node
type = nodeData.GetType();
}
public List<string> GetInputNodesId(){
List<string> dependencies = new List<string>();
foreach (NodeLink link in InputLink)
{
dependencies.Add(link.outPort.nodeDataId);
}
return dependencies;
}
} }
} }

@ -50,6 +50,11 @@ namespace TNodeCore.RuntimeCache{
AddBlackboardDataTypeToCache(type,attribute); AddBlackboardDataTypeToCache(type,attribute);
RegisterRuntimeBlackboard(type); RegisterRuntimeBlackboard(type);
} }
//Check if the type is a node data type
if(typeof(NodeData).IsAssignableFrom(type)){
//if it is, add it to the cache
RegisterRuntimeNodeData(type);
}
} }
@ -101,6 +106,41 @@ namespace TNodeCore.RuntimeCache{
} }
} }
public void RegisterRuntimeNodeData(Type type){
if (type == null) return;
if(!CachedDelegatesForGettingValue.ContainsKey(type)){
CachedDelegatesForGettingValue.Add(type, new Dictionary<string, GetValueDelegate>());
CachedDelegatesForSettingValue.Add(type,new Dictionary<string, SetValueDelegate>());
var properties = type.GetProperties();
foreach(var property in properties){
//if the property only has a setter ,skip
if(property.SetMethod != null){
var setValueDelegate = SetValueDelegateForProperty(property);
CachedDelegatesForSettingValue[type].Add(property.Name,setValueDelegate);
}
if(property.GetMethod != null){
var getValueDelegate = GetValueDelegateForProperty(property);
CachedDelegatesForGettingValue[type].Add(property.Name,getValueDelegate);
}
}
//register the fields
var fields = type.GetFields();
foreach(var field in fields){
var getValueDelegate = GetValueDelegateForField(field);
CachedDelegatesForGettingValue[type].Add(field.Name,getValueDelegate);
if (field.IsPublic){
var setValueDelegate = SetValueDelegateForField(field);
CachedDelegatesForSettingValue[type].Add(field.Name,setValueDelegate);
}
}
}
}
private GetValueDelegate GetValueDelegateForField(FieldInfo field){ private GetValueDelegate GetValueDelegateForField(FieldInfo field){
return field.GetValue; return field.GetValue;
} }
@ -120,26 +160,29 @@ namespace TNodeCore.RuntimeCache{
public static class RuntimeExtension{ public static class RuntimeExtension{
//todo latter on i will try some way caching reflection more efficiently //todo latter on i will try some way caching reflection more efficiently
public static T GetValue<T>(this BlackboardData blackboardData,string path){ public static T GetValue<T>(this IModel data,string path,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[type??data.GetType()][path];
return (T) method.Invoke(blackboardData); return (T) method.Invoke(data);
} }
public static object GetValue(this BlackboardData blackboardData, string path){ public static object GetValue(this IModel data, string path,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[type??data.GetType()][path];
return method.Invoke(blackboardData); return method.Invoke(data);
} }
public static void SetValue<T>(this BlackboardData blackboardData,string path,T value){
var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[blackboardData.GetType()][path]; public static void SetValue<T>(this IModel data,string path,T value,Type type=null){
method.Invoke(blackboardData,value); var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[type??data.GetType()][path];
method.Invoke(data,value);
} }
public static void SetValue(this BlackboardData blackboardData,string path,object value){ public static void SetValue(this IModel data,string path,object value,Type type=null){
var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[blackboardData.GetType()][path]; var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[type??data.GetType()][path];
method.Invoke(blackboardData,value); method.Invoke(data,value);
} }
public static RuntimeCache.GetValueDelegate GetValueDelegate(this BlackboardData blackboardData,string path){ public static RuntimeCache.GetValueDelegate GetValueDelegate(this IModel blackboardData,string path){
var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path];
return method; return method;
} }
} }
} }

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using TNode.Editor; using TNode.Editor;
using TNode.Editor.NodeViews; using TNode.Editor.NodeViews;
using TNodeCore.Attribute; using TNodeCore.Attribute;
@ -58,11 +59,13 @@ namespace TNodeGraphViewImpl.Editor.Cache{
SetViewComponentAttribute(type); SetViewComponentAttribute(type);
//Register Node Data by GraphUsageAttribute. //Register Node Data by GraphUsageAttribute.
SetGraphUsageAttribute(type); SetGraphUsageAttribute(type);
} }
} }
} }
} }
private void SetGraphUsageAttribute(Type type){ private void SetGraphUsageAttribute(Type type){
foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){ foreach (var attribute in type.GetCustomAttributes(typeof(GraphUsageAttribute), true)){
var parent = type.BaseType; var parent = type.BaseType;

@ -2,6 +2,7 @@
using System.Reflection; using System.Reflection;
using TNode.Editor.Search; using TNode.Editor.Search;
using TNodeCore.Attribute; using TNodeCore.Attribute;
using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Editor.Serialization; using TNodeCore.Editor.Serialization;
using TNodeCore.Models; using TNodeCore.Models;
using UnityEditor; using UnityEditor;
@ -21,6 +22,8 @@ namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
protected override void UpdateBlackboard(BlackboardData data){ protected override void UpdateBlackboard(BlackboardData data){
if (data == null) return; if (data == null) return;
var serializedObject = new SerializedObject((BlackboardDataWrapper)data); var serializedObject = new SerializedObject((BlackboardDataWrapper)data);
var currentGraphView = graphView as IBaseDataGraphView;
var isRuntimeGraph = currentGraphView?.IsRuntimeGraph ?? false;
foreach (var field in data.GetType() foreach (var field in data.GetType()
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){ .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)){
//if the field is MonoBehaviour,add a property field for blackboard //if the field is MonoBehaviour,add a property field for blackboard
@ -31,14 +34,12 @@ namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
var foldoutData = new Foldout{ var foldoutData = new Foldout{
text = field.Name text = field.Name
}; };
var drawer = new GraphBlackboardPropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),field.Name); var drawer = new GraphBlackboardPropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),field.Name,isRuntimeGraph);
drawer.Bind(serializedObject); drawer.Bind(serializedObject);
foldoutData.Add(drawer); foldoutData.Add(drawer);
visualElement.Add(propertyField); visualElement.Add(propertyField);
visualElement.Add(foldoutData); visualElement.Add(foldoutData);
Add(visualElement); Add(visualElement);
} }
else{ else{
var blackboardList = new BlackboardSection{ var blackboardList = new BlackboardSection{

@ -4,15 +4,18 @@ using UnityEngine.UIElements;
namespace TNodeGraphViewImpl.Editor.GraphBlackboard{ namespace TNodeGraphViewImpl.Editor.GraphBlackboard{
public class GraphBlackboardPropertyField:PropertyField{ public class GraphBlackboardPropertyField:PropertyField{
public GraphBlackboardPropertyField(SerializedProperty findPropertyRelative, string fieldName):base(findPropertyRelative, fieldName){ private readonly bool _runtime;
public GraphBlackboardPropertyField(SerializedProperty findPropertyRelative, string fieldName,bool runtime):base(findPropertyRelative, fieldName){
_runtime = runtime;
} }
protected override void ExecuteDefaultActionAtTarget(EventBase evt) protected override void ExecuteDefaultActionAtTarget(EventBase evt)
{ {
base.ExecuteDefaultActionAtTarget(evt); base.ExecuteDefaultActionAtTarget(evt);
if (this.Q<ObjectField>() != null){ if (this.Q<ObjectField>() != null){
this.Q<ObjectField>().allowSceneObjects = false; this.Q<ObjectField>().allowSceneObjects = _runtime;
} }
} }

@ -1,24 +1,59 @@
using Codice.CM.Common; using System;
using TNode.Editor.Inspector; using TNodeCore.Editor;
using TNodeCore.Editor.EditorPersistence; using TNodeCore.Editor.EditorPersistence;
using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Models; using TNodeCore.Models;
using TNodeGraphViewImpl.Editor.Cache; using TNodeGraphViewImpl.Editor.Cache;
using TNodeGraphViewImpl.Editor.NodeGraphView; using TNodeGraphViewImpl.Editor.NodeGraphView;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace TNode.Editor{ namespace TNodeGraphViewImpl.Editor{
// public class SelectGraphWindow : EditorWindow{
public abstract class GraphEditor<T> : EditorWindow where T:GraphData{ // public EditorWindow parent;
// public Type graphType;
// public static void ShowWindow<T> (GraphEditor<T> parent) where T:GraphData{
// var window = GetWindow<SelectGraphWindow>();
// window.graphType = typeof(T);
// window.Show();
// window.parent = parent;
// }
// private void OnGUI(){
//
// if(GUILayout.Button("Create An Graph")){
// //Add a save file dialog to save the graph
// //Create the graph
// var graphAsset = ScriptableObject.CreateInstance(graphType);
// var path = EditorUtility.SaveFilePanel("Save Graph", "", "", "asset");
// //Save the graph
// AssetDatabase.CreateAsset(graphAsset, path);
// AssetDatabase.SaveAssets();
// AssetDatabase.Refresh();
// //Load the graph
// var graph = AssetDatabase.LoadAssetAtPath<ScriptableObject>(path) as GraphData;
// var graphEditor = parent as IGraphEditor;
// if (graphEditor.GetGraphView() != null){
// graphEditor.GetGraphView().SetGraphData(graph);
// Debug.Log(graph);
// }
// }
// //Drag and drop a graph asset to load it
// if(Event.current.type == EventType.DragUpdated){
// DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
// Event.current.Use();
// }
// }
// }
public abstract class GraphEditor<T> : EditorWindow,IGraphEditor where T:GraphData{
protected BaseDataGraphView<T> GraphView; protected BaseDataGraphView<T> GraphView;
[SerializeField] [SerializeField]
private VisualTreeAsset mVisualTreeAsset = default; private VisualTreeAsset mVisualTreeAsset = default;
//Persist editor data ,such as node position,node size ,etc ,in this script object //Persist editor data ,such as node position,node size ,etc ,in this script object
[FormerlySerializedAs("nodeEditorData")] public GraphEditorData graphEditorData; [FormerlySerializedAs("nodeEditorData")] public GraphEditorData graphEditorData;
private bool _windowShowed=false;
public void CreateGUI(){ public void CreateGUI(){
@ -31,9 +66,23 @@ namespace TNode.Editor{
BuildGraphView(); BuildGraphView();
DefineGraphEditorActions(); DefineGraphEditorActions();
GraphView.Owner = this;
OnCreate(); OnCreate();
} }
public void Update(){
if (GraphView == null) return;
if (GraphView.Data != null) return;
if (_windowShowed==false){
_windowShowed = true;
}
}
public void SetupNonRuntime(T graphData){
GraphView.Data = graphData;
GraphView.IsRuntimeGraph = false;
}
private void BuildGraphView(){ private void BuildGraphView(){
GraphView = NodeEditorExtensions.CreateViewComponentFromBaseType<BaseDataGraphView<T>>(); GraphView = NodeEditorExtensions.CreateViewComponentFromBaseType<BaseDataGraphView<T>>();
rootVisualElement.Add(GraphView); rootVisualElement.Add(GraphView);
@ -76,5 +125,12 @@ namespace TNode.Editor{
} }
public void SetGraphView(IBaseDataGraphView graphView){
GraphView = graphView as BaseDataGraphView<T>;
}
public IBaseDataGraphView GetGraphView(){
return GraphView;
}
} }
} }

@ -36,6 +36,9 @@ namespace TNode.Editor.Inspector{
RefreshPropertyDrawer(); RefreshPropertyDrawer();
} }
private void CreateTestButton(){
}
private void RefreshPropertyDrawer(){ private void RefreshPropertyDrawer(){
//Check if the data's type is a generic type of BlackboardDragNodeData<> //Check if the data's type is a generic type of BlackboardDragNodeData<>
if (_data.GetType().IsSubclassOf(typeof(BlackboardDragNodeData))){ if (_data.GetType().IsSubclassOf(typeof(BlackboardDragNodeData))){
@ -51,6 +54,17 @@ namespace TNode.Editor.Inspector{
var drawer = new PropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),field.Name); var drawer = new PropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),field.Name);
drawer.Bind(serializedObject); drawer.Bind(serializedObject);
Add(drawer); Add(drawer);
}
if (_data.isTest){
//Add a test button for the node
var testButton = new Button(()=>{
Debug.Log("Test button clicked");
});
testButton.text = "Test";
_data.OnTest();
Add(testButton);
} }
} }

@ -1,31 +1,32 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using TNode.Editor;
using TNode.Editor.Inspector; using TNode.Editor.Inspector;
using TNode.Editor.NodeViews;
using TNode.Editor.Search; using TNode.Editor.Search;
using TNodeCore.Editor.Blackboard; using TNodeCore.Editor.Blackboard;
using TNodeCore.Editor.EditorPersistence; using TNodeCore.Editor.EditorPersistence;
using TNodeCore.Editor.NodeGraphView; using TNodeCore.Editor.NodeGraphView;
using TNodeCore.Editor.Tools.NodeCreator; using TNodeCore.Editor.Tools.NodeCreator;
using TNodeCore.Models; using TNodeCore.Models;
using TNodeCore.Runtime;
using TNodeGraphViewImpl.Editor.Cache; using TNodeGraphViewImpl.Editor.Cache;
using TNodeGraphViewImpl.Editor.GraphBlackboard; using TNodeGraphViewImpl.Editor.GraphBlackboard;
using TNodeGraphViewImpl.Editor.GraphBlackboard.BlackboardProperty;
using TNodeGraphViewImpl.Editor.NodeViews; using TNodeGraphViewImpl.Editor.NodeViews;
using UnityEditor; using UnityEditor;
using UnityEditor.Experimental.GraphView; using UnityEditor.Experimental.GraphView;
using UnityEditor.VersionControl;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
using Edge = UnityEditor.Experimental.GraphView.Edge; using Edge = UnityEditor.Experimental.GraphView.Edge;
namespace TNodeGraphViewImpl.Editor.NodeGraphView{ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
public abstract class BaseDataGraphView<T>:GraphView,IDataGraphView<T> where T:GraphData{ public abstract class BaseDataGraphView<T>:GraphView,IDataGraphView<T> where T:GraphData{
#region variables and properties #region variables and properties
private T _data; private T _data;
private RuntimeGraph _runtimeGraph;
private bool _isInspectorOn; private bool _isInspectorOn;
private NodeSearchWindowProvider _nodeSearchWindowProvider; private NodeSearchWindowProvider _nodeSearchWindowProvider;
private NodeInspector _nodeInspector; private NodeInspector _nodeInspector;
@ -64,7 +65,91 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale); SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale);
RegisterDragEvent(); RegisterDragEvent();
OnInit(); OnInit();
CheckAfterInit();
}
/// <summary>
/// Probably reusable in later GTFs version
/// </summary>
private void WaitingForAGraph(){
Debug.Log("hello");
VisualElement visualElement = new VisualElement();
//Set background color to white
visualElement.style.backgroundColor = new StyleColor(new Color(0.1f, 0.1f, 0.1f, 1));
Debug.Log("hello2");
visualElement.StretchToParentSize();
visualElement.name = "WaitingForAGraph";
Add(visualElement);
visualElement.BringToFront();
//Add a label at the center of the created element
Label label = new Label("drag a graph item here"){
style ={
position = Position.Absolute
},
name = "HintLabel"
};
visualElement.RegisterCallback<DragPerformEvent>((evt) => {
//check if the dragged object is a graph data or a Game Object contains a runtime graph
var res = DragAndDrop.objectReferences;
foreach (var obj in res){
if (obj is T graphData){
Data = graphData;
IsRuntimeGraph = false;
}
else{
if (obj is GameObject gameObject){
if (gameObject.GetComponent<RuntimeGraph>() != null){
if (gameObject.GetComponent<RuntimeGraph>().graphData != null){
_runtimeGraph = gameObject.GetComponent<RuntimeGraph>();
IsRuntimeGraph = true;
Data = gameObject.GetComponent<RuntimeGraph>().graphData as T;
if(Data==null){
Debug.LogError($"Dragged a wrong graph data to editor,expected {typeof(T)} but got {gameObject.GetComponent<RuntimeGraph>().graphData.GetType()}");
}
}
}
}
}
}
});
visualElement.RegisterCallback<DragUpdatedEvent>((evt) => {
//check if the dragged object is a graph data or a Game Object contains a runtime graph
var res = DragAndDrop.objectReferences;
foreach (var obj in res){
if (obj is GraphData graphData){
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
}
else{
if (obj is GameObject gameObject){
if (gameObject.GetComponent<RuntimeGraph>() != null){
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
}
}
}
}
});
visualElement.Add(label);
OnDataChanged += (sender, e) => {
if (Data != null){
visualElement.RemoveFromHierarchy();
}
};
}
private void CheckAfterInit(){
if(Data == null){
WaitingForAGraph();
}
} }
private void ConstructDefaultBehaviour(){ private void ConstructDefaultBehaviour(){
//Register a right click context menu //Register a right click context menu
ConstructViewContextualMenu(); ConstructViewContextualMenu();
@ -106,7 +191,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
if(selectable is { } field) { if(selectable is { } field) {
//Make a constructor of BlackboardDragNodeData<field.PropertyType > by reflection //Make a constructor of BlackboardDragNodeData<field.PropertyType > by reflection
var dragNodeData = NodeCreator.InstantiateNodeData<BlackboardDragNodeData>(); var dragNodeData = NodeCreator.InstantiateNodeData<BlackboardDragNodeData>();
dragNodeData.blackboardData = _data.blackboardData; dragNodeData.blackboardData = GetBlackboardData();
dragNodeData.blackDragData = field.BlackboardProperty.PropertyName; dragNodeData.blackDragData = field.BlackboardProperty.PropertyName;
AddTNode(dragNodeData,new Rect(evt.mousePosition,new Vector2(200,200))); AddTNode(dragNodeData,new Rect(evt.mousePosition,new Vector2(200,200)));
} }
@ -116,7 +201,6 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
} }
private void OnDragUpdated(DragUpdatedEvent evt){ private void OnDragUpdated(DragUpdatedEvent evt){
Debug.Log(evt);
//check if the drag data is BlackboardField //check if the drag data is BlackboardField
@ -188,7 +272,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
public virtual void CreateMiniMap(Rect rect){ public virtual void CreateMiniMap(Rect rect){
var miniMap = new MiniMap(); var miniMap = new MiniMap();
this.Add(miniMap); Add(miniMap);
miniMap.SetPosition(rect); miniMap.SetPosition(rect);
} }
@ -200,7 +284,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
if (_data.blackboardData == null) return; if (_data.blackboardData == null) return;
} }
_blackboard.SetBlackboardData(_data.blackboardData); _blackboard.SetBlackboardData(GetBlackboardData());
} }
public virtual void DestroyInspector(){ public virtual void DestroyInspector(){
@ -292,7 +376,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){ public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter){
return ports.Where(x => x.portType == startPort.portType).ToList(); return ports.Where(x => x.portType == startPort.portType || x.portType.IsAssignableFrom(startPort.portType)).ToList();
} }
public virtual void OnGraphViewCreate(){ public virtual void OnGraphViewCreate(){
@ -358,13 +442,10 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
_blackboard.Setup(this,Owner); _blackboard.Setup(this,Owner);
var castedBlackboard = _blackboard as Blackboard; var castedBlackboard = _blackboard as Blackboard;
Add(castedBlackboard); Add(castedBlackboard);
Rect blackboardPos = new Rect(0,0,300,700); Rect blackboardPos = new Rect(0,0,300,700);
castedBlackboard?.SetPosition(blackboardPos); castedBlackboard?.SetPosition(blackboardPos);
OnDataChanged+= (sender, e) => { BlackboardUpdate(); }; OnDataChanged+= (sender, e) => { BlackboardUpdate(); };
} }
@ -374,8 +455,18 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
public BlackboardData GetBlackboardData(){ public BlackboardData GetBlackboardData(){
return this._data.blackboardData; if (IsRuntimeGraph){
return _runtimeGraph.runtimeBlackboardData;
}
return _data.blackboardData;
} }
public bool IsRuntimeGraph{ get; set; }
public void SetGraphData(GraphData graph){
Data = graph as T;
}
#endregion #endregion
} }

@ -45,7 +45,6 @@ namespace TNode.Editor.Search{
} }
Debug.Log($"{list.Count}"); Debug.Log($"{list.Count}");
return list; return list;
} }
public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context){ public bool OnSelectEntry(SearchTreeEntry SearchTreeEntry, SearchWindowContext context){

Loading…
Cancel
Save