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++; command.CommandIndex = index++;
} }
} }
//editor only state for speeding up flowchart window drawing
public bool IsSelected { get; set; }
public bool IsFiltered { get; set; }
#endif #endif
#region Public members #region Public members

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

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

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

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

Loading…
Cancel
Save