Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Commit

Permalink
#74 Property-based Node and new ConnectionPort system
Browse files Browse the repository at this point in the history
- Node is now defined through properties rather than with the Create function (see nodes), fixing #72
- Create has been replaced by the optional Init function
- New ConnectionPort/ConnectionKnob/ValueConnectionKnob level-hierarchy for node connection ports:
    - ConnectionPort: Basic connection between nodes, straight line
    - ConnectionKnob: A Knob on the node that can connect to other knobs on other nodes through connections
    - ValueConnectionKnob: A Value-Knob defined by a type and designed to pass values to it's connections
- ConnectionPorts are now defined through Attributes right on variables in the Node definitions (see nodes)
- ConnectionPorts of all levels have preset-styling similar to ConnectionTypes previously, each with different settings
- Inputs/Outputs are now weakly-typed, maximum connection counts are seperately specified
    - Currently not possible to edit Multi-Multi connection knobs due to interfacing, but structurally it's finally possible
  • Loading branch information
Seneral committed Jul 2, 2017
1 parent dff7d93 commit dc85da4
Show file tree
Hide file tree
Showing 47 changed files with 2,067 additions and 1,850 deletions.
12 changes: 5 additions & 7 deletions Editor/Node_Editor/NodeEditorWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ private void OnEnable()
canvasCache.SetupCacheEvents();
if (canvasCache.nodeCanvas.GetType () == typeof(NodeCanvas))
ShowNotification(new GUIContent("The Canvas has no specific type. Please use the convert button to assign a type and re-save the canvas!"));
canvasCache.nodeCanvas.Validate (false);
canvasCache.nodeCanvas.Validate ();
}

private void NormalReInit()
{
NodeEditor.ReInit(false);
canvasCache.nodeCanvas.Validate (false);
canvasCache.nodeCanvas.Validate ();
}

private void OnDestroy()
Expand Down Expand Up @@ -221,9 +221,7 @@ private void DrawToolbarGUI()
GenericMenu menu = new GenericMenu();

// Canvas creation
foreach (System.Collections.Generic.KeyValuePair<Type, NodeCanvasTypeData> data in NodeCanvasManager.CanvasTypes)
menu.AddItem(new GUIContent("New Canvas/" + data.Value.DisplayString), false, CreateCanvasCallback, data.Key);
// menu.AddItem(new GUIContent("New Standard Canvas"), false, CreateCanvasCallback, null);
NodeCanvasManager.FillCanvasTypeMenu(ref menu, CreateCanvas, "New Canvas/");
menu.AddSeparator("");

// Scene Saving
Expand Down Expand Up @@ -378,9 +376,9 @@ private void DrawSideWindow()

#region Menu Callbacks

private void CreateCanvasCallback(object userdata)
private void CreateCanvas(Type type)
{
editor.canvasCache.NewNodeCanvas((Type)userdata);
editor.canvasCache.NewNodeCanvas(type);
}

private void LoadCanvas()
Expand Down
13 changes: 7 additions & 6 deletions Editor/Node_Editor/RTCanvasCalculatorEditor.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using NodeEditorFramework;

namespace NodeEditorFramework.Standard
Expand All @@ -26,19 +27,19 @@ public override void OnInspectorGUI ()
if (GUILayout.Button ("Calculate and debug Output"))
RTCalc.CalculateCanvas ();

if (inputNodes == null)
inputNodes = RTCalc.getInputNodes ();
DisplayInputValues ();
}

private void DisplayInputValues ()
{
if (inputNodes == null)
inputNodes = RTCalc.getInputNodes ();
foreach (Node inputNode in inputNodes)
{
string outID = "(IN) " + inputNode.name + ": ";
foreach (NodeOutput output in inputNode.Outputs)
outID += output.typeID + " " + (output.IsValueNull? "NULL" : output.GetValue ().ToString ()) + "; ";
GUILayout.Label (outID);
string outValueLog = "(IN) " + inputNode.name + ": ";
foreach (ValueConnectionKnob knob in inputNode.outputKnobs.OfType<ValueConnectionKnob> ())
outValueLog += knob.styleID + " " + knob.name + " = " + (knob.IsValueNull? "NULL" : knob.GetValue ().ToString ()) + "; ";
GUILayout.Label (outValueLog);
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions Node_Editor/Default/CalculationCanvasType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ protected override void OnCreate ()

public void OnEnable ()
{
if (Traversal == null)
Traversal = new CanvasCalculator (this);
// Register to other callbacks, f.E.:
//NodeEditorCallbacks.OnDeleteNode += OnDeleteNode;
}
Expand Down
68 changes: 30 additions & 38 deletions Node_Editor/Default/CanvasCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,11 @@ public class CanvasCalculator : NodeCanvasTraversal
{
// A list of Nodes from which calculation originates -> Call StartCalculation
public List<Node> workList;
private int calculationCount;

private const int maxTriesOnSingleNode = 1000;

public CanvasCalculator (NodeCanvas canvas) : base(canvas)
{
}
public CanvasCalculator (NodeCanvas canvas) : base(canvas) {}

/// <summary>
/// Recalculate from every Input Node.
/// Usually does not need to be called at all, the smart calculation system is doing the job just fine
/// Recalculate from every node regarded as an input node
/// </summary>
public override void TraverseAll ()
{
Expand All @@ -36,8 +30,7 @@ public override void TraverseAll ()
}

/// <summary>
/// Recalculate from this node.
/// Usually does not need to be called manually
/// Recalculate from the specified node
/// </summary>
public override void OnChange (Node node)
{
Expand All @@ -47,58 +40,57 @@ public override void OnChange (Node node)
}

/// <summary>
/// Iterates through workList and calculates everything, including children
/// Iteratively calculates all nodes from the worklist, including child nodes, until no further calculation is possible
/// </summary>
private void StartCalculation ()
{
if (workList == null || workList.Count == 0)
return;
// this blocks iterates through the worklist and starts calculating
// if a node returns false, it stops and adds the node to the worklist
// this workList is worked on until it's empty or a limit is reached
calculationCount = 0;

bool limitReached = false;
for (int roundCnt = 0; !limitReached; roundCnt++)
{ // Runs until every node possible is calculated
while (!limitReached)
{ // Runs until the whole workList is calculated thoroughly or no further calculation is possible
limitReached = true;
for (int workCnt = 0; workCnt < workList.Count; workCnt++)
{
{ // Iteratively check workList
if (ContinueCalculation (workList[workCnt]))
limitReached = false;
}
if (roundCnt > maxTriesOnSingleNode)
limitReached = true;
}
if (workList.Count > 0)
{
Debug.LogError("Did not complete calculation! " + workList.Count + " nodes block calculation from advancing!");
foreach (Node node in workList)
Debug.LogError("" + node.name + " blocks calculation!");
}
}

/// <summary>
/// Recursive function which continues calculation on this node and all the child nodes
/// Usually does not need to be called manually
/// Returns success/failure of this node only
/// Recursively calculates this node and it's children
/// All nodes that could not be calculated in the current state are added to the workList for later calculation
/// Returns whether calculation could advance at all
/// </summary>
private bool ContinueCalculation (Node node)
{
if (node.calculated)
return false;
if ((node.descendantsCalculated () || node.isInLoop ()) && node.Calculate ())
{ // finished Calculating, continue with the children
if (node.calculated && !node.AllowRecursion)
{ // Already calulated
workList.Remove (node);
return true;
}
if (node.descendantsCalculated () && node.Calculate ())
{ // Calculation was successful
node.calculated = true;
calculationCount++;
workList.Remove (node);
if (node.ContinueCalculation && calculationCount < 1000)
{
foreach (NodeOutput output in node.Outputs)
{
foreach (NodeInput connection in output.connections)
ContinueCalculation (connection.body);
}
if (node.ContinueCalculation)
{ // Continue with children
foreach (ConnectionPort outputPort in node.outputPorts)
foreach (ConnectionPort connectionPort in outputPort.connections)
ContinueCalculation (connectionPort.body);
}
else if (calculationCount >= 1000)
Debug.LogError ("Stopped calculation because of suspected Recursion. Maximum calculation iteration is currently at 1000!");
return true;
}
else if (!workList.Contains (node))
{ // failed to calculate, add it to check later
{ // Calculation failed, record to calculate later on
workList.Add (node);
}
return false;
Expand Down
10 changes: 4 additions & 6 deletions Node_Editor/Default/FloatCalculation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@

namespace NodeEditorFramework.Standard
{
public class FloatType : IConnectionTypeDeclaration
public class FloatConnectionType : ValueConnectionType
{
public string Identifier { get { return "Float"; } }
public Type Type { get { return typeof(float); } }
public Color Color { get { return Color.cyan; } }
public string InKnobTex { get { return "Textures/In_Knob.png"; } }
public string OutKnobTex { get { return "Textures/Out_Knob.png"; } }
public override string Identifier { get { return "Float"; } }
public override Color Color { get { return Color.cyan; } }
public override Type Type { get { return typeof(float); } }
}
}
26 changes: 10 additions & 16 deletions Node_Editor/Default/Runtime Examples/RTCanvasCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void CalculateCanvas ()
{
AssureCanvas ();
NodeEditor.checkInit (false);
canvas.Validate (true);
canvas.Validate ();
canvas.TraverseAll ();
DebugOutputResults ();
}
Expand All @@ -44,19 +44,13 @@ private void DebugOutputResults ()
Debug.Log ("Calculating '" + canvas.saveName + "':");
List<Node> outputNodes = getOutputNodes ();
foreach (Node outputNode in outputNodes)
{
string outID = "(OUT) " + outputNode.name + ": ";
if (outputNode.Outputs.Count == 0)
{ // If the node has no outputs, display it's inputs, because that's what the output node works with
foreach (NodeInput input in outputNode.Inputs)
outID += input.typeID + " " + (input.IsValueNull? "NULL" : input.GetValue ().ToString ()) + "; ";
}
else
{ // Else display the final output of the output node
foreach (NodeOutput output in outputNode.Outputs)
outID += output.typeID + " " + (output.IsValueNull? "NULL" : output.GetValue ().ToString ()) + "; ";
}
Debug.Log (outID);
{ // Display value of all output nodes
string outValueLog = "(OUT) " + outputNode.name + ": ";
// Use knob values - either output knobs, or input knobs if there are now output knobs
List<ConnectionKnob> sourceValueKnobs = outputNode.outputKnobs.Count == 0? outputNode.inputKnobs : outputNode.outputKnobs;
foreach (ValueConnectionKnob knob in sourceValueKnobs.OfType<ValueConnectionKnob> ())
outValueLog += knob.styleID + " " + knob.name + " = " + (knob.IsValueNull? "NULL" : knob.GetValue ().ToString ()) + "; ";
Debug.Log (outValueLog);
}
}

Expand All @@ -66,7 +60,7 @@ private void DebugOutputResults ()
public List<Node> getInputNodes ()
{
AssureCanvas ();
return canvas.nodes.Where ((Node node) => (node.Inputs.Count == 0 && node.Outputs.Count != 0) || node.Inputs.TrueForAll ((NodeInput input) => input.connection == null)).ToList ();
return canvas.nodes.Where ((Node node) => node.isInput ()).ToList ();
}

/// <summary>
Expand All @@ -75,7 +69,7 @@ public List<Node> getInputNodes ()
public List<Node> getOutputNodes ()
{
AssureCanvas ();
return canvas.nodes.Where ((Node node) => (node.Outputs.Count == 0 && node.Inputs.Count != 0) || node.Outputs.TrueForAll ((NodeOutput output) => output.connections.Count == 0)).ToList ();
return canvas.nodes.Where ((Node node) => node.isOutput ()).ToList ();
}
}
}
Loading

0 comments on commit dc85da4

Please sign in to comment.