fix: fix runtime conditional node bug

main
taoria 3 years ago
parent 7207424daf
commit f6af4e7390
  1. 25
      Samples/AddNode.cs
  2. 4
      Samples/HelloBlackboard.cs
  3. 153
      Samples/New HelloGraph.asset
  4. 3
      Samples/Nodes.meta
  5. 15
      Samples/Nodes/AddNode.cs
  6. 0
      Samples/Nodes/AddNode.cs.meta
  7. 28
      Samples/Nodes/CheckSizeNode.cs
  8. 3
      Samples/Nodes/CheckSizeNode.cs.meta
  9. 2
      Samples/TestScene.unity
  10. 4
      TNodeCore/Editor/Tools/GraphEditorCreator/GraphEditorCreator.cs
  11. 4
      TNodeCore/Runtime/Components/RuntimeGraph.cs
  12. 32
      TNodeCore/Runtime/Models/ConditionalNode.cs
  13. 51
      TNodeCore/Runtime/RuntimeCache/RuntimeCache.cs
  14. 10
      TNodeCore/Runtime/RuntimeModels/ConditionalRuntimeNode.cs
  15. 4
      TNodeCore/Runtime/RuntimeModels/StaticGraph.cs
  16. 7
      TNodeCore/Runtime/Tools/GraphTool.cs
  17. 5
      TNodeGraphViewImpl/Editor/NodeGraphView/DataGraphView.cs
  18. 131
      TNodeGraphViewImpl/Editor/NodeViews/NodeView.cs
  19. 64
      Tests/StaticGraphTest.cs

@ -1,25 +0,0 @@

using System.Collections.Generic;
using System.Runtime.InteropServices;
using TNodeCore.Runtime;
using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.Models;
using UnityEngine;
namespace Samples{
[GraphUsage(typeof(HelloGraph),"Math")]
public class AddNode:NodeData{
[Input]
public Vector3 A{ get; set; }
[Input]
public Vector2 B{ get; set; }
[Output]
public Vector3 Res{ get; set; }
public override void Process(){
Res = A + (Vector3)B;
this.Log($"{Res}");
}
}
}

@ -10,8 +10,8 @@ namespace TNode.Samples{
public class HelloBlackboard:BlackboardData{
public string HelloString;
public GameObject HelloGameObject;
public List<Vector3> V3S;
public List<Vector2> V2S;
public List<float> Value;
}
}

@ -17,64 +17,31 @@ MonoBehaviour:
- id: 1
- id: 2
- id: 3
- id: 4
- id: 5
- id: 6
nodeLinks:
- inPort:
portEntryName: B
nodeDataId: 94327133-34e1-47bb-a365-0782120c581e
outPort:
portEntryName: Value
nodeDataId: 07c1f545-719b-4f9b-9f4c-dc3883c02423
- inPort:
portEntryName: A
nodeDataId: 94327133-34e1-47bb-a365-0782120c581e
nodeDataId: 4300534d-023d-4b56-a0cb-39e197e68845
outPort:
portEntryName: Value
nodeDataId: 72477a0c-2399-47c1-ba04-495add218335
- inPort:
portEntryName: A
nodeDataId: 134adf78-f8ba-4888-8362-4a2ca0df2c69
outPort:
portEntryName: Res
nodeDataId: 94327133-34e1-47bb-a365-0782120c581e
nodeDataId: 6dba1aab-0db9-45a0-b3f7-e8fe9c47c168
- inPort:
portEntryName: B
nodeDataId: 134adf78-f8ba-4888-8362-4a2ca0df2c69
nodeDataId: 4300534d-023d-4b56-a0cb-39e197e68845
outPort:
portEntryName: Value
nodeDataId: 9b6e59e3-cc30-4697-a310-8f1195631ec9
nodeDataId: 5fd53e10-e727-45e3-8458-04a6ec8581c4
- inPort:
portEntryName: A
nodeDataId: 8d01abf2-f69a-4884-a6a1-99903ed96b7a
nodeDataId: f236a611-cc64-4fce-88d2-40baf7f4a490
outPort:
portEntryName: Value
nodeDataId: 72477a0c-2399-47c1-ba04-495add218335
- inPort:
portEntryName: B
nodeDataId: 8d01abf2-f69a-4884-a6a1-99903ed96b7a
outPort:
portEntryName: Value
nodeDataId: 07c1f545-719b-4f9b-9f4c-dc3883c02423
- inPort:
portEntryName: A
nodeDataId: d4ff4eb9-dd02-4712-90dc-898223d1758f
outPort:
portEntryName: Res
nodeDataId: 8d01abf2-f69a-4884-a6a1-99903ed96b7a
- inPort:
portEntryName: B
nodeDataId: d4ff4eb9-dd02-4712-90dc-898223d1758f
outPort:
portEntryName: Value
nodeDataId: 07c1f545-719b-4f9b-9f4c-dc3883c02423
portEntryName: C
nodeDataId: 4300534d-023d-4b56-a0cb-39e197e68845
blackboardData:
id: 7
id: 4
sceneReference:
editorModels: []
graphViewModel:
id: 8
id: 5
references:
version: 1
00000000:
@ -82,105 +49,62 @@ MonoBehaviour:
data:
positionInView:
serializedVersion: 2
x: 550
y: 218
x: 674
y: 261
width: 0
height: 0
id: 72477a0c-2399-47c1-ba04-495add218335
id: 6dba1aab-0db9-45a0-b3f7-e8fe9c47c168
nodeName:
entryPoint: 0
isTest: 0
blackboardDragTypeString: UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
blackDragData: V3S.0
blackboardDragTypeString: System.Single, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
blackDragData: Value.0
isListElement: 1
00000001:
type: {class: AddNode, ns: Samples, asm: Assembly-CSharp}
data:
positionInView:
serializedVersion: 2
x: 906
y: 29
width: 0
height: 0
id: d4ff4eb9-dd02-4712-90dc-898223d1758f
nodeName: AddNode
entryPoint: 0
isTest: 0
00000002:
type: {class: BlackboardDragNode, ns: TNodeCore.Runtime.Models, asm: Taoria.TNodeCore.Runtime}
data:
positionInView:
serializedVersion: 2
x: 574
y: 306
x: 674
y: 330
width: 0
height: 0
id: 07c1f545-719b-4f9b-9f4c-dc3883c02423
id: 5fd53e10-e727-45e3-8458-04a6ec8581c4
nodeName:
entryPoint: 0
isTest: 0
blackboardDragTypeString: UnityEngine.Vector2, UnityEngine.CoreModule, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
blackDragData: V2S.0
blackboardDragTypeString: System.Single, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
blackDragData: Value.1
isListElement: 1
00000003:
type: {class: AddNode, ns: Samples, asm: Assembly-CSharp}
data:
positionInView:
serializedVersion: 2
x: 733
y: 52
width: 0
height: 0
id: 8d01abf2-f69a-4884-a6a1-99903ed96b7a
nodeName: AddNode
entryPoint: 0
isTest: 0
00000004:
type: {class: BlackboardDragNode, ns: TNodeCore.Runtime.Models, asm: Taoria.TNodeCore.Runtime}
data:
positionInView:
serializedVersion: 2
x: 817
y: 387
width: 0
height: 0
id: 9b6e59e3-cc30-4697-a310-8f1195631ec9
nodeName:
entryPoint: 0
isTest: 0
blackboardDragTypeString: UnityEngine.Vector2, UnityEngine.CoreModule, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
blackDragData: V2S.0
isListElement: 1
00000005:
type: {class: AddNode, ns: Samples, asm: Assembly-CSharp}
00000002:
type: {class: AddNode, ns: Samples.Nodes, asm: Assembly-CSharp}
data:
positionInView:
serializedVersion: 2
x: 669.5
y: 198.5
x: 774
y: 252
width: 0
height: 0
id: 94327133-34e1-47bb-a365-0782120c581e
id: 4300534d-023d-4b56-a0cb-39e197e68845
nodeName: AddNode
entryPoint: 0
isTest: 0
00000006:
type: {class: AddNode, ns: Samples, asm: Assembly-CSharp}
00000003:
type: {class: CheckSizeNode, ns: Samples.Nodes, asm: Assembly-CSharp}
data:
positionInView:
serializedVersion: 2
x: 1007
y: 199
x: 904
y: 252
width: 0
height: 0
id: 134adf78-f8ba-4888-8362-4a2ca0df2c69
nodeName: AddNode
id: f236a611-cc64-4fce-88d2-40baf7f4a490
nodeName: CheckSizeNode
entryPoint: 0
isTest: 0
00000007:
00000004:
type: {class: HelloBlackboard, ns: TNode.Samples, asm: Assembly-CSharp}
data:
positionInView:
@ -192,11 +116,10 @@ MonoBehaviour:
id:
HelloString:
HelloGameObject: {fileID: 0}
V3S:
- {x: 0, y: 0, z: 0}
V2S:
- {x: 4, y: 4}
00000008:
Value:
- 11
- 102.1
00000005:
type: {class: GraphViewModel, ns: TNode.TNodeCore.Editor.Models, asm: Taoria.TNodeCore.Runtime}
data:
positionInView:
@ -207,5 +130,5 @@ MonoBehaviour:
height: 0
id:
persistScale: 1
persistOffset: {x: -169, y: 62}
persistOffset: {x: -136, y: 40}
isBlackboardOn: 1

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f50f5cbc213948329c1087add634caa6
timeCreated: 1661237859

@ -0,0 +1,15 @@
using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.Models;
namespace Samples.Nodes{
[GraphUsage(typeof(HelloGraph),"Math")]
public class AddNode:NodeData{
[Input]
public float A{ get; set; }
[Input]
public float B{ get; set; }
[Output] public float C => A + B;
}
}

@ -0,0 +1,28 @@
using TNode.TNodeCore.Runtime.Models;
using TNodeCore.Runtime.Attributes;
using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.Models;
namespace Samples.Nodes{
[GraphUsage(typeof(HelloGraph),"Math")]
public class CheckSizeNode:ConditionalNode{
[Input]
public float A{ get; set; }
[Output]
public TransitionCondition Bigger(){
return new TransitionCondition(){
Condition = A>0,
Priority = 0
};
}
[Output]
public TransitionCondition SmallerOrEqual(){
return new TransitionCondition(){
Condition = A<=0,
Priority = 0
};
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7f1f136a46d34c1ab5bcc8bc1a43fe5f
timeCreated: 1661237873

@ -219,7 +219,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 325720a2ce64404d917fff20d22e80f2, type: 3}
m_Name:
m_EditorClassIdentifier:
graphData: {fileID: 11400000, guid: f55ebad0b05015a4f873ac78896d95d3, type: 2}
graphData: {fileID: 0}
runtimeBlackboardData:
id: 0
references:

@ -19,8 +19,8 @@ namespace TNodeCore.Editor.Tools.GraphEditorCreator{
private TextField _graphClassNameTextField;
private Button _createButton;
private readonly SourceGeneratorForGraphEditor _sourceGeneratorForGraphEditor = new SourceGeneratorForGraphEditor();
[MenuItem("Assets/CreateProp/TNodeCore/CreateProp New Graph Editor")]
[MenuItem("TNodeCore/CreateProp New Graph Editor")]
[MenuItem("Assets/Create/TNodeCore/Create New Graph Editor")]
[MenuItem("TNodeCore/Create New Graph Editor")]
public static void ShowExample()
{
GraphEditorCreator wnd = GetWindow<GraphEditorCreator>();

@ -179,10 +179,10 @@ namespace TNodeCore.Runtime.Components{
_runtimeNodeEnumerator = _graphTool.DeepFirstSearchWithCondition();
break;
case AccessMethod.StateTransition:
_runtimeNodeEnumerator = _graphTool.IterateDirectlyTraversal();
_runtimeNodeEnumerator = _graphTool.IterateNext();
break;
case AccessMethod.Dependency:
_runtimeNodeEnumerator = _graphTool.IterateNext();
_runtimeNodeEnumerator = _graphTool.IterateDirectlyTraversal();
break;
}

@ -1,14 +1,36 @@
using TNodeCore.Runtime;
using TNodeCore.Runtime.Attributes.Ports;
using TNodeCore.Runtime.Models;
using Unity.Plastic.Newtonsoft.Json.Serialization;
namespace TNode.TNodeCore.Runtime.Models{
public class ConditionalNode:NodeData{
[Input]
public object In{ get; set; }
}
public class TransitionCondition:IBaseTransition{
public Func<object> DataFunc;
public bool Condition{ get; set; }
public int Priority{ get; set; }
public object GetValue(){
return DataFunc();
}
}
public class TransitionCondition<T>:IBaseTransition{
public Func<T> DataFunc;
public bool Condition{ get; set; }
public int Priority{ get; set; }
public object GetValue(){
return DataFunc.Invoke();
}
}
public struct TransitionCondition{
public bool Condition;
public int Priority;
public interface IBaseTransition{
public bool Condition{ get; set; }
public int Priority{ get; set; }
public object GetValue();
}
}

@ -31,14 +31,8 @@ namespace TNodeCore.Runtime.RuntimeCache{
if (method == null){
throw new Exception("Method not found for name " + name);
}
if (method.ReturnType != typeof(void)){
Type = method.ReturnType;
Get = (Func<T1, T2>)Delegate.CreateDelegate(typeof(Func<T1, T2>), null, method);
}
else{
Type = method.GetParameters()[0].ParameterType;
Set = (Action<T1, T2>)Delegate.CreateDelegate(typeof(Action<T1, T2>), null, method);
}
Type = method.MethodPortType();
Get = (Func<T1, T2>)Delegate.CreateDelegate(typeof(Func<T1, T2>), null, method);
}
}
@ -448,6 +442,47 @@ namespace TNodeCore.Runtime.RuntimeCache{
var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[type??data.GetType()][path];
method.Invoke(data,value);
}
public static Type MethodPortType(this MethodInfo info){
if (info.ReturnType == typeof(void)){
return info.GetParameters()[0].ParameterType;
}
else{
return info.ReturnType;
}
}
public static Type MemberPortType(this MemberInfo memberInfo){
if (memberInfo is FieldInfo){
throw new Exception("FieldInfo is not supported as Port");
}
if (memberInfo is MethodInfo methodInfo){
return MethodPortType(methodInfo);
}
if (memberInfo is PropertyInfo propertyInfo){
return propertyInfo.PropertyType;
}
return memberInfo.DeclaringType;
}
public static object GetPortValue(this MemberInfo memberInfo,Model data){
if (memberInfo is FieldInfo){
throw new Exception("FieldInfo is not supported as Port");
}
if (memberInfo is MethodInfo methodInfo){
return methodInfo.Invoke(data, null);
}
if (memberInfo is PropertyInfo propertyInfo){
return propertyInfo.GetValue(data);
}
return null;
}
}
}

@ -22,7 +22,10 @@ namespace TNodeCore.Runtime{
}
foreach (var port in transitionPort){
if(GetPortDirection(port)==Direction.Input) continue;
_possibleTransition.Add(new Tuple<string, Func<TransitionCondition>>(port,() => (TransitionCondition)GetOutput(port)) );
var ids = OutputLinks.Where(x => x.outPort.portEntryName == port).Select(x => x.inPort.nodeDataId);
var enumerable1 = ids as string[] ?? ids.ToArray();
if(enumerable1.FirstOrDefault()!=null)
_possibleTransition.Add(new Tuple<string, Func<TransitionCondition>>(enumerable1.FirstOrDefault(),() => (TransitionCondition)GetOutput(port)) );
}
}
else{
@ -32,10 +35,7 @@ namespace TNodeCore.Runtime{
public string[] GetConditionalNextIds(){
var ports = _possibleTransition.Where(x => x.Item2().Condition);
var portNames = ports.Select(x => x.Item1);
//Search output links to found the link contains portNames as outport's name
var outputLinks = OutputLinks.Where(x => portNames.Contains(x.outPort.portEntryName));
return outputLinks.Select(x => x.inPort.nodeDataId).ToArray();
return ports.Select(x => x.Item1).ToArray();
}
public string GetNextNodeId(){

@ -59,10 +59,10 @@ namespace TNodeCore.Runtime.RuntimeModels{
_runtimeNodeEnumerator = _graphTool.DeepFirstSearchWithCondition();
break;
case AccessMethod.StateTransition:
_runtimeNodeEnumerator = _graphTool.IterateDirectlyTraversal();
_runtimeNodeEnumerator = _graphTool.IterateNext();
break;
case AccessMethod.Dependency:
_runtimeNodeEnumerator = _graphTool.IterateNext();
_runtimeNodeEnumerator = _graphTool.IterateDirectlyTraversal();
break;
}

@ -83,7 +83,12 @@ namespace TNode.TNodeCore.Runtime.Tools{
while(currentNode.OutputLinks.Any()){
if (currentNode is ConditionalRuntimeNode conditionalRuntimeNode){
currentNode = RuntimeNodes[conditionalRuntimeNode.GetNextNodeId()];
var id = conditionalRuntimeNode.GetNextNodeId();
if (id != null && id.Trim(' ').Length > 0){
Debug.Log(currentNode.NodeData+" is going to run "+id);
currentNode = RuntimeNodes[conditionalRuntimeNode.GetNextNodeId()];
}
}
else{
var link = currentNode.OutputLinks.FirstOrDefault();

@ -191,7 +191,7 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
Vector2 editorPosition = Owner==null?Vector2.zero:Owner.position.position;
//Remove all the previous menu items
evt.menu.MenuItems().Clear();
evt.menu.AppendAction("CreateProp Node", dma => {
evt.menu.AppendAction("Create Node", dma => {
var dmaPos = dma.eventInfo.mousePosition+editorPosition;
var searchWindow = ScriptableObject.CreateInstance<NodeSearchWindowProvider>();
var targetPos = this.viewTransform.matrix.inverse.MultiplyPoint(dma.eventInfo.localMousePosition);
@ -200,10 +200,9 @@ namespace TNodeGraphViewImpl.Editor.NodeGraphView{
searchWindow.Setup(typeof(T),this,Owner,targetPos);
Debug.Log(targetPos);
SearchWindow.Open(searchWindowContext, searchWindow);
});
evt.menu.AppendAction("CreateProp PlacematModel",dma=> {
evt.menu.AppendAction("Create PlacematModel",dma=> {
//find placemat container
var container = GetPlacematContainer();
var targetPos = this.viewTransform.matrix.inverse.MultiplyPoint(dma.eventInfo.localMousePosition);

@ -116,18 +116,18 @@ namespace TNodeGraphViewImpl.Editor.NodeViews{
this.RefreshExpandedState();
}
protected virtual string BuildPortName(PortAttribute portAttribute,PropertyInfo propertyInfo,params object[] args){
protected virtual string BuildPortName(PortAttribute portAttribute,MemberInfo memberInfo,params object[] args){
switch (portAttribute.NameHandling){
case PortNameHandling.Auto:
return portAttribute.Name.Trim(' ').Length>0?portAttribute.Name:propertyInfo.Name;
return portAttribute.Name.Trim(' ').Length>0?portAttribute.Name:memberInfo.Name;
case PortNameHandling.Manual:
return portAttribute.Name;
case PortNameHandling.MemberName:
return propertyInfo.Name;
return memberInfo.Name;
case PortNameHandling.Format:
return String.Format(propertyInfo.Name, args);
return String.Format(memberInfo.Name, args);
case PortNameHandling.MemberType:
return propertyInfo.PropertyType.Name;
return memberInfo.MemberPortType().Name;
default:
throw new ArgumentOutOfRangeException();
}
@ -152,28 +152,32 @@ namespace TNodeGraphViewImpl.Editor.NodeViews{
throw new Exception("Member is not a property or field");
}
protected virtual Type BuildPortType(PortAttribute portAttribute,PropertyInfo propertyInfo){
protected virtual Type BuildPortType(PortAttribute portAttribute,MemberInfo propertyInfo){
switch (portAttribute.TypeHandling){
switch (portAttribute.TypeHandling){
case TypeHandling.Declared :
return propertyInfo.PropertyType;
return propertyInfo.MemberPortType();
case TypeHandling.Implemented:
return propertyInfo.GetValue(_data)?.GetType();
return propertyInfo.GetPortValue(_data)?.GetType();
case TypeHandling.Specified:
return portAttribute.HandledType??typeof(object);
case TypeHandling.Path:
var type = GetDataType(portAttribute.TypePath);
return type;
default:
throw new ArgumentOutOfRangeException();
}
}
protected virtual Type BuildGroupPortType(PortAttribute portAttribute,PropertyInfo propertyInfo,int index){
var iList = propertyInfo.GetValue(_data) as IList;
protected virtual Type BuildGroupPortType(PortAttribute portAttribute,MemberInfo propertyInfo,int index){
IList iList = null;
if (propertyInfo is PropertyInfo propertyInfo1){
iList = propertyInfo1.GetValue(_data) as IList;
}
else if (propertyInfo is MethodInfo methodInfo){
iList = methodInfo.Invoke(_data,null) as IList;
}
if (iList is Array array){
switch (portAttribute.TypeHandling){
case TypeHandling.Declared:
@ -204,9 +208,7 @@ namespace TNodeGraphViewImpl.Editor.NodeViews{
throw new ArgumentOutOfRangeException();
}
}
return null;
}
/// <summary>
@ -214,67 +216,71 @@ namespace TNodeGraphViewImpl.Editor.NodeViews{
/// </summary>
protected virtual void BuildInputAndOutputPort(){
var propertyInfos = _data.GetType().GetProperties();
var methodInfos = _data.GetType().GetMethods();
foreach (var propertyInfo in propertyInfos){
if (propertyInfo.GetCustomAttributes(typeof(OutputAttribute),true).FirstOrDefault() is OutputAttribute attribute){
if (attribute.Group == false){
Port port = new CustomPort(Orientation.Horizontal, Direction.Output,
attribute.Multiple ? Port.Capacity.Multi : Port.Capacity.Single,
BuildPortType(attribute, propertyInfo));
BuildPort(port, attribute, propertyInfo,outputContainer);
}
else{
var propertyValue = propertyInfo.GetValue(_data);
if (propertyValue is IList list){
for (var i = 0; i < list.Count; i++){
var port = new CustomPort(Orientation.Horizontal, Direction.Output,
Port.Capacity.Single,
BuildGroupPortType(attribute, propertyInfo,i));
BuildGroupPort(port, attribute, propertyInfo,outputContainer,list[i],i);
}
}
}
BuildPortFromAttributeAndPropertyInfo(attribute,propertyInfo,Direction.Output);
}
}
foreach (var propertyInfo in propertyInfos){
if(propertyInfo.GetCustomAttributes(typeof(InputAttribute),true).FirstOrDefault() is InputAttribute attribute){
if (attribute.Group == false){
Port port = new CustomPort
(Orientation.Horizontal,
Direction.Input,attribute.Multiple?Port.Capacity.Multi: Port.Capacity.Single,BuildPortType(attribute,propertyInfo));
BuildPort(port,attribute,propertyInfo,inputContainer);
BuildPortFromAttributeAndPropertyInfo(attribute, propertyInfo);
}
}
foreach (var method in methodInfos){
if (method.GetCustomAttribute<PortAttribute>() != null){
var portAtt = method.GetCustomAttribute<PortAttribute>();
if (portAtt is InputAttribute input){
BuildPortFromAttributeAndPropertyInfo(input,method);
}
else{
var propertyValue = propertyInfo.GetValue(_data);
if (propertyValue is IList list){
for (var i = 0; i < list.Count; i++){
var port = new CustomPort(Orientation.Horizontal, Direction.Input,
Port.Capacity.Single,
BuildGroupPortType(attribute, propertyInfo,i));
BuildGroupPort(port, attribute, propertyInfo,inputContainer,list[i],i);
}
}
if (portAtt is OutputAttribute output){
BuildPortFromAttributeAndPropertyInfo(output,method,Direction.Output);
}
}
}
}
private void BuildPortFromAttributeAndPropertyInfo(PortAttribute attribute, MemberInfo propertyInfo,Direction direction = Direction.Input){
if (attribute.Group == false){
Port port = new CustomPort
(Orientation.Horizontal,
direction, attribute.Multiple ? Port.Capacity.Multi : Port.Capacity.Single,
BuildPortType(attribute, propertyInfo));
BuildPort(port, attribute, propertyInfo, direction==Direction.Input?inputContainer:outputContainer);
}
else{
var propertyValue = propertyInfo.GetPortValue(_data);
if (propertyValue is IList list){
for (var i = 0; i < list.Count; i++){
var port = new CustomPort(Orientation.Horizontal, direction,
attribute.Multiple ? Port.Capacity.Multi : Port.Capacity.Single,
BuildGroupPortType(attribute, propertyInfo, i));
BuildGroupPort(port, attribute, propertyInfo, direction==Direction.Input?inputContainer:outputContainer, list[i], i);
}
}
}
}
private void BuildPort(Port port, PortAttribute attribute, PropertyInfo propertyInfo,VisualElement portContainer){
private void BuildPort(Port port, PortAttribute attribute, MemberInfo memberInfo,VisualElement portContainer){
portContainer.Add(port);
var portName = ObjectNames.NicifyVariableName(BuildPortName(attribute, propertyInfo));
var portName = ObjectNames.NicifyVariableName(BuildPortName(attribute, memberInfo));
port.portName = portName;
port.name = propertyInfo.Name;
var colorAtt = propertyInfo.PropertyType.GetCustomAttribute<PortColorAttribute>();
port.name = memberInfo.Name;
PortColorAttribute colorAtt = null;
colorAtt = memberInfo.MemberPortType().GetCustomAttribute<PortColorAttribute>();
if (colorAtt != null){
var color = colorAtt.Color;
port.portColor = color;
}
}
private void BuildGroupPort(Port port, PortAttribute attribute, PropertyInfo propertyInfo,
private void BuildGroupPort(Port port, PortAttribute attribute, MemberInfo propertyInfo,
VisualElement portContainer,object currentElement,int index = 0){
portContainer.Add(port);
port.name = propertyInfo.Name + ":" + index;
@ -286,26 +292,23 @@ namespace TNodeGraphViewImpl.Editor.NodeViews{
port.portName = ObjectNames.NicifyVariableName(BuildGroupPortName(attribute, propertyInfo, index));
}
}
}
private string BuildGroupPortName(PortAttribute attribute, PropertyInfo propertyInfo, int index){
private string BuildGroupPortName(PortAttribute attribute, MemberInfo memberInfo, int index){
switch (attribute.NameHandling){
case PortNameHandling.Auto:
return (attribute.Name.Trim(' ').Length>0?attribute.Name:propertyInfo.Name)+":"+index;
return (attribute.Name.Trim(' ').Length>0?attribute.Name:memberInfo.Name)+":"+index;
case PortNameHandling.Manual:
return attribute.Name+":"+index;;
case PortNameHandling.MemberName:
return propertyInfo.Name+":"+index;
return memberInfo.Name+":"+index;
case PortNameHandling.Format:
throw new NotImplementedException();
case PortNameHandling.MemberType:
return propertyInfo.PropertyType.Name+":"+index;
return memberInfo.MemberPortType().Name + ":" + index;
default:
throw new ArgumentOutOfRangeException();
}
}
public void StartARenameTitleTextField(){
var textField = new TextField{
value = title,

@ -17,12 +17,14 @@ namespace Tests{
}
[GraphUsage(typeof(GraphDataForTest))]
internal class TestNode : NodeData{
[Input] public int Input{ get; set; }
[Input] public object Input{ get; set; }
[Output] public int Output{ get; set; }
}
[GraphUsage(typeof(GraphDataForTest))]
internal class TestConditionalNode : ConditionalNode{
public bool TestCondition = false;
[Input]
public object In{ get; set; }
[Output]
public TransitionCondition Output(){
return new TransitionCondition(){
@ -185,5 +187,65 @@ namespace Tests{
staticGraph2.MoveNext();
Assert.AreNotEqual(node6,staticGraph2.CurrentNode());
}
[Test]
public void TestStaticGraphDirectlyNext(){
GraphData graphData = ScriptableObject.CreateInstance<GraphData>();
var node1 = NodeCreator.InstantiateNodeData<TestNode>();
var node2 = NodeCreator.InstantiateNodeData<TestNode>();
var node3 = NodeCreator.InstantiateNodeData<TestConditionalNode>();
var node4 = NodeCreator.InstantiateNodeData<TestConditionalNode>();
var node5 = NodeCreator.InstantiateNodeData<TestNode>();
var node6 = NodeCreator.InstantiateNodeData<TestNode>();
graphData.NodeDictionary.Add(node1.id,node1);
graphData.NodeDictionary.Add(node2.id,node2);
graphData.NodeDictionary.Add(node3.id,node3);
graphData.NodeDictionary.Add(node4.id,node4);
graphData.NodeDictionary.Add(node5.id,node5);
graphData.NodeDictionary.Add(node6.id,node6);
//Link node1 to node2
graphData.NodeLinks.Add(new NodeLink(new PortInfo{
portEntryName = "Input",
nodeDataId = node2.id
},new PortInfo{
portEntryName = "Output",
nodeDataId = node1.id
}));
//Link node2 to node3
graphData.NodeLinks.Add(new NodeLink(new PortInfo{
portEntryName = "In",
nodeDataId = node3.id
},new PortInfo{
portEntryName = "Output",
nodeDataId = node2.id
}));
//Link node3 to node6
graphData.NodeLinks.Add(new NodeLink(new PortInfo{
portEntryName = "Input",
nodeDataId = node6.id
},new PortInfo{
portEntryName = "Output",
nodeDataId = node3.id
}));
node3.TestCondition = true;
var staticGraph = new StaticGraph(graphData);
staticGraph.AccessMethod = AccessMethod.StateTransition;
staticGraph.ResetState();
Assert.AreEqual(node1,staticGraph.CurrentNode());
staticGraph.MoveNext();
Assert.AreEqual(node2,staticGraph.CurrentNode());
staticGraph.MoveNext();
Assert.AreEqual(node3,staticGraph.CurrentNode());
staticGraph.MoveNext();
}
}
}
Loading…
Cancel
Save