diff --git a/Source/Editor/Surface/Archetypes/Flow.cs b/Source/Editor/Surface/Archetypes/Flow.cs index 4ef1976c2..a214319ed 100644 --- a/Source/Editor/Surface/Archetypes/Flow.cs +++ b/Source/Editor/Surface/Archetypes/Flow.cs @@ -1,6 +1,7 @@ // Copyright (c) 2012-2020 Wojciech Figat. All rights reserved. using FlaxEngine; +using FlaxEngine.GUI; namespace FlaxEditor.Surface.Archetypes { @@ -10,6 +11,82 @@ namespace FlaxEditor.Surface.Archetypes [HideInEditor] public static class Flow { + private class SequenceNode : SurfaceNode + { + private Button _addButton; + private Button _removeButton; + + public SequenceNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch) + : base(id, context, nodeArch, groupArch) + { + } + + public override void OnSurfaceLoaded() + { + base.OnSurfaceLoaded(); + + _removeButton = new Button(0, 0, 20, 20) + { + Text = "-", + TooltipText = "Remove last sequence output", + Parent = this + }; + _removeButton.Clicked += () => SetValue(0, (int)Values[0] - 1); + + _addButton = new Button(0, 0, 20, 20) + { + Text = "+", + TooltipText = "Add sequence output", + Parent = this + }; + _addButton.Clicked += () => SetValue(0, (int)Values[0] + 1); + + UpdateUI(); + } + + public override void OnSurfaceCanEditChanged(bool canEdit) + { + base.OnSurfaceCanEditChanged(canEdit); + + _addButton.Enabled = canEdit; + _removeButton.Enabled = canEdit; + UpdateUI(); + } + + public override void OnValuesChanged() + { + base.OnValuesChanged(); + + UpdateUI(); + } + + private void UpdateUI() + { + var count = (int)Values[0]; + var countMin = 0; + var countMax = 16; + for (int i = 0; i < count; i++) + { + var box = GetBox(i + 1); + box.Visible = true; + } + for (int i = count; i <= countMax; i++) + { + var box = GetBox(i + 1); + box.RemoveConnections(); + box.Visible = false; + } + + _addButton.Enabled = count < countMax && Surface.CanEdit; + _removeButton.Enabled = count > countMin && Surface.CanEdit; + + Resize(140, 40 + (count - 1) * 20); + + _addButton.Location = new Vector2(Width - _addButton.Width - FlaxEditor.Surface.Constants.NodeMarginX, Height - 20 - FlaxEditor.Surface.Constants.NodeMarginY - FlaxEditor.Surface.Constants.NodeFooterSize); + _removeButton.Location = new Vector2(_addButton.X - _removeButton.Width - 4, _addButton.Y); + } + } + /// /// The nodes for that group. /// @@ -68,6 +145,37 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.Output(2, "Done", typeof(void), 5, true), } }, + new NodeArchetype + { + TypeID = 4, + Title = "Sequence", + Create = (id, context, arch, groupArch) => new SequenceNode(id, context, arch, groupArch), + Description = "Performs a series of actions in a sequence (one after the another).", + Flags = NodeFlags.VisualScriptGraph, + Size = new Vector2(140, 80), + DefaultValues = new object[] { 2 }, + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, string.Empty, false, typeof(void), 0), + NodeElementArchetype.Factory.Output(0, string.Empty, typeof(void), 1, true), + NodeElementArchetype.Factory.Output(1, string.Empty, typeof(void), 2, true), + NodeElementArchetype.Factory.Output(2, string.Empty, typeof(void), 3, true), + NodeElementArchetype.Factory.Output(3, string.Empty, typeof(void), 4, true), + NodeElementArchetype.Factory.Output(4, string.Empty, typeof(void), 5, true), + NodeElementArchetype.Factory.Output(5, string.Empty, typeof(void), 6, true), + NodeElementArchetype.Factory.Output(6, string.Empty, typeof(void), 7, true), + NodeElementArchetype.Factory.Output(7, string.Empty, typeof(void), 8, true), + NodeElementArchetype.Factory.Output(8, string.Empty, typeof(void), 9, true), + NodeElementArchetype.Factory.Output(9, string.Empty, typeof(void), 10, true), + NodeElementArchetype.Factory.Output(10, string.Empty, typeof(void), 11, true), + NodeElementArchetype.Factory.Output(11, string.Empty, typeof(void), 12, true), + NodeElementArchetype.Factory.Output(12, string.Empty, typeof(void), 13, true), + NodeElementArchetype.Factory.Output(13, string.Empty, typeof(void), 14, true), + NodeElementArchetype.Factory.Output(14, string.Empty, typeof(void), 15, true), + NodeElementArchetype.Factory.Output(15, string.Empty, typeof(void), 16, true), + NodeElementArchetype.Factory.Output(16, string.Empty, typeof(void), 17, true), + } + }, }; } } diff --git a/Source/Engine/Content/Assets/VisualScript.cpp b/Source/Engine/Content/Assets/VisualScript.cpp index de1a85586..2cab30892 100644 --- a/Source/Engine/Content/Assets/VisualScript.cpp +++ b/Source/Engine/Content/Assets/VisualScript.cpp @@ -1117,6 +1117,18 @@ void VisualScriptExecutor::ProcessGroupFlow(Box* boxBase, Node* node, Value& val break; } break; + } + // Sequence + case 4: + { + const int32 count = (int32)node->Values[0]; + for (int32 i = 0; i < count; i++) + { + boxBase = node->GetBox(i + 1); + if (boxBase->HasConnection()) + eatBox(node, boxBase->FirstConnection()); + } + break; } } }