-
Notifications
You must be signed in to change notification settings - Fork 404
/
Copy pathDynamicNode.cs
151 lines (119 loc) · 4.99 KB
/
DynamicNode.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GraphProcessor;
using System.Linq;
using System.Reflection;
using System;
[System.Serializable]
public abstract class DynamicNode<T> : BaseNode
{
[Input("Action Data", true)]
public Dictionary<string, List<object>> actionData = new Dictionary<string, List<object>>();
public T data;
public override bool needsInspector => true;
protected override void Process()
{
UpdateActionWithCustomPortData();
}
protected virtual void UpdateActionWithCustomPortData()
{
// We clone due to reference issues
Dictionary<string, List<object>> actionDataClone = new Dictionary<string, List<object>>(actionData);
foreach (var field in GetInputFieldsOfType())
{
if (!actionDataClone.ContainsKey(field.fieldInfo.Name))
{
if (field.inputAttribute.showAsDrawer || field.fieldInfo.HasCustomAttribute<ShowAsDrawer>())
continue;
field.fieldInfo.SetValue(data, default);
continue;
}
field.fieldInfo.SetValue(data, actionDataClone[field.fieldInfo.Name][0]);
}
actionData.Clear();
}
#region Reflection Generation Of Ports
private List<FieldPortInfo> GetInputFieldsOfType()
{
List<FieldPortInfo> foundInputFields = new List<FieldPortInfo>();
Type dataType = data != null ? data.GetType() : typeof(T);
foreach (var field in dataType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
foreach (var attribute in field.GetCustomAttributes(typeof(InputAttribute), true))
{
if (attribute.GetType() != typeof(InputAttribute) && !attribute.GetType().IsSubclassOf(typeof(InputAttribute))) continue;
foundInputFields.Add(new FieldPortInfo(field, attribute as InputAttribute));
break;
}
}
return foundInputFields;
}
private FieldPortInfo GetFieldPortInfo(string fieldName)
{
Type dataType = data != null ? data.GetType() : typeof(T);
FieldInfo fieldInfo = dataType.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
InputAttribute inputAttribute = fieldInfo.GetCustomAttribute<InputAttribute>();
return new FieldPortInfo(fieldInfo, inputAttribute);
}
[CustomPortInput(nameof(actionData), typeof(object))]
protected void PullInputs(List<SerializableEdge> connectedEdges)
{
if (connectedEdges.Count == 0) return;
FieldPortInfo field = GetFieldPortInfo(connectedEdges.ElementAt(0).inputPortIdentifier);
if (actionData == null) actionData = new Dictionary<string, List<object>>();
foreach (var edge in connectedEdges)
{
if (!actionData.ContainsKey(field.fieldInfo.Name))
actionData.Add(field.fieldInfo.Name, new List<object>());
actionData[field.fieldInfo.Name].Add(edge.passThroughBuffer);
}
}
[CustomPortBehavior(nameof(actionData))]
protected IEnumerable<PortData> ActionDataBehaviour(List<SerializableEdge> edges) // Try changing edge here when ports update
{
foreach (var field in GetInputFieldsOfType())
{
Type displayType = field.fieldInfo.FieldType;
yield return new PortData
{
displayName = field.inputAttribute.name,
displayType = displayType,
identifier = field.fieldInfo.Name,
showAsDrawer = field.inputAttribute.showAsDrawer,
vertical = false,
proxiedFieldPath = nameof(data) + '.' + field.fieldInfo.Name,
acceptMultipleEdges = field.inputAttribute.allowMultiple,
};
}
// Debug.Log(this.GetCustomName() + " BEHAVE: " + this.inputPorts.Count);
}
// public override IEnumerable<FieldInfo> OverrideFieldOrder(IEnumerable<FieldInfo> fields)
// {
// return base.OverrideFieldOrder(fields).Reverse();
// // static long GetFieldInheritanceLevel(FieldInfo f)
// // {
// // int level = 0;
// // var t = f.DeclaringType;
// // while (t != null)
// // {
// // t = t.BaseType;
// // level++;
// // }
// // return level;
// // }
// // // Order by MetadataToken and inheritance level to sync the order with the port order (make sure FieldDrawers are next to the correct port)
// // return fields.OrderByDescending(f => (GetFieldInheritanceLevel(f) << 32) | (long)f.MetadataToken);
// }
#endregion
}
public struct FieldPortInfo
{
public FieldInfo fieldInfo;
public InputAttribute inputAttribute;
public FieldPortInfo(FieldInfo fieldInfo, InputAttribute inputAttribute)
{
this.fieldInfo = fieldInfo;
this.inputAttribute = inputAttribute;
}
}