Browse Source

FlowchartWindow perf improvements

Only draw connections that are on screen
Limit repaint to when changes in block execution or previous execution happen rather forcing every frame
master
desktop-maesty/steve 6 years ago
parent
commit
4f37234f69
  1. 193
      Assets/Fungus/Scripts/Editor/FlowchartWindow.cs

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

@ -104,6 +104,74 @@ namespace Fungus.EditorUtils
internal Texture2D offTexture;
}
/// <summary>
/// Helper class to maintain list of blocks that are currently executing when the game is running in editor
/// </summary>
protected class ExecutingBlocks
{
internal List<Block> areExecuting = new List<Block>(),
wereExecuting = new List<Block>(),
workspace = new List<Block>();
internal bool isChangeDetected { get; set; }
private float lastFade;
internal void ProcessAllBlocks(Block[] blocks)
{
isChangeDetected = false;
workspace.Clear();
//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)
{
var b = blocks[i];
var bIsExec = b.IsExecuting();
if (bIsExec)
{
b.ExecutingIconTimer = fadeTimer;
b.ActiveCommand.ExecutingIconTimer = fadeTimer;
workspace.Add(b);
}
}
if(areExecuting.Count != workspace.Count || !WorkspaceMatchesExeucting())
{
wereExecuting.Clear();
wereExecuting.AddRange(areExecuting);
areExecuting.Clear();
areExecuting.AddRange(workspace);
isChangeDetected = true;
lastFade = fadeTimer;
}
}
internal bool WorkspaceMatchesExeucting()
{
for (int i = 0; i < areExecuting.Count; i++)
{
if (areExecuting[i] != workspace[i])
return false;
}
return true;
}
internal bool IsAnimFadeoutNeed()
{
return (lastFade - Time.realtimeSinceStartup) >= 0;
}
internal void ClearAll()
{
areExecuting.Clear();
wereExecuting.Clear();
workspace.Clear();
isChangeDetected = true;
lastFade = 0;
}
}
protected List<BlockCopy> copyList = new List<BlockCopy>();
public static List<Block> deleteList = new List<Block>();
protected Vector2 startDragPosition;
@ -139,6 +207,7 @@ namespace Fungus.EditorUtils
private bool filterStale = true;
private bool wasControl;
private ExecutingBlocks executingBlocks = new ExecutingBlocks();
[MenuItem("Tools/Fungus/Flowchart Window")]
static void Init()
@ -164,6 +233,27 @@ namespace Fungus.EditorUtils
wantsMouseMove = true; // For hover selection in block search popup
UpdateBlockCollection();
EditorApplication.update += OnEditorUpdate;
}
protected virtual void OnDisable()
{
EditorApplication.update -= OnEditorUpdate;
}
void OnEditorUpdate()
{
HandleFlowchartSelectionChange();
if (Application.isPlaying)
{
executingBlocks.ProcessAllBlocks(blocks);
if (executingBlocks.isChangeDetected || executingBlocks.IsAnimFadeoutNeed())
Repaint();
}
}
protected void UpdateBlockCollection()
@ -429,35 +519,35 @@ namespace Fungus.EditorUtils
mouseDownSelectionState.Clear();
}
protected virtual void OnGUI()
internal bool HandleFlowchartSelectionChange()
{
// TODO: avoid calling some of these methods in OnGUI because it should be possible
// to only call them when the window is initialized or a new flowchart is selected, etc.
flowchart = GetFlowchart();
if (flowchart == null)
{
GUILayout.Label("No Flowchart scene object selected");
return;
}
//target has changed, so clear the blockinspector
if (flowchart != prevFlowchart)
{
blockInspector = null;
prevFlowchart = flowchart;
executingBlocks.ClearAll();
UpdateBlockCollection();
Repaint();
return;
return true;
}
DeleteBlocks();
return false;
}
////blocks = flowchart.GetComponents<Block>();
//if (prevBlockCount != blocks.Length)
// filterStale = true;
protected virtual void OnGUI()
{
// TODO: avoid calling some of these methods in OnGUI because it should be possible
// to only call them when the window is initialized or a new flowchart is selected, etc.
if (HandleFlowchartSelectionChange()) return;
//prevBlockCount = blocks.Length;
if (flowchart == null)
{
GUILayout.Label("No Flowchart scene object selected");
return;
}
DeleteBlocks();
UpdateFilteredBlocks();
@ -1054,8 +1144,7 @@ namespace Fungus.EditorUtils
// Draw play icons beside all executing blocks
if (Application.isPlaying)
{
//greedy repaint for now
Repaint();
var emptyStyle = new GUIStyle();
//cache these once as they can end up being called thousands of times per frame otherwise
var curRealTime = Time.realtimeSinceStartup;
@ -1063,40 +1152,40 @@ namespace Fungus.EditorUtils
for (int i = 0; i < blocks.Length; ++i)
{
var b = blocks[i];
var bIsExec = b.IsExecuting();
if (bIsExec)
{
b.ExecutingIconTimer = fadeTimer;
b.ActiveCommand.ExecutingIconTimer = fadeTimer;
}
DrawExecutingBlockIcon(b,
scriptViewRect,
(b.ExecutingIconTimer - curRealTime) / FungusConstants.ExecutingIconFadeTime,
emptyStyle);
}
GUI.color = Color.white;
}
if (b.ExecutingIconTimer > curRealTime)
{
Rect rect = new Rect(b._NodeRect);
EditorZoomArea.End();
}
rect.x += flowchart.ScrollPos.x - 37;
rect.y += flowchart.ScrollPos.y + 3;
rect.width = 34;
rect.height = 34;
private void DrawExecutingBlockIcon(Block b, Rect scriptViewRect, float alpha, GUIStyle style)
{
if (alpha <= 0)
return;
if (!bIsExec)
{
float alpha = (b.ExecutingIconTimer - curRealTime) / FungusConstants.ExecutingIconFadeTime;
alpha = Mathf.Clamp01(alpha);
GUI.color = new Color(1f, 1f, 1f, alpha);
}
Rect rect = new Rect(b._NodeRect);
if (GUI.Button(rect, FungusEditorResources.PlayBig, new GUIStyle()))
{
SelectBlock(b);
}
rect.x += flowchart.ScrollPos.x - 37;
rect.y += flowchart.ScrollPos.y + 3;
rect.width = 34;
rect.height = 34;
GUI.color = Color.white;
}
if (scriptViewRect.Overlaps(rect))
{
GUI.color = new Color(1f, 1f, 1f, alpha);
if (GUI.Button(rect, FungusEditorResources.PlayBig, style))
{
SelectBlock(b);
}
}
EditorZoomArea.End();
GUI.color = Color.white;
}
}
private Rect CalcFlowchartWindowViewRect()
@ -1218,6 +1307,9 @@ namespace Fungus.EditorUtils
bool blockIsSelected = flowchart.SelectedBlock == block;
Rect scriptViewRect = CalcFlowchartWindowViewRect();
var commandList = block.CommandList;
foreach (var command in commandList)
{
@ -1259,7 +1351,14 @@ namespace Fungus.EditorUtils
endRect.x += flowchart.ScrollPos.x;
endRect.y += flowchart.ScrollPos.y;
DrawRectConnection(startRect, endRect, highlight);
Rect boundRect = new Rect();
boundRect.xMin = Mathf.Min(startRect.xMin, endRect.xMin);
boundRect.xMax = Mathf.Max(startRect.xMax, endRect.xMax);
boundRect.yMin = Mathf.Min(startRect.yMin, endRect.yMin);
boundRect.yMax = Mathf.Max(startRect.yMax, endRect.yMax);
if (boundRect.Overlaps(scriptViewRect))
DrawRectConnection(startRect, endRect, highlight);
}
}
}

Loading…
Cancel
Save