mirror of
https://github.com/Siccity/xNode.git
synced 2026-02-06 15:24:55 +08:00
Streamlined creation of custom node ports
Instead of initializing port arrays in Init();, ports are now defined by attributes on public fields
This commit is contained in:
parent
97bbc236be
commit
59085db16a
@ -3,6 +3,8 @@
|
||||
[System.Serializable]
|
||||
public class BaseNode : Node {
|
||||
|
||||
[Input] public string input;
|
||||
[Output] public string output;
|
||||
public bool concat;
|
||||
[TextArea]
|
||||
public string SomeString;
|
||||
@ -10,11 +12,4 @@ public class BaseNode : Node {
|
||||
public Color col;
|
||||
public AnimationCurve anim;
|
||||
public Vector3 vec;
|
||||
protected override void Init() {
|
||||
inputs = new NodePort[2];
|
||||
inputs[0] = CreateNodeInput("IntInput", typeof(int));
|
||||
inputs[1] = CreateNodeInput("StringInput", typeof(string));
|
||||
outputs = new NodePort[1];
|
||||
outputs[0] = CreateNodeOutput("StringOutput", typeof(string));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,25 +2,11 @@
|
||||
|
||||
[System.Serializable]
|
||||
public class MathNode : Node {
|
||||
|
||||
[Input] public float a;
|
||||
[Input] public float b;
|
||||
[Output] public float result;
|
||||
public enum ValueType { Float, Int }
|
||||
public enum MathType { Add, Subtract, Multiply, Divide}
|
||||
public ValueType valueType = ValueType.Float;
|
||||
public MathType mathType = MathType.Add;
|
||||
|
||||
protected override void Init() {
|
||||
inputs = new NodePort[2];
|
||||
inputs[0] = CreateNodeInput("A", typeof(float));
|
||||
inputs[1] = CreateNodeInput("B", typeof(float));
|
||||
outputs = new NodePort[1];
|
||||
outputs[0] = CreateNodeOutput("Result", typeof(float));
|
||||
}
|
||||
|
||||
public void OnValidate() {
|
||||
System.Type type = typeof(int);
|
||||
if (valueType == ValueType.Float) type = typeof(float);
|
||||
inputs[0].type = type;
|
||||
inputs[1].type = type;
|
||||
outputs[0].type = type;
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,11 +14,11 @@ public class NodeEditor {
|
||||
public virtual void OnNodeGUI() {
|
||||
portRects.Clear();
|
||||
DrawNodePortsGUI();
|
||||
DrawDefaultNodeGUI();
|
||||
DrawDefaultNodeBody();
|
||||
}
|
||||
|
||||
/// <summary> Draws standard field editors for all public fields </summary>
|
||||
protected void DrawDefaultNodeGUI() {
|
||||
protected void DrawDefaultNodeBody() {
|
||||
FieldInfo[] fields = GetInspectorFields(target);
|
||||
for (int i = 0; i < fields.Length; i++) {
|
||||
Type fieldType = fields[i].FieldType;
|
||||
@ -31,6 +31,9 @@ public class NodeEditor {
|
||||
EditorGUILayout.LabelField(headerAttrib.header);
|
||||
}
|
||||
|
||||
//Skip if field has input or output attribute
|
||||
if (NodeEditorUtilities.HasAttrib<Node.InputAttribute>(fieldAttribs) || NodeEditorUtilities.HasAttrib<Node.OutputAttribute>(fieldAttribs)) continue;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (fieldType == typeof(int)) {
|
||||
fieldValue = EditorGUILayout.IntField(fieldName, (int)fieldValue);
|
||||
|
||||
@ -23,6 +23,15 @@ public static class NodeEditorUtilities {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool HasAttrib<T>(object[] attribs) where T : Attribute {
|
||||
for (int i = 0; i < attribs.Length; i++) {
|
||||
if (attribs[i].GetType() == typeof(T)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary> Return color based on type </summary>
|
||||
public static Color GetTypeColor(Type type) {
|
||||
UnityEngine.Random.InitState(type.Name.GetHashCode());
|
||||
|
||||
@ -14,18 +14,21 @@ public abstract class Node {
|
||||
[SerializeField] private string nodeType;
|
||||
|
||||
[SerializeField] public Rect position = new Rect(0,0,200,200);
|
||||
[SerializeField] protected NodePort[] inputs = new NodePort[0];
|
||||
[SerializeField] protected NodePort[] outputs = new NodePort[0];
|
||||
[SerializeField] private NodePort[] inputs = new NodePort[0];
|
||||
[SerializeField] private NodePort[] outputs = new NodePort[0];
|
||||
|
||||
public int InputCount { get { return inputs.Length; } }
|
||||
public int OutputCount { get { return outputs.Length; } }
|
||||
|
||||
protected Node() {
|
||||
nodeType = GetType().ToString();
|
||||
CachePorts();
|
||||
Init();
|
||||
}
|
||||
|
||||
protected abstract void Init();
|
||||
protected virtual void Init() {
|
||||
|
||||
}
|
||||
|
||||
public int GetInputId(NodePort input) {
|
||||
for (int i = 0; i < inputs.Length; i++) {
|
||||
@ -75,4 +78,40 @@ public abstract class Node {
|
||||
public override int GetHashCode() {
|
||||
return JsonUtility.ToJson(this).GetHashCode();
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
|
||||
public class InputAttribute : Attribute {
|
||||
public InputAttribute() {
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
|
||||
public class OutputAttribute : Attribute {
|
||||
public OutputAttribute() {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Use reflection to find all fields with <see cref="InputAttribute"/> or <see cref="OutputAttribute"/>, and write to <see cref="inputs"/> and <see cref="outputs"/> </summary>
|
||||
private void CachePorts() {
|
||||
List<NodePort> inputPorts = new List<NodePort>();
|
||||
List<NodePort> outputPorts = new List<NodePort>();
|
||||
|
||||
System.Reflection.FieldInfo[] fieldInfo = GetType().GetFields();
|
||||
for (int i = 0; i < fieldInfo.Length; i++) {
|
||||
//Get InputAttribute and OutputAttribute
|
||||
object[] attribs = fieldInfo[i].GetCustomAttributes(false);
|
||||
InputAttribute inputAttrib = null;
|
||||
OutputAttribute outputAttrib = null;
|
||||
for (int k = 0; k < attribs.Length; k++) {
|
||||
if (attribs[k] is InputAttribute) inputAttrib = attribs[k] as InputAttribute;
|
||||
else if (attribs[k] is OutputAttribute) outputAttrib = attribs[k] as OutputAttribute;
|
||||
}
|
||||
if (inputAttrib != null && outputAttrib != null) Debug.LogError("Field " + fieldInfo + " cannot be both input and output.");
|
||||
else if (inputAttrib != null) inputPorts.Add(new NodePort(fieldInfo[i].Name, fieldInfo[i].FieldType, this, NodePort.IO.Input));
|
||||
else if (outputAttrib != null) outputPorts.Add(new NodePort(fieldInfo[i].Name, fieldInfo[i].FieldType, this, NodePort.IO.Output));
|
||||
}
|
||||
|
||||
inputs = inputPorts.ToArray();
|
||||
outputs = outputPorts.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user