From 6a4c29410ae63c64b2ab5286b30cc14c6dd1471f Mon Sep 17 00:00:00 2001 From: Thor Brigsted Date: Sun, 8 Oct 2017 02:00:33 +0200 Subject: [PATCH] Added VerifyConnections, Added GetPortByFieldName. --- Examples/NodeToy/NodeGraphExample.asset | Bin 8116 -> 7592 bytes Scripts/Node.cs | 45 ++++++++++++++++++----- Scripts/NodeGraph.cs | 8 ++++ Scripts/NodePort.cs | 47 ++++++++++++++++-------- 4 files changed, 76 insertions(+), 24 deletions(-) diff --git a/Examples/NodeToy/NodeGraphExample.asset b/Examples/NodeToy/NodeGraphExample.asset index c44ea50b8e5dac10bd72dce71b534d6e70a08b7e..7fa3bace72d9f021ca63eb99cd339a2358978119 100644 GIT binary patch literal 7592 zcmeI0Yiv|S6vxkPw=MWaK|lq|LyMx7f{M?wJmpOVA1ET-c5mCo?cKV)U~7V2K4{>J z7?oHPO?=1renpMML~TF#_@L1cH7YSiV>D5N?+=yaJ+mh3rAkV^L>&PQ~zg=s6Mf5%Dvl=jIBD24X!`R(o4dwZ&~cH3|3R zOz7Dh>){x4)iZZKBQ0+0IV9np+>3dxhaS%FQ0jmpV~1tnd@sJUnSTey{U#pwaBwCM z7P04lgkqZ8;~trCPZnd`$DoJyKZ-n3?Y#!rlR}O)7cWg-sq`O@KAg|drv+XY2)J)o^tGY0=RzPl-Ty15c8&{uz113Y%VMm7xsjH(48v;jncVcQ7-Q(z+-A_zAuHxBkUsCytxOt^a>@E~X6K|wv-u+&pa7?G#cfwmG= z@<|D=at@ry;QBzTb`G>D{U;~f)n7-BuIiIr$BXZZT=#QGaesvBxQmJ2^OBm^K`A2E|iouKK?z*23T<(1@AXnnP z?}Z6>{ffR_PXC;QyMC1>M=JFzm@L-g`qeygq*A|{ubAexUoA+u>sJe@BvS1izgooh zX>!-ExbL+cT)$eJaM!PvfS0qwQnpW1murV*6Pnp*|0-8{9JoS zC=4B%3dK-zLD#0RTY^ldF9h=oL4Y2JKBP4%x&a465NXT#`Rq#e+F%v^Ak&ifv$7$Z znE)mZNHza20qR$ie9A@aE&lC6C z4nr5s^|zfDP^W%gizM1t|0TfX^j}J@#MOUU!u8eumAHO6aviGaaR*T4xNFIyeaF25 zxZJo`k}Gk?U6*iAFo)92N6xO8AK}&zJD} zn0F@JlP}@tjo`d82N023jG@=de99=4@H0^7e7Z{byjcIWF+b36djFLWUEKxZfSu8Q zYbKO6g-(A>Sj+|OAbCXW?TF(uk_mF1vdr&oEAk2u=J2yQli%dyKCvcWKxmJ!Ul+nm z(C!D}3SJuU6|?9s3EFZ&F6?Ek&>dRU)rBy_JHx7C)-TFtzZD-ds%Xpfk54F*@@HFI znzn9E`iF@-J=VW~!1nUeZ^d(;dt;~9g~~Wc1z1mZ%wf-bbEmfr71QpAN3XB#Z|(EC zDu>#ksC0bR`xHvLuPO7HU6zfvZ*Qqz{``U$r<}K^dC{>avw_IuBfh+U??YP_-Bh)H z@}#+~w`n@FZRhA)KIvQf(xke#e(oIes-~*Lzxm<&F)=rD;UUAD+(pGqSI5GhOlMb~ zds8_lbMx*j8+);A-k)V-GnNk|nR(E*W**!OD{!e}|J2Q2_4n7VdR=7kd6Qy+h{{rH^k`({| literal 8116 zcmeI1TWlT09mfA_pV$cmO50p$0wFhWAjHHDPMkoTgL5Gv2{D*UAOw5uv$juqe2#m( zHg-^8^H4;2fGRYqTd7iL(>}D2a+4C&m!N<|3lc&o0t7?|DKC*w3l(Z!ApO3%Y<8AI z2&k1>>5M#QW_~;S&Fw$4Gh>li4~kszqKJH7WY*6SO7qgD6^%`eO?^%B<(V^Qyjrj_ zABf!d#jKgdz1fE!eQjR%;{NR)?s;f*|0jRha{B7})lY11nCPB^JgeY6_a>NR33V z7@bLp{7Id<1W)SJ$J~?ap)+c9SjJ82nOmPJ37*usAm*MNKs|RthxNOV8W6Jmuo;}~ zVw-LK2T<-QQ|?9JbRK#nS^tX_(>z)3_hRnJMwI&}=&=7UA&*pkuL=E0PmVDcFH2sl z^k?H8*5?Q0%Gb(m$h!-k=^w^i>n}6<)5xQU^>p;7lV{0YeU2wyRXnLbGv=NgM_m>n z&3aynkS?wNBaOeJKP$l-5oi6`$FpOear*NzaNXXFB>VGn!#g^{@{Q|r`LI-8KNbeX z;e4ssCWBoY@`Yg2Iz&4BZ~&2FDHjZj%DwPb#M|`5@#N)gWB-ay9Qs|`o=YD(eDL)h z2YkGI46qZ=YfT;l$yjPfQ$n3X@<7 z7$^AIiBqHab%vjvIGSUjQ2EbJ9L=$?E6#~S$MI@Icr!dFEGG`;H>kTH%!#?XAaEh4 z<3d3lPFU*9C5*^3ax0=c;mPMA)O?b&;LMMCowJ}VAcym$PU%?vg@h4#z2p%cf#*VT zB|M#n&&vtqupgkS6w^GpP&CB6UM;-4k!C$P4qAV*Q_riJKTDk{PCc(7SAL4K@Gg#d zM(OWGn)=rwtke%2XRYt{0~bTBU+3s^{59A5k04F`r3fqO(=ICMHMx7A)_)9X z>R*qrl70*GXQ}1Ze>u7Gu0HM2*8c!L9Nfq--3reyH|>Yx_$wqc@GHsTtlb_&ob}=6 zMc2o*+Z$r;+Ub_Cx=Vh?OMe& zPulIen7ekno+6RT@7V1I=FgJ5cFTFM``@+OjWKuab`yA|ez=ACv($3?VKce%?znG> zxofvu!7J%=EGp@5i*;Q6j+nc4i%m;K{o9#8`_=k)k}L1(-x2eS+9+DPy%W5W-QGnG zN4tFrHFz5F4E)`MaF!oJoP0YWoaN6VPJRy|969I3VZ_PrC4@WQ4Np1f4P{Km<$-)I z9FTz^-#-uvw>}-Eawz%Y&`5|45#no0#Ue6e<0QRt)ZHs__asBei=C7|oa>XWd``NG z{$L)HiROf>A; zbLiuyd;1Umec{Z#o0>aU-}OfL>Wp?S(^-rQho-vi(&lgg%V+hx;x6;wbY7`$yD)(w z+K;Ah#5e6y_lt|o{Uxpg%>8JsbKLncd6sq3 z$47fVS|Eq70sjCY-j8?(I%v2jlhpS7B+_hGF~v_AUP|$Q7(SHZrw#u}f^*yMp%TD2U48Z2&~Uoinkg4 zal`+gju+|-V-6cUy7c;?be0B#&aj*>_Jb7A{rxzD_~IAygR(go?<@1n66WzU>K8@= zoP#GH}KUIRm7DLntVGM1Y@^|@2O^o}5L znaTIrA9v3^);r<7TPw1~?xd^G-NRRZ6&aXw4NW!IBG>uKEb;=02NR-NeHFyks_ z5Sf4R$=`nZ`#l?eI%((pc{la$)3mv7|Fp+Hn7HN0yoSGhJ~;iTrs{?B`9bxRV`%HZ zg@q^2o6G*t!1^(NaHzobL>VMQ+h)dXKQV6G&A9C=#?QyudL;XW6JRS2qWb;!kBPk6 zF0yegJ@Z*thscta<;z=r-Ny)2U)$#l<2*h38G<+u%eLj)He3LCV+xb`GTbpYNr|=|5>p)Mp*(&S_6F xtzDwVxR3Y_^V6Nnp6s00ZNR)s*qUv#dX}&gYNqGZ*V!TS(rJCn!T*x2{TsY8>q7tl diff --git a/Scripts/Node.cs b/Scripts/Node.cs index d563231..1963d3b 100644 --- a/Scripts/Node.cs +++ b/Scripts/Node.cs @@ -26,6 +26,40 @@ public abstract class Node : ScriptableObject { Init(); } + + /// Checks all connections for invalid references, and removes them. + public void VerifyConnections() { + for (int i = 0; i < InputCount; i++) { + inputs[i].VerifyConnections(); + } + for (int i = 0; i < OutputCount; i++) { + outputs[i].VerifyConnections(); + } + } + + /// Returns input or output port which matches fieldName + public NodePort GetPortByFieldName(string fieldName) { + NodePort port = GetOutputByFieldName(fieldName); + if (port != null) return port; + else return GetInputByFieldName(fieldName); + } + + /// Returns output port which matches fieldName + public NodePort GetOutputByFieldName(string fieldName) { + for (int i = 0; i < OutputCount; i++) { + if (outputs[i].fieldName == fieldName) return outputs[i]; + } + return null; + } + + /// Returns input port which matches fieldName + public NodePort GetInputByFieldName(string fieldName) { + for (int i = 0; i < InputCount; i++) { + if (inputs[i].fieldName == fieldName) return inputs[i]; + } + return null; + } + /// Initialize node. Called on creation. protected virtual void Init() { name = GetType().Name; } @@ -48,13 +82,6 @@ public abstract class Node : ScriptableObject { return -1; } - public NodePort CreateNodeInput(string name, Type type) { - return new NodePort(name, type, this, NodePort.IO.Input); - } - public NodePort CreateNodeOutput(string name, Type type) { - return new NodePort(name, type, this, NodePort.IO.Output); - } - public void ClearConnections() { for (int i = 0; i < inputs.Count; i++) { inputs[i].ClearConnections(); @@ -96,8 +123,8 @@ public abstract class Node : ScriptableObject { 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)); + else if (inputAttrib != null) inputPorts.Add(new NodePort(fieldInfo[i], this)); + else if (outputAttrib != null) outputPorts.Add(new NodePort(fieldInfo[i], this)); } inputs = inputPorts; diff --git a/Scripts/NodeGraph.cs b/Scripts/NodeGraph.cs index d61ec99..9e3c7d8 100644 --- a/Scripts/NodeGraph.cs +++ b/Scripts/NodeGraph.cs @@ -44,6 +44,14 @@ public abstract class NodeGraph : ScriptableObject, ISerializationCallbackReceiv for (int i = 0; i < nodes.Count; i++) { nodes[i].graph = this; } + VerifyConnections(); + } + + /// Checks all connections for invalid references, and removes them. + public void VerifyConnections() { + for (int i = 0; i < nodes.Count; i++) { + nodes[i].VerifyConnections(); + } } } diff --git a/Scripts/NodePort.cs b/Scripts/NodePort.cs index c0df2bb..937c0d1 100644 --- a/Scripts/NodePort.cs +++ b/Scripts/NodePort.cs @@ -2,10 +2,11 @@ using System.Collections.Generic; using UnityEngine; using System; +using System.Reflection; [Serializable] public class NodePort { - public enum IO { Input, Output} + public enum IO { Input, Output } public int ConnectionCount { get { return connections.Count; } } /// Return the first connection @@ -18,24 +19,40 @@ public class NodePort { public bool IsOutput { get { return direction == IO.Output; } } public Node node { get; private set; } - public string name { get { return _name; } } + [SerializeField] public string name; public bool enabled { get { return _enabled; } set { _enabled = value; } } - public string id { get { return _id; } } + public string fieldName { get { return _fieldName; } } + [SerializeField] private List connections = new List(); - [SerializeField] private string asdf; - [SerializeField] private string _id; + [SerializeField] private string _fieldName; [SerializeField] public Type type; - [SerializeField] private string _name; [SerializeField] private bool _enabled = true; [SerializeField] private IO _direction; - public NodePort(string name, Type type, Node node, IO direction) { - _name = name; - this.type = type; + public NodePort(FieldInfo fieldInfo, Node node) { + _fieldName = fieldInfo.Name; + name = _fieldName; + type = fieldInfo.FieldType; this.node = node; - _direction = direction; - _id = node.GetInstanceID() + _name; + + var attribs = fieldInfo.GetCustomAttributes(false); + for (int i = 0; i < attribs.Length; i++) { + if (attribs[i] is Node.InputAttribute) _direction = IO.Input; + else if (attribs[i] is Node.InputAttribute) _direction = IO.Output; + } + } + + /// Checks all connections for invalid references, and removes them. + public void VerifyConnections() { + for (int i = 0; i < connections.Count; i++) { + if (connections[i].node != null && + !string.IsNullOrEmpty(connections[i].fieldName) && + connections[i].node.GetPortByFieldName(connections[i].fieldName) != null) + continue; + Debug.LogWarning("Removed invalid connection"); + connections.RemoveAt(i); + } } /// Connect this to another @@ -86,22 +103,22 @@ public class NodePort { [Serializable] public class PortConnection { [SerializeField] public Node node; - [SerializeField] public string portID; + [SerializeField] public string fieldName; public NodePort Port { get { return port != null ? port : port = GetPort(); } } [NonSerialized] private NodePort port; public PortConnection(NodePort port) { this.port = port; node = port.node; - portID = port.id; + fieldName = port.fieldName; } private NodePort GetPort() { for (int i = 0; i < node.OutputCount; i++) { - if (node.outputs[i].id == portID) return node.outputs[i]; + if (node.outputs[i].fieldName == fieldName) return node.outputs[i]; } for (int i = 0; i < node.InputCount; i++) { - if (node.inputs[i].id == portID) return node.inputs[i]; + if (node.inputs[i].fieldName == fieldName) return node.inputs[i]; } return null; }