Skip to content

Commit 35319c7

Browse files
authored
Merge branch 'customize-edgeview' into customize-edgeview
2 parents b804c94 + e017b1d commit 35319c7

File tree

75 files changed

+4769
-497
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+4769
-497
lines changed

.vsconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"version": "1.0",
3+
"components": [
4+
"Microsoft.VisualStudio.Workload.ManagedGame"
5+
]
6+
}

Assets/Examples/BasicExample.asset

Lines changed: 553 additions & 71 deletions
Large diffs are not rendered by default.

Assets/Examples/ConditionalGraph/ConditionalNode.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,28 @@ public override IEnumerable< ConditionalNode > GetExecutedNodes()
4545
.GetEdges().Select(e => e.inputNode as ConditionalNode);
4646
}
4747
}
48+
49+
[System.Serializable]
50+
/// <summary>
51+
/// This class represent a waitable node which invokes another node after a time/frame
52+
/// </summary>
53+
public abstract class WaitableNode : LinearConditionalNode
54+
{
55+
[Output(name = "Execute After")]
56+
public ConditionalLink executeAfter;
57+
58+
protected void ProcessFinished()
59+
{
60+
onProcessFinished.Invoke(this);
61+
}
62+
63+
[HideInInspector]
64+
public Action<WaitableNode> onProcessFinished;
65+
66+
public IEnumerable< ConditionalNode > GetExecuteAfterNodes()
67+
{
68+
return outputPorts.FirstOrDefault(n => n.fieldName == nameof(executeAfter))
69+
.GetEdges().Select(e => e.inputNode as ConditionalNode);
70+
}
71+
}
4872
}

Assets/Examples/ConditionalGraph/ConditionalProcessor.cs

Lines changed: 119 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,31 @@ public override void UpdateComputeOrder()
4343

4444
public override void Run()
4545
{
46-
// Execute the whole graph:
47-
var enumerator = RunConditionalGraph();
46+
IEnumerator<BaseNode> enumerator;
4847

49-
while (enumerator.MoveNext())
48+
if(startNodeList.Count == 0)
49+
{
50+
enumerator = RunTheGraph();
51+
}
52+
else
53+
{
54+
Stack<BaseNode> nodeToExecute = new Stack<BaseNode>();
55+
// Add all the start nodes to the execution stack
56+
startNodeList.ForEach(s => nodeToExecute.Push(s));
57+
// Execute the whole graph:
58+
enumerator = RunTheGraph(nodeToExecute);
59+
}
60+
61+
while(enumerator.MoveNext())
62+
;
63+
}
64+
65+
private void WaitedRun(Stack<BaseNode> nodesToRun)
66+
{
67+
// Execute the waitable node:
68+
var enumerator = RunTheGraph(nodesToRun);
69+
70+
while(enumerator.MoveNext())
5071
;
5172
}
5273

@@ -67,96 +88,110 @@ IEnumerable<BaseNode> GatherNonConditionalDependencies(BaseNode node)
6788
yield return dependency;
6889
}
6990
}
70-
71-
public IEnumerator<BaseNode> RunConditionalGraph()
91+
92+
private IEnumerator<BaseNode> RunTheGraph()
7293
{
73-
if (startNodeList.Count == 0)
74-
{
75-
int count = processList.Count;
94+
int count = processList.Count;
7695

77-
for (int i = 0; i < count; i++)
78-
{
79-
processList[i].OnProcess();
80-
yield return processList[i];
81-
}
82-
}
83-
else // Conditional graph execution:
96+
for(int i = 0; i < count; i++)
8497
{
85-
Stack<BaseNode> nodeToExecute = new Stack<BaseNode>();
86-
HashSet<BaseNode> nodeDependenciesGathered = new HashSet<BaseNode>();
87-
HashSet<BaseNode> skipConditionalHandling = new HashSet<BaseNode>();
88-
89-
// Add all the start nodes to the execution stack
90-
startNodeList.ForEach(s => nodeToExecute.Push(s));
91-
92-
while (nodeToExecute.Count > 0)
93-
{
94-
var node = nodeToExecute.Pop();
95-
// TODO: maxExecutionTimeMS
96-
97-
// In case the node is conditional, then we need to execute it's non-conditional dependencies first
98-
if (node is IConditionalNode && !skipConditionalHandling.Contains(node))
99-
{
100-
// Gather non-conditional deps: TODO, move to the cache:
101-
if (nodeDependenciesGathered.Contains(node))
102-
{
103-
// Execute the conditional node:
104-
node.OnProcess();
105-
yield return node;
106-
107-
// And select the next nodes to execute:
108-
switch (node)
109-
{
110-
// special code path for the loop node as it will execute multiple times the same nodes
111-
case ForLoopNode forLoopNode:
112-
forLoopNode.index = forLoopNode.start - 1; // Initialize the start index
113-
foreach (var n in forLoopNode.GetExecutedNodesLoopCompleted())
114-
nodeToExecute.Push(n);
115-
for (int i = forLoopNode.start; i < forLoopNode.end; i++)
116-
{
117-
foreach (var n in forLoopNode.GetExecutedNodesLoopBody())
118-
nodeToExecute.Push(n);
119-
120-
nodeToExecute.Push(node); // Increment the counter
121-
}
122-
skipConditionalHandling.Add(node);
123-
break;
124-
case IConditionalNode cNode:
125-
foreach (var n in cNode.GetExecutedNodes())
126-
nodeToExecute.Push(n);
127-
break;
128-
default:
129-
Debug.LogError($"Conditional node {node} not handled");
130-
break;
131-
}
132-
nodeDependenciesGathered.Remove(node);
133-
}
134-
else
135-
{
136-
nodeToExecute.Push(node);
137-
nodeDependenciesGathered.Add(node);
138-
foreach (var nonConditionalNode in GatherNonConditionalDependencies(node))
139-
{
140-
nodeToExecute.Push(nonConditionalNode);
141-
}
142-
}
143-
}
144-
else
145-
{
146-
node.OnProcess();
147-
yield return node;
148-
}
149-
}
98+
processList[i].OnProcess();
99+
yield return processList[i];
150100
}
151101
}
152-
153-
// Advance the execution of the graph of one node, mostly for debug
102+
103+
private IEnumerator<BaseNode> RunTheGraph(Stack<BaseNode> nodeToExecute)
104+
{
105+
HashSet<BaseNode> nodeDependenciesGathered = new HashSet<BaseNode>();
106+
HashSet<BaseNode> skipConditionalHandling = new HashSet<BaseNode>();
107+
108+
while(nodeToExecute.Count > 0)
109+
{
110+
var node = nodeToExecute.Pop();
111+
// TODO: maxExecutionTimeMS
112+
113+
// In case the node is conditional, then we need to execute it's non-conditional dependencies first
114+
if(node is IConditionalNode && !skipConditionalHandling.Contains(node))
115+
{
116+
// Gather non-conditional deps: TODO, move to the cache:
117+
if(nodeDependenciesGathered.Contains(node))
118+
{
119+
// Execute the conditional node:
120+
node.OnProcess();
121+
yield return node;
122+
123+
// And select the next nodes to execute:
124+
switch(node)
125+
{
126+
// special code path for the loop node as it will execute multiple times the same nodes
127+
case ForLoopNode forLoopNode:
128+
forLoopNode.index = forLoopNode.start - 1; // Initialize the start index
129+
foreach(var n in forLoopNode.GetExecutedNodesLoopCompleted())
130+
nodeToExecute.Push(n);
131+
for(int i = forLoopNode.start; i < forLoopNode.end; i++)
132+
{
133+
foreach(var n in forLoopNode.GetExecutedNodesLoopBody())
134+
nodeToExecute.Push(n);
135+
136+
nodeToExecute.Push(node); // Increment the counter
137+
}
138+
139+
skipConditionalHandling.Add(node);
140+
break;
141+
// another special case for waitable nodes, like "wait for a coroutine", wait x seconds", etc.
142+
case WaitableNode waitableNode:
143+
foreach(var n in waitableNode.GetExecutedNodes())
144+
nodeToExecute.Push(n);
145+
146+
waitableNode.onProcessFinished += (waitedNode) =>
147+
{
148+
Stack<BaseNode> waitedNodes = new Stack<BaseNode>();
149+
foreach(var n in waitedNode.GetExecuteAfterNodes())
150+
waitedNodes.Push(n);
151+
WaitedRun(waitedNodes);
152+
waitableNode.onProcessFinished = null;
153+
};
154+
break;
155+
case IConditionalNode cNode:
156+
foreach(var n in cNode.GetExecutedNodes())
157+
nodeToExecute.Push(n);
158+
break;
159+
default:
160+
Debug.LogError($"Conditional node {node} not handled");
161+
break;
162+
}
163+
164+
nodeDependenciesGathered.Remove(node);
165+
}
166+
else
167+
{
168+
nodeToExecute.Push(node);
169+
nodeDependenciesGathered.Add(node);
170+
foreach(var nonConditionalNode in GatherNonConditionalDependencies(node))
171+
{
172+
nodeToExecute.Push(nonConditionalNode);
173+
}
174+
}
175+
}
176+
else
177+
{
178+
node.OnProcess();
179+
yield return node;
180+
}
181+
}
182+
}
183+
184+
// Advance the execution of the graph of one node, mostly for debug. Doesn't work for WaitableNode's executeAfter port.
154185
public void Step()
155186
{
156187
if (currentGraphExecution == null)
157188
{
158-
currentGraphExecution = RunConditionalGraph();
159-
currentGraphExecution.MoveNext(); // Advance to the first node
189+
Stack<BaseNode> nodeToExecute = new Stack<BaseNode>();
190+
if(startNodeList.Count > 0)
191+
startNodeList.ForEach(s => nodeToExecute.Push(s));
192+
193+
currentGraphExecution = startNodeList.Count == 0 ? RunTheGraph() : RunTheGraph(nodeToExecute);
194+
currentGraphExecution.MoveNext(); // Advance to the first node
160195
}
161196
else
162197
if (!currentGraphExecution.MoveNext())

Assets/Examples/DefaultNodes/Nodes/ColorNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
public class ColorNode : BaseNode
99
{
1010
[Output(name = "Color"), SerializeField]
11-
public Color color;
11+
new public Color color;
1212

1313
public override string name => "Color";
1414
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using GraphProcessor;
3+
using UnityEngine;
4+
5+
namespace NodeGraphProcessor.Examples
6+
{
7+
[Serializable, NodeMenuItem("Debug/Console Log")]
8+
public class ConsoleNode : LinearConditionalNode
9+
{
10+
public override string name => "Console Log";
11+
12+
[Input("Object")]
13+
public object obj;
14+
15+
[Input("Log"), SerializeField, Tooltip("If Object is null, this will be the log.")]
16+
public string logText = "Log";
17+
18+
[Setting("Log Type")]
19+
public LogType logType = LogType.Log;
20+
21+
protected override void Process()
22+
{
23+
switch(logType)
24+
{
25+
case LogType.Error:
26+
case LogType.Exception:
27+
Debug.LogError(obj != null ? obj.ToString() : logText);
28+
break;
29+
case LogType.Assert:
30+
Debug.LogAssertion(obj != null ? obj.ToString() : logText);
31+
break;
32+
case LogType.Warning:
33+
Debug.LogWarning(obj != null ? obj.ToString() : logText);
34+
break;
35+
case LogType.Log:
36+
Debug.Log(obj != null ? obj.ToString() : logText);
37+
break;
38+
}
39+
}
40+
}
41+
}

Assets/Examples/DefaultNodes/Nodes/ConsoleLogNode.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Examples/DefaultNodes/Nodes/CustomPortDataNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class CustomPortData : BaseNode
1010
[Input(name = "In Values", allowMultiple = true)]
1111
public IEnumerable< object > inputs = null;
1212

13-
PortData[] portDatas = new PortData[] {
13+
static PortData[] portDatas = new PortData[] {
1414
new PortData{displayName = "0", displayType = typeof(float), identifier = "0"},
1515
new PortData{displayName = "1", displayType = typeof(int), identifier = "1"},
1616
new PortData{displayName = "2", displayType = typeof(GameObject), identifier = "2"},

Assets/Examples/DefaultNodes/Nodes/DrawerFieldTestNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class DrawerFieldTestNode : BaseNode
3030
public string stringInput;
3131

3232
[Input(name = "Color"), ShowAsDrawer]
33-
public Color color;
33+
new public Color color;
3434

3535
[Input(name = "Game Object"), ShowAsDrawer]
3636
public GameObject gameObject;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
using GraphProcessor;
5+
using System.Linq;
6+
7+
[System.Serializable, NodeMenuItem("Custom/FieldTestNode")]
8+
public class FieldTestNode : BaseNode
9+
{
10+
public string s;
11+
public int i;
12+
public float f;
13+
public Vector2 v2;
14+
public Vector3 v3;
15+
public Vector4 v4;
16+
public LayerMask layer;
17+
new public Color color;
18+
public Bounds bounds;
19+
public Rect rect;
20+
public CameraClearFlags flags = CameraClearFlags.Color;
21+
public bool toggle;
22+
public Gradient gradient;
23+
public AnimationCurve curve;
24+
25+
public override string name => "FieldTestNode";
26+
27+
protected override void Process() { }
28+
}

0 commit comments

Comments
 (0)