Skip to content

Commit a230aa0

Browse files
committed
feat: improve performance
1 parent f421152 commit a230aa0

9 files changed

Lines changed: 381 additions & 96 deletions

Editor/Scripts/GraphView/PlayableGraphView.cs

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using GBG.PlayableGraphMonitor.Editor.Node;
22
using System.Collections.Generic;
33
using UnityEditor.Experimental.GraphView;
4-
using UnityEditor.Playables;
54
using UnityEngine;
65
using UnityEngine.Playables;
76
using UnityEngine.UIElements;
@@ -13,7 +12,7 @@ public class PlayableGraphView : UGraphView
1312
{
1413
private PlayableGraph _playableGraph;
1514

16-
private readonly List<PlayableOutputNode> _playableOutputNodes = new List<PlayableOutputNode>();
15+
private readonly List<PlayableOutputNode> _rootOutputNodes = new List<PlayableOutputNode>();
1716

1817

1918
public PlayableGraphView()
@@ -29,29 +28,37 @@ public PlayableGraph GetPlayableGraph()
2928
return _playableGraph;
3029
}
3130

32-
public void SetPlayableGraph(PlayableGraph playableGraph)
31+
public void Update(PlayableGraph playableGraph)
3332
{
34-
//if (IsEqual(ref _playableGraph, ref playableGraph))
35-
//{
36-
// return;
37-
//}
33+
if (!_playableGraph.IsValid())
34+
{
35+
ClearView();
36+
}
3837

39-
_playableGraph = playableGraph;
38+
if (IsEqual(ref _playableGraph, ref playableGraph))
39+
{
40+
DiffOutputNodes();
41+
}
42+
else
43+
{
44+
// playable graph changed
45+
_playableGraph = playableGraph;
4046

41-
ClearView();
47+
PopulateView();
48+
}
4249

43-
PopulateView();
50+
CalculateLayout();
4451
}
4552

4653

4754
private void ClearView()
4855
{
49-
foreach (var playableOutputNode in _playableOutputNodes)
56+
foreach (var playableOutputNode in _rootOutputNodes)
5057
{
5158
playableOutputNode.RemoveFromContainer();
5259
}
5360

54-
_playableOutputNodes.Clear();
61+
_rootOutputNodes.Clear();
5562
}
5663

5764
private void PopulateView()
@@ -65,27 +72,85 @@ private void PopulateView()
6572
for (int i = 0; i < _playableGraph.GetOutputCount(); i++)
6673
{
6774
var playableOutput = _playableGraph.GetOutput(i);
68-
var playableOutputTypeName = playableOutput.GetPlayableOutputType().Name;
69-
var playableOutputEditorName = playableOutput.GetEditorName();
70-
var playableOutputNode = new PlayableOutputNode(0, playableOutput)
75+
var playableOutputNode = PlayableOutputNodeFactory.CreateNode(playableOutput);
76+
playableOutputNode.AddToContainer(this);
77+
78+
_rootOutputNodes.Add(playableOutputNode);
79+
}
80+
81+
for (int i = 0; i < _rootOutputNodes.Count; i++)
82+
{
83+
//_rootOutputNodes[i].CreateAndConnectInputNodes();
84+
_rootOutputNodes[i].Update();
85+
}
86+
}
87+
88+
private void DiffOutputNodes()
89+
{
90+
if (!_playableGraph.IsValid())
91+
{
92+
return;
93+
}
94+
95+
// mark all root nodes inactive
96+
for (int i = 0; i < _rootOutputNodes.Count; i++)
97+
{
98+
_rootOutputNodes[i].RemoveFlag(NodeFlag.Active);
99+
}
100+
101+
// diff nodes
102+
for (int i = 0; i < _playableGraph.GetOutputCount(); i++)
103+
{
104+
var playableOutput = _playableGraph.GetOutput(i);
105+
var rootOutputNodeIndex = FindRootOutputNode(playableOutput);
106+
if (rootOutputNodeIndex >= 0)
71107
{
72-
title = $"{playableOutputTypeName} ({playableOutputEditorName})"
73-
};
108+
_rootOutputNodes[i].AddFlag(NodeFlag.Active);
109+
continue;
110+
}
111+
112+
// create new node
113+
var playableOutputNode = PlayableOutputNodeFactory.CreateNode(playableOutput);
74114
playableOutputNode.AddToContainer(this);
115+
playableOutputNode.AddFlag(NodeFlag.Active);
116+
117+
_rootOutputNodes.Add(playableOutputNode);
118+
}
75119

76-
_playableOutputNodes.Add(playableOutputNode);
120+
for (int i = _rootOutputNodes.Count - 1; i >= 0; i--)
121+
{
122+
var rootOutputNode = _rootOutputNodes[i];
123+
if (!rootOutputNode.CheckFlag(NodeFlag.Active))
124+
{
125+
rootOutputNode.RemoveFromContainer();
126+
127+
_rootOutputNodes.RemoveAt(i);
128+
continue;
129+
}
130+
131+
rootOutputNode.Update();
77132
}
133+
}
78134

79-
for (int i = 0; i < _playableOutputNodes.Count; i++)
135+
private int FindRootOutputNode(PlayableOutput playableOutput)
136+
{
137+
for (int i = 0; i < _rootOutputNodes.Count; i++)
80138
{
81-
_playableOutputNodes[i].CreateAndConnectInputNodes();
139+
if (_rootOutputNodes[i].PlayableOutput.Equals(playableOutput))
140+
{
141+
return i;
142+
}
82143
}
83144

84-
// calculate node layout
145+
return -1;
146+
}
147+
148+
private void CalculateLayout()
149+
{
85150
var origin = Vector2.zero;
86-
for (int i = 0; i < _playableOutputNodes.Count; i++)
151+
for (int i = 0; i < _rootOutputNodes.Count; i++)
87152
{
88-
var outputNode = _playableOutputNodes[i];
153+
var outputNode = _rootOutputNodes[i];
89154
var treeSize = outputNode.GetHierarchySize();
90155

91156
outputNode.CalculateLayout(origin);
Lines changed: 80 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,35 @@
11
using System.Collections.Generic;
22
using UnityEditor.Experimental.GraphView;
33
using UnityEngine;
4+
using UEdge = UnityEditor.Experimental.GraphView.Edge;
45
using UGraphView = UnityEditor.Experimental.GraphView.GraphView;
56
using UNode = UnityEditor.Experimental.GraphView.Node;
67

78
namespace GBG.PlayableGraphMonitor.Editor.Node
89
{
9-
public abstract class GraphViewNode : UNode
10+
public enum NodeFlag : uint
11+
{
12+
None = 0,
13+
Active = 1 << 0,
14+
Dirty = 1 << 1,
15+
}
16+
17+
public readonly struct NodeInput
1018
{
11-
public int Depth { get; }
19+
public UEdge Edge { get; }
1220

21+
public GraphViewNode Node { get; }
22+
23+
24+
public NodeInput(UEdge edge, GraphViewNode node)
25+
{
26+
Edge = edge;
27+
Node = node;
28+
}
29+
}
30+
31+
public abstract class GraphViewNode : UNode
32+
{
1333
public IReadOnlyList<Port> InputPorts => InternalInputPorts;
1434

1535
protected List<Port> InternalInputPorts { get; } = new List<Port>();
@@ -18,30 +38,57 @@ public abstract class GraphViewNode : UNode
1838

1939
protected List<Port> InternalOutputPorts { get; } = new List<Port>();
2040

21-
// public IReadOnlyList<Edge> InputEdges => InternalInputEdges;
41+
protected UGraphView Container { get; set; }
2242

23-
protected List<Edge> InternalInputEdges { get; } = new List<Edge>();
43+
public IReadOnlyList<NodeInput> Inputs => InternalInputs;
2444

25-
protected UGraphView Container { get; set; }
45+
protected List<NodeInput> InternalInputs { get; } = new List<NodeInput>();
2646

2747
protected GraphViewNode Parent { get; private set; }
2848

29-
protected new List<GraphViewNode> Children { get; } = new List<GraphViewNode>();
3049

50+
public virtual void Update() { }
3151

32-
private Vector2? _hierarchySize;
3352

53+
#region Hierarchy
3454

35-
protected GraphViewNode(int depth)
55+
public virtual void AddToContainer(UGraphView container)
56+
{
57+
Container = container;
58+
Container.AddElement(this);
59+
}
60+
61+
public virtual void RemoveFromContainer()
3662
{
37-
Depth = depth;
63+
// self
64+
Container.RemoveElement(this);
65+
66+
// children
67+
for (int i = 0; i < InternalInputs.Count; i++)
68+
{
69+
var input = InternalInputs[i];
70+
Container.RemoveElement(input.Edge);
71+
input.Node.RemoveFromContainer();
72+
}
73+
74+
InternalInputs.Clear();
75+
76+
Container = null;
3877
}
3978

79+
4080
protected Port InstantiatePort<TPort>(Direction direction)
4181
{
4282
return InstantiatePort(Orientation.Horizontal, direction, Port.Capacity.Single, typeof(TPort));
4383
}
4484

85+
#endregion
86+
87+
88+
#region Layout
89+
90+
private Vector2? _hierarchySize;
91+
4592

4693
public Vector2 GetNodeSize()
4794
{
@@ -56,20 +103,20 @@ public Vector2 GetHierarchySize()
56103
return _hierarchySize.Value;
57104
}
58105

59-
if (Children.Count == 0)
106+
if (Inputs.Count == 0)
60107
{
61108
_hierarchySize = GetNodeSize();
62109
return _hierarchySize.Value;
63110
}
64111

65112
var subHierarchySize = Vector2.zero;
66-
for (int i = 0; i < Children.Count; i++)
113+
for (int i = 0; i < Inputs.Count; i++)
67114
{
68-
var childSize = Children[i].GetHierarchySize();
115+
var childSize = Inputs[i].Node.GetHierarchySize();
69116
subHierarchySize.x = Mathf.Max(subHierarchySize.x, childSize.x);
70117
subHierarchySize.y += childSize.y;
71118
}
72-
subHierarchySize.y += (Children.Count - 1) * NodeLayoutInfo.VerticalSpace;
119+
subHierarchySize.y += (Inputs.Count - 1) * NodeLayoutInfo.VerticalSpace;
73120

74121
var hierarchySize = GetNodeSize() + new Vector2(NodeLayoutInfo.HorizontalSpace, 0);
75122
hierarchySize.y = Mathf.Max(hierarchySize.y, subHierarchySize.y);
@@ -85,11 +132,11 @@ public void CalculateLayout(Vector2 origin)
85132
SetPosition(new Rect(nodePos, Vector2.zero));
86133

87134
origin.x -= GetNodeSize().x - NodeLayoutInfo.HorizontalSpace;
88-
for (int i = 0; i < Children.Count; i++)
135+
for (int i = 0; i < Inputs.Count; i++)
89136
{
90-
var childNode = Children[i];
91-
var childHierarchySize = childNode.GetHierarchySize();
92-
childNode.CalculateLayout(origin);
137+
var childNode = Inputs[i];
138+
var childHierarchySize = childNode.Node.GetHierarchySize();
139+
childNode.Node.CalculateLayout(origin);
93140

94141
origin.y += childHierarchySize.y;
95142
}
@@ -102,36 +149,29 @@ public static Vector2 CalculateSubTreeRootNodePosition(Vector2 subTreeSize, Vect
102149
return subTreePos;
103150
}
104151

105-
public virtual void AddToContainer(UGraphView container)
106-
{
107-
Container = container;
108-
Container.AddElement(this);
109-
}
152+
#endregion
110153

111-
public virtual void RemoveFromContainer()
112-
{
113-
// self
114-
Container.RemoveElement(this);
115154

116-
// input edges
117-
for (int i = 0; i < InternalInputEdges.Count; i++)
118-
{
119-
Container.RemoveElement(InternalInputEdges[i]);
120-
}
155+
#region Flags
121156

122-
InternalInputEdges.Clear();
157+
private uint _flags = 0;
123158

124-
// children
125-
foreach (var childNode in Children)
126-
{
127-
childNode.RemoveFromContainer();
128-
}
129159

130-
Children.Clear();
160+
public bool CheckFlag(NodeFlag flag)
161+
{
162+
return (_flags & (uint)flag) != 0;
163+
}
131164

132-
Container = null;
165+
public void AddFlag(NodeFlag flag)
166+
{
167+
_flags |= (uint)flag;
168+
}
169+
170+
public void RemoveFlag(NodeFlag flag)
171+
{
172+
_flags &= ~(uint)flag;
133173
}
134174

135-
public abstract void CreateAndConnectInputNodes();
175+
#endregion
136176
}
137177
}

0 commit comments

Comments
 (0)