Browse Source

Detect and respond to play mode invalidating FlowchartWindow local blocks cache

FlowchartWindow.DrawRectConnection optimisation to remove alloc and internal loops
master
desktop-maesty/steve 6 years ago
parent
commit
e176222cd6
  1. 114
      Assets/Fungus/Scripts/Editor/FlowchartWindow.cs

114
Assets/Fungus/Scripts/Editor/FlowchartWindow.cs

@ -185,13 +185,15 @@ namespace Fungus.EditorUtils
{ {
// Ensure the Block Inspector is always showing the currently selected block // Ensure the Block Inspector is always showing the currently selected block
var flowchart = GetFlowchart(); var flowchart = GetFlowchart();
if (flowchart == null) if (flowchart == null || AnyNullBLocks())
{ {
UpdateBlockCollection();
Repaint();
return; return;
} }
if (Selection.activeGameObject == null && if (Selection.activeGameObject == null &&
flowchart.SelectedBlock != null ) flowchart.SelectedBlock != null)
{ {
if (blockInspector == null) if (blockInspector == null)
{ {
@ -200,10 +202,27 @@ namespace Fungus.EditorUtils
blockInspector.block = (Block)flowchart.SelectedBlock; blockInspector.block = (Block)flowchart.SelectedBlock;
} }
forceRepaintCount--; if (forceRepaintCount != 0)
forceRepaintCount = Math.Max(0, forceRepaintCount); {
forceRepaintCount--;
forceRepaintCount = Math.Max(0, forceRepaintCount);
Repaint();
}
}
private bool AnyNullBLocks()
{
if (blocks == null)
return true;
for (int i = 0; i < blocks.Length; i++)
{
if (blocks[i] == null)
return true;
}
//Repaint(); return false;
} }
protected virtual void OnBecameVisible() protected virtual void OnBecameVisible()
@ -428,6 +447,7 @@ namespace Fungus.EditorUtils
blockInspector = null; blockInspector = null;
prevFlowchart = flowchart; prevFlowchart = flowchart;
UpdateBlockCollection(); UpdateBlockCollection();
Repaint();
return; return;
} }
@ -1034,17 +1054,23 @@ namespace Fungus.EditorUtils
// Draw play icons beside all executing blocks // Draw play icons beside all executing blocks
if (Application.isPlaying) if (Application.isPlaying)
{ {
//greedy repaint for now
Repaint();
//cache these once as they can end up being called thousands of times per frame otherwise
var curRealTime = Time.realtimeSinceStartup;
var fadeTimer = curRealTime + FungusConstants.ExecutingIconFadeTime;
for (int i = 0; i < blocks.Length; ++i) for (int i = 0; i < blocks.Length; ++i)
{ {
var b = blocks[i]; var b = blocks[i];
if (b.IsExecuting()) var bIsExec = b.IsExecuting();
if (bIsExec)
{ {
b.ExecutingIconTimer = Time.realtimeSinceStartup + FungusConstants.ExecutingIconFadeTime; b.ExecutingIconTimer = fadeTimer;
b.ActiveCommand.ExecutingIconTimer = Time.realtimeSinceStartup + FungusConstants.ExecutingIconFadeTime; b.ActiveCommand.ExecutingIconTimer = fadeTimer;
forceRepaintCount = 1;
} }
if (b.ExecutingIconTimer > Time.realtimeSinceStartup) if (b.ExecutingIconTimer > curRealTime)
{ {
Rect rect = new Rect(b._NodeRect); Rect rect = new Rect(b._NodeRect);
@ -1053,9 +1079,9 @@ namespace Fungus.EditorUtils
rect.width = 34; rect.width = 34;
rect.height = 34; rect.height = 34;
if (!b.IsExecuting()) if (!bIsExec)
{ {
float alpha = (b.ExecutingIconTimer - Time.realtimeSinceStartup) / FungusConstants.ExecutingIconFadeTime; float alpha = (b.ExecutingIconTimer - curRealTime) / FungusConstants.ExecutingIconFadeTime;
alpha = Mathf.Clamp01(alpha); alpha = Mathf.Clamp01(alpha);
GUI.color = new Color(1f, 1f, 1f, alpha); GUI.color = new Color(1f, 1f, 1f, alpha);
} }
@ -1238,37 +1264,51 @@ namespace Fungus.EditorUtils
} }
} }
static readonly Vector2[] pointsA = new Vector2[4];
static readonly Vector2[] pointsB = new Vector2[4];
//we only connect mids on sides to matching opposing middle side on other block
private struct IndexPair { public int a, b; public IndexPair(int a, int b) { this.a = a;this.b = b; } }
static readonly IndexPair[] closestCornerIndexPairs = new IndexPair[]
{
new IndexPair(){a=0,b=3 },
new IndexPair(){a=3,b=0 },
new IndexPair(){a=1,b=2 },
new IndexPair(){a=2,b=1 },
};
//prevent alloc in DrawAAConvexPolygon
static readonly Vector3[] beizerWorkSpace = new Vector3[3];
protected virtual void DrawRectConnection(Rect rectA, Rect rectB, bool highlight) protected virtual void DrawRectConnection(Rect rectA, Rect rectB, bool highlight)
{ {
Vector2[] pointsA = new Vector2[] { //previous method made a lot of garbage so now we reuse the same array
new Vector2(rectA.xMin, rectA.center.y), pointsA[0] = new Vector2(rectA.xMin, rectA.center.y);
new Vector2(rectA.xMin + rectA.width / 2, rectA.yMin), pointsA[1] = new Vector2(rectA.xMin + rectA.width / 2, rectA.yMin);
new Vector2(rectA.xMin + rectA.width / 2, rectA.yMax), pointsA[2] = new Vector2(rectA.xMin + rectA.width / 2, rectA.yMax);
new Vector2(rectA.xMax, rectA.center.y) pointsA[3] = new Vector2(rectA.xMax, rectA.center.y);
};
Vector2[] pointsB = new Vector2[] { pointsB[0] = new Vector2(rectB.xMin, rectB.center.y);
new Vector2(rectB.xMin, rectB.center.y), pointsB[1] = new Vector2(rectB.xMin + rectB.width / 2, rectB.yMin);
new Vector2(rectB.xMin + rectB.width / 2, rectB.yMin), pointsB[2] = new Vector2(rectB.xMin + rectB.width / 2, rectB.yMax);
new Vector2(rectB.xMin + rectB.width / 2, rectB.yMax), pointsB[3] = new Vector2(rectB.xMax, rectB.center.y);
new Vector2(rectB.xMax, rectB.center.y)
};
Vector2 pointA = Vector2.zero; Vector2 pointA = Vector2.zero;
Vector2 pointB = Vector2.zero; Vector2 pointB = Vector2.zero;
float minDist = float.MaxValue; float minDist = float.MaxValue;
foreach (var a in pointsA) //previous method compared every point to every point
// we only check mathcing opposing mids
for (int i = 0; i < closestCornerIndexPairs.Length; i++)
{ {
foreach (var b in pointsB) var a = pointsA[closestCornerIndexPairs[i].a];
var b = pointsB[closestCornerIndexPairs[i].b];
float d = Vector2.Distance(a, b);
if (d < minDist)
{ {
float d = Vector2.Distance(a, b); pointA = a;
if (d < minDist) pointB = b;
{ minDist = d;
pointA = a;
pointB = b;
minDist = d;
}
} }
} }
@ -1300,9 +1340,11 @@ namespace Fungus.EditorUtils
var point = GetPointOnCurve(pointA, controlA, pointB, controlB, 0.7f); var point = GetPointOnCurve(pointA, controlA, pointB, controlB, 0.7f);
var direction = (GetPointOnCurve(pointA, controlA, pointB, controlB, 0.6f) - point).normalized; var direction = (GetPointOnCurve(pointA, controlA, pointB, controlB, 0.6f) - point).normalized;
var perp = new Vector2(direction.y, -direction.x); var perp = new Vector2(direction.y, -direction.x);
Handles.DrawAAConvexPolygon( //reuse same array to avoid the auto alloced one in DrawAAConvexPolygon
point, point + direction * 10 + perp * 5, point + direction * 10 - perp * 5 beizerWorkSpace[0] = point;
); beizerWorkSpace[1] = point + direction * 10 + perp * 5;
beizerWorkSpace[2] = point + direction * 10 - perp * 5;
Handles.DrawAAConvexPolygon(beizerWorkSpace);
var connectionPointA = pointA + directionA * 4f; var connectionPointA = pointA + directionA * 4f;
var connectionRectA = new Rect(connectionPointA.x - 4f, connectionPointA.y - 4f, 8f, 8f); var connectionRectA = new Rect(connectionPointA.x - 4f, connectionPointA.y - 4f, 8f, 8f);

Loading…
Cancel
Save