Browse Source

FlowchartWindow performance for 100s of blocks

Blocks now track their selectedness and filteredness to avoid hundreds of contains calls every Draw
Only recalculate filtered collection and total blocks on flowchart when a change has occured
master
desktop-maesty/steve 6 years ago
parent
commit
9dd37ee7f7
  1. 4
      Assets/Fungus/Scripts/Components/Block.cs
  2. 24
      Assets/Fungus/Scripts/Components/Flowchart.cs
  3. 82
      Assets/Fungus/Scripts/Editor/FlowchartWindow.cs

4
Assets/Fungus/Scripts/Components/Block.cs

@ -109,6 +109,10 @@ namespace Fungus
command.CommandIndex = index++;
}
}
//editor only state for speeding up flowchart window drawing
public bool IsSelected { get; set; }
public bool IsFiltered { get; set; }
#endif
#region Public members

24
Assets/Fungus/Scripts/Components/Flowchart.cs

@ -333,6 +333,7 @@ namespace Fungus
/// </summary>
public virtual Rect ScrollViewRect { get { return scrollViewRect; } set { scrollViewRect = value; } }
#if UNITY_EDITOR
/// <summary>
/// Current actively selected block in the Flowchart editor.
/// </summary>
@ -344,13 +345,14 @@ namespace Fungus
}
set
{
selectedBlocks.Clear();
selectedBlocks.Add(value);
ClearSelectedBlocks();
AddSelectedBlock(value);
}
}
public virtual List<Block> SelectedBlocks { get { return selectedBlocks; } set { selectedBlocks = value; } }
#endif
/// <summary>
/// Currently selected command in the Flowchart editor.
/// </summary>
@ -1106,11 +1108,16 @@ namespace Fungus
}
}
#if UNITY_EDITOR
/// <summary>
/// Clears the list of selected blocks.
/// </summary>
public virtual void ClearSelectedBlocks()
{
foreach (var item in selectedBlocks)
{
item.IsSelected = false;
}
selectedBlocks.Clear();
}
@ -1121,10 +1128,23 @@ namespace Fungus
{
if (!selectedBlocks.Contains(block))
{
block.IsSelected = true;
selectedBlocks.Add(block);
}
}
public virtual bool DeselectBlock(Block block)
{
if (!selectedBlocks.Contains(block))
{
block.IsSelected = false;
selectedBlocks.Remove(block);
return true;
}
return false;
}
#endif
/// <summary>
/// Reset the commands and variables in the Flowchart.
/// </summary>

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

@ -59,9 +59,9 @@ namespace Fungus.EditorUtils
newSerializedObject.ApplyModifiedProperties();
}
internal Block PasteBlock(Flowchart flowchart)
internal Block PasteBlock(FlowchartWindow flowWind ,Flowchart flowchart)
{
var newBlock = FlowchartWindow.CreateBlock(flowchart, Vector2.zero);
var newBlock = flowWind.CreateBlock(flowchart, Vector2.zero);
// Copy all command serialized properties
// Copy references to match duplication behavior
@ -127,16 +127,17 @@ namespace Fungus.EditorUtils
private string searchString = string.Empty;
protected Rect searchRect;
protected Rect popupRect;
protected Block[] filteredBlocks;
protected Block[] filteredBlocks = new Block[0];
protected int blockPopupSelection = -1;
protected Vector2 popupScroll;
protected Flowchart flowchart, prevFlowchart;
protected Block[] blocks;
protected Block[] blocks = new Block[0];
protected Block dragBlock;
protected static FungusState fungusState;
static protected VariableListAdaptor variableListAdaptor;
private bool filterStale = true;
[MenuItem("Tools/Fungus/Flowchart Window")]
static void Init()
@ -146,7 +147,6 @@ namespace Fungus.EditorUtils
protected virtual void OnEnable()
{
// All block nodes use the same GUIStyle, but with a different background
nodeStyle.border = new RectOffset(20, 20, 5, 5);
nodeStyle.padding = nodeStyle.border;
@ -161,6 +161,16 @@ namespace Fungus.EditorUtils
copyList.Clear();
wantsMouseMove = true; // For hover selection in block search popup
UpdateBlockCollection();
}
protected void UpdateBlockCollection()
{
flowchart = GetFlowchart();
blocks = flowchart.GetComponents<Block>();
filterStale = true;
UpdateFilteredBlocks();
}
protected virtual void OnInspectorUpdate()
@ -185,7 +195,7 @@ namespace Fungus.EditorUtils
forceRepaintCount--;
forceRepaintCount = Math.Max(0, forceRepaintCount);
Repaint();
//Repaint();
}
protected virtual void OnBecameVisible()
@ -245,9 +255,27 @@ namespace Fungus.EditorUtils
protected void UpdateFilteredBlocks()
{
if (filterStale)
{
filterStale = false;
//reset all
foreach (var item in filteredBlocks)
{
item.IsFiltered = false;
}
//gather new
filteredBlocks = blocks.Where(block => block.BlockName.ToLower().Contains(searchString.ToLower())).ToArray();
//update filteredness
foreach (var item in filteredBlocks)
{
item.IsFiltered = true;
}
blockPopupSelection = Mathf.Clamp(blockPopupSelection, 0, filteredBlocks.Length - 1);
}
}
protected virtual void HandleEarlyEvents(Event e)
{
@ -358,7 +386,12 @@ namespace Fungus.EditorUtils
DeleteBlocks();
blocks = flowchart.GetComponents<Block>();
////blocks = flowchart.GetComponents<Block>();
//if (prevBlockCount != blocks.Length)
// filterStale = true;
//prevBlockCount = blocks.Length;
UpdateFilteredBlocks();
BringSelectedBlockToFront();
@ -422,6 +455,7 @@ namespace Fungus.EditorUtils
50 / flowchart.Zoom - flowchart.ScrollPos.x, 50 / flowchart.Zoom - flowchart.ScrollPos.y
);
CreateBlock(flowchart, newNodePosition);
UpdateBlockCollection();
}
GUILayout.Label("", EditorStyles.toolbarButton, GUILayout.Width(8)); // Separator
@ -452,6 +486,7 @@ namespace Fungus.EditorUtils
if (newString != searchString)
{
searchString = newString;
filterStale = true;
}
if (e.type == EventType.Repaint)
@ -684,11 +719,7 @@ namespace Fungus.EditorUtils
if (GetAppendModifierDown())
{
if (flowchart.SelectedBlocks.Contains(hitBlock))
{
flowchart.SelectedBlocks.Remove(hitBlock);
}
else
if (!flowchart.DeselectBlock(hitBlock))
{
flowchart.AddSelectedBlock(hitBlock);
}
@ -778,7 +809,7 @@ namespace Fungus.EditorUtils
{
if (mouseDownSelectionState.Contains(block))
{
flowchart.SelectedBlocks.Remove(block);
flowchart.DeselectBlock(block);
}
else
{
@ -791,7 +822,7 @@ namespace Fungus.EditorUtils
}
else
{
flowchart.SelectedBlocks.Remove(block);
flowchart.DeselectBlock(block);
}
}
e.Use();
@ -865,6 +896,7 @@ namespace Fungus.EditorUtils
{
SetBlockForInspector(flowchart, flowchart.SelectedBlock);
}
Repaint();
}
break;
@ -950,7 +982,6 @@ namespace Fungus.EditorUtils
{
DrawConnections(block, true);
}
}
for (int i = 0; i < blocks.Length; ++i)
{
@ -972,7 +1003,7 @@ namespace Fungus.EditorUtils
windowRect.position += flowchart.ScrollPos;
// Draw blocks
bool selected = flowchart.SelectedBlocks.Contains(block);
bool selected = block.IsSelected;
GUIStyle nodeStyleCopy = new GUIStyle(nodeStyle);
var graphics = GetBlockGraphics(block);
@ -995,7 +1026,7 @@ namespace Fungus.EditorUtils
var brightness = graphics.tint.r * 0.3 + graphics.tint.g * 0.59 + graphics.tint.b * 0.11;
nodeStyleCopy.normal.textColor = brightness >= 0.5 ? Color.black : Color.white;
if (GUI.GetNameOfFocusedControl() == searchFieldName && !filteredBlocks.Contains(block))
if (GUI.GetNameOfFocusedControl() == searchFieldName && !block.IsFiltered)
{
graphics.tint.a *= 0.2f;
}
@ -1042,6 +1073,7 @@ namespace Fungus.EditorUtils
GUI.Label(rect, handlerLabel, handlerStyle);
}
}
}
// Draw play icons beside all executing blocks
if (Application.isPlaying)
@ -1175,9 +1207,10 @@ namespace Fungus.EditorUtils
Selection.activeGameObject = flowchart.gameObject;
}
public static Block CreateBlock(Flowchart flowchart, Vector2 position)
public Block CreateBlock(Flowchart flowchart, Vector2 position)
{
Block newBlock = flowchart.CreateBlock(position);
UpdateBlockCollection();
Undo.RegisterCreatedObjectUndo(newBlock, "New Block");
// Use AddSelected instead of Select for when multiple blocks are duplicated
@ -1348,7 +1381,7 @@ namespace Fungus.EditorUtils
for (int i = 0; i < deleteList.Count; ++i)
{
var deleteBlock = deleteList[i];
bool isSelected = (flowchart.SelectedBlocks.Contains(deleteBlock));
bool isSelected = deleteBlock.IsSelected;
var commandList = deleteBlock.CommandList;
for (int j = 0; j < commandList.Count; ++j)
@ -1367,13 +1400,18 @@ namespace Fungus.EditorUtils
if (isSelected)
{
// Deselect
flowchart.SelectedBlocks.Remove(deleteBlock);
flowchart.DeselectBlock(deleteBlock);
// Revert to showing properties for the Flowchart
Selection.activeGameObject = flowchart.gameObject;
}
}
if (deleteList.Count > 0)
{
UpdateBlockCollection();
}
deleteList.Clear();
}
@ -1446,7 +1484,7 @@ namespace Fungus.EditorUtils
foreach (var copy in copyList)
{
pasteList.Add(copy.PasteBlock(flowchart));
pasteList.Add(copy.PasteBlock(this, flowchart));
}
var copiedCenter = GetBlockCenter(pasteList.ToArray()) + flowchart.ScrollPos;
@ -1458,6 +1496,8 @@ namespace Fungus.EditorUtils
tempRect.position += delta;
block._NodeRect = tempRect;
}
UpdateBlockCollection();
}
protected virtual void Duplicate()

Loading…
Cancel
Save