From c902e33d8af955aff7321e629e63e832bb140b57 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 16 Feb 2021 15:54:22 +0100 Subject: [PATCH] Add Build Actions option to editor settings for build button configuration --- Source/Editor/Editor.cs | 17 -- Source/Editor/Modules/UIModule.cs | 2 +- Source/Editor/Options/GeneralOptions.cs | 49 ++++++ Source/Editor/States/BuildingScenesState.cs | 159 +++++++++++++++--- Source/Editor/States/EditingSceneState.cs | 22 +++ Source/Editor/States/ReloadingScriptsState.cs | 22 +++ Source/Engine/Utilities/State.cs | 3 - Source/Engine/Utilities/StateMachine.cs | 5 + 8 files changed, 233 insertions(+), 46 deletions(-) diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index f81f81ddd..3aa8346c8 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -242,8 +242,6 @@ namespace FlaxEditor StateMachine = new EditorStateMachine(this); Undo = new EditorUndo(this); - ScriptsBuilder.ScriptsReloadBegin += ScriptsBuilder_ScriptsReloadBegin; - ScriptsBuilder.ScriptsReloadEnd += ScriptsBuilder_ScriptsReloadEnd; UIControl.FallbackParentGetDelegate += OnUIControlFallbackParentGet; } @@ -260,18 +258,6 @@ namespace FlaxEditor return null; } - private void ScriptsBuilder_ScriptsReloadBegin() - { - EnsureState(); - StateMachine.GoToState(); - } - - private void ScriptsBuilder_ScriptsReloadEnd() - { - EnsureState(); - StateMachine.GoToState(); - } - internal void RegisterModule(EditorModule module) { Log("Register Editor module " + module); @@ -497,9 +483,6 @@ namespace FlaxEditor Surface.VisualScriptSurface.NodesCache.Clear(); Instance = null; - ScriptsBuilder.ScriptsReloadBegin -= ScriptsBuilder_ScriptsReloadBegin; - ScriptsBuilder.ScriptsReloadEnd -= ScriptsBuilder_ScriptsReloadEnd; - // Invoke new instance if need to open a project if (!string.IsNullOrEmpty(_projectToOpen)) { diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index 6b01986a9..99d8f6e2a 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -507,7 +507,7 @@ namespace FlaxEditor.Modules _toolStripRotate = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Rotate32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate).LinkTooltip("Change Gizmo tool mode to Rotate (2)"); _toolStripScale = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Scale32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale).LinkTooltip("Change Gizmo tool mode to Scale (3)"); ToolStrip.AddSeparator(); - _toolStripBuildScenes = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Build32, Editor.BuildScenesOrCancel).LinkTooltip("Build scenes data - CSG, navmesh, static lighting, env probes (Ctrl+F10)"); + _toolStripBuildScenes = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Build32, Editor.BuildScenesOrCancel).LinkTooltip("Build scenes data - CSG, navmesh, static lighting, env probes - configurable via Build Actions in editor options (Ctrl+F10)"); ToolStrip.AddSeparator(); _toolStripPlay = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Play32, Editor.Simulation.RequestPlayOrStopPlay).LinkTooltip("Start/Stop game (F5)"); _toolStripPause = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Pause32, Editor.Simulation.RequestResumeOrPause).LinkTooltip("Pause/Resume game(F6)"); diff --git a/Source/Editor/Options/GeneralOptions.cs b/Source/Editor/Options/GeneralOptions.cs index 9b5450f45..85174030f 100644 --- a/Source/Editor/Options/GeneralOptions.cs +++ b/Source/Editor/Options/GeneralOptions.cs @@ -32,6 +32,42 @@ namespace FlaxEditor.Options LastOpened, } + /// + /// The build actions. + /// + public enum BuildAction + { + /// + /// Builds Constructive Solid Geometry brushes into meshes. + /// + [Tooltip("Builds Constructive Solid Geometry brushes into meshes.")] + CSG, + + /// + /// Builds Env Probes and Sky Lights to prerendered cube textures. + /// + [Tooltip("Builds Env Probes and Sky Lights to prerendered cube textures.")] + EnvProbes, + + /// + /// Builds static lighting into lightmaps. + /// + [Tooltip("Builds static lighting into lightmaps.")] + StaticLighting, + + /// + /// Builds navigation meshes. + /// + [Tooltip("Builds navigation meshes.")] + NavMesh, + + /// + /// Compiles the scripts. + /// + [Tooltip("Compiles the scripts.")] + CompileScripts, + } + /// /// Gets or sets the scene to load on editor startup. /// @@ -53,6 +89,19 @@ namespace FlaxEditor.Options [EditorDisplay("General", "Editor FPS"), EditorOrder(110), Tooltip("Limit for the editor draw/update frames per second rate (FPS). Use higher values if you need more responsive interface or lower values to use less device power. Value 0 disables any limits.")] public float EditorFPS { get; set; } = 60.0f; + /// + /// Gets or sets the sequence of actions to perform when using Build Scenes button. Can be used to configure this as button (eg. compile code or just update navmesh). + /// + [EditorDisplay("General"), EditorOrder(200), Tooltip("The sequence of actions to perform when using Build Scenes button. Can be used to configure this as button (eg. compile code or just update navmesh).")] + public BuildAction[] BuildActions { get; set; } = + { + BuildAction.CSG, + BuildAction.EnvProbes, + BuildAction.StaticLighting, + BuildAction.EnvProbes, + BuildAction.NavMesh, + }; + /// /// Gets or sets a value indicating whether perform automatic scripts reload on main window focus. /// diff --git a/Source/Editor/States/BuildingScenesState.cs b/Source/Editor/States/BuildingScenesState.cs index 998292626..40ccff829 100644 --- a/Source/Editor/States/BuildingScenesState.cs +++ b/Source/Editor/States/BuildingScenesState.cs @@ -1,6 +1,9 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; +using System.Collections.Generic; +using System.Linq; +using FlaxEditor.Options; using FlaxEditor.SceneGraph.Actors; using FlaxEngine; using FlaxEngine.Utilities; @@ -16,6 +19,9 @@ namespace FlaxEditor.States { private sealed class SubStateMachine : StateMachine { + public int ActionIndex = -1; + public readonly List Actions = new List(); + protected override void SwitchState(State nextState) { if (CurrentState != null && nextState != null) @@ -27,10 +33,40 @@ namespace FlaxEditor.States private abstract class SubState : State { + public virtual bool DirtyScenes => true; + + public virtual bool CanReloadScripts => false; + + public virtual void Before() + { + } + public virtual void Update() { } + public virtual void Done() + { + var stateMachine = (SubStateMachine)StateMachine; + stateMachine.ActionIndex++; + if (stateMachine.ActionIndex < stateMachine.Actions.Count) + { + var action = stateMachine.Actions[stateMachine.ActionIndex]; + var state = stateMachine.States.FirstOrDefault(x => x is ActionState a && a.Action == action); + if (state != null) + { + StateMachine.GoToState(state); + } + else + { + Editor.LogError($"Missing or invalid build scene action {action}."); + } + return; + } + + StateMachine.GoToState(); + } + public virtual void Cancel() { StateMachine.GoToState(); @@ -45,18 +81,31 @@ namespace FlaxEditor.States { public override void OnEnter() { - var editor = Editor.Instance; - foreach (var scene in Level.Scenes) + var stateMachine = (SubStateMachine)StateMachine; + var scenesDirty = false; + foreach (var state in stateMachine.States) { - scene.ClearLightmaps(); - editor.Scene.MarkSceneEdited(scene); + ((SubState)state).Before(); + scenesDirty |= ((SubState)state).DirtyScenes; } - StateMachine.GoToState(); + if (scenesDirty) + { + foreach (var scene in Level.Scenes) + Editor.Instance.Scene.MarkSceneEdited(scene); + } + Done(); } } - private sealed class CSGState : SubState + private abstract class ActionState : SubState { + public abstract GeneralOptions.BuildAction Action { get; } + } + + private sealed class CSGState : ActionState + { + public override GeneralOptions.BuildAction Action => GeneralOptions.BuildAction.CSG; + public override void OnEnter() { foreach (var scene in Level.Scenes) @@ -68,13 +117,14 @@ namespace FlaxEditor.States public override void Update() { if (!Editor.Internal_GetIsCSGActive()) - StateMachine.GoToState(); + Done(); } } - - private class EnvProbesNoGIState : SubState + private class EnvProbesState : ActionState { + public override GeneralOptions.BuildAction Action => GeneralOptions.BuildAction.EnvProbes; + public override void OnEnter() { Editor.Instance.Scene.ExecuteOnGraph(node => @@ -94,12 +144,20 @@ namespace FlaxEditor.States public override void Update() { if (!Editor.Instance.ProgressReporting.BakeEnvProbes.IsActive) - StateMachine.GoToState(); + Done(); } } - private sealed class StaticLightingState : SubState + private sealed class StaticLightingState : ActionState { + public override GeneralOptions.BuildAction Action => GeneralOptions.BuildAction.StaticLighting; + + public override void Before() + { + foreach (var scene in Level.Scenes) + scene.ClearLightmaps(); + } + public override void OnEnter() { Editor.LightmapsBakeEnd += OnLightmapsBakeEnd; @@ -110,7 +168,6 @@ namespace FlaxEditor.States OnLightmapsBakeEnd(false); } - /// public override void Cancel() { Editor.Internal_BakeLightmaps(true); @@ -125,21 +182,14 @@ namespace FlaxEditor.States private void OnLightmapsBakeEnd(bool failed) { - StateMachine.GoToState(); + Done(); } } - private sealed class EnvProbesWithGIState : EnvProbesNoGIState + private sealed class NavMeshState : ActionState { - public override void Update() - { - if (!Editor.Instance.ProgressReporting.BakeEnvProbes.IsActive) - StateMachine.GoToState(); - } - } + public override GeneralOptions.BuildAction Action => GeneralOptions.BuildAction.NavMesh; - private sealed class NavMeshState : SubState - { public override void OnEnter() { foreach (var scene in Level.Scenes) @@ -151,7 +201,58 @@ namespace FlaxEditor.States public override void Update() { if (!Navigation.IsBuildingNavMesh) - StateMachine.GoToState(); + Done(); + } + } + + private sealed class CompileScriptsState : ActionState + { + private bool _compiled, _reloaded; + + public override GeneralOptions.BuildAction Action => GeneralOptions.BuildAction.CompileScripts; + + public override bool DirtyScenes => false; + + public override bool CanReloadScripts => true; + + public override void OnEnter() + { + _compiled = _reloaded = false; + ScriptsBuilder.Compile(); + + ScriptsBuilder.CompilationSuccess += OnCompilationSuccess; + ScriptsBuilder.CompilationFailed += OnCompilationFailed; + ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd; + } + + public override void OnExit(State nextState) + { + ScriptsBuilder.CompilationSuccess -= OnCompilationSuccess; + ScriptsBuilder.CompilationFailed -= OnCompilationFailed; + ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd; + + base.OnExit(nextState); + } + + private void OnCompilationSuccess() + { + _compiled = true; + } + + private void OnCompilationFailed() + { + Cancel(); + } + + private void OnScriptsReloadEnd() + { + _reloaded = true; + } + + public override void Update() + { + if (_compiled && _reloaded) + Done(); } } @@ -173,10 +274,10 @@ namespace FlaxEditor.States _stateMachine.AddState(new BeginState()); _stateMachine.AddState(new SetupState()); _stateMachine.AddState(new CSGState()); - _stateMachine.AddState(new EnvProbesNoGIState()); + _stateMachine.AddState(new EnvProbesState()); _stateMachine.AddState(new StaticLightingState()); - _stateMachine.AddState(new EnvProbesWithGIState()); _stateMachine.AddState(new NavMeshState()); + _stateMachine.AddState(new CompileScriptsState()); _stateMachine.AddState(new EndState()); _stateMachine.GoToState(); } @@ -192,6 +293,9 @@ namespace FlaxEditor.States /// public override bool CanEditContent => false; + /// + public override bool CanReloadScripts => ((SubState)_stateMachine.CurrentState).CanReloadScripts; + /// public override bool IsPerformanceHeavy => true; @@ -215,6 +319,11 @@ namespace FlaxEditor.States { Editor.Log("Starting scenes build..."); _startTime = DateTime.Now; + _stateMachine.ActionIndex = -1; + _stateMachine.Actions.Clear(); + var actions = (GeneralOptions.BuildAction[])Editor.Options.Options.General.BuildActions?.Clone(); + if (actions != null) + _stateMachine.Actions.AddRange(actions); _stateMachine.GoToState(); } diff --git a/Source/Editor/States/EditingSceneState.cs b/Source/Editor/States/EditingSceneState.cs index 7aa9ce13d..176039948 100644 --- a/Source/Editor/States/EditingSceneState.cs +++ b/Source/Editor/States/EditingSceneState.cs @@ -1,6 +1,7 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using FlaxEngine; +using FlaxEngine.Utilities; namespace FlaxEditor.States { @@ -39,5 +40,26 @@ namespace FlaxEditor.States { UpdateFPS(); } + + /// + public override void OnEnter() + { + base.OnEnter(); + + ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin; + } + + /// + public override void OnExit(State nextState) + { + ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin; + + base.OnExit(nextState); + } + + private void OnScriptsReloadBegin() + { + StateMachine.GoToState(); + } } } diff --git a/Source/Editor/States/ReloadingScriptsState.cs b/Source/Editor/States/ReloadingScriptsState.cs index 17f1abdab..1fb34317d 100644 --- a/Source/Editor/States/ReloadingScriptsState.cs +++ b/Source/Editor/States/ReloadingScriptsState.cs @@ -1,6 +1,7 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using FlaxEngine; +using FlaxEngine.Utilities; namespace FlaxEditor.States { @@ -18,5 +19,26 @@ namespace FlaxEditor.States : base(editor) { } + + /// + public override void OnEnter() + { + base.OnEnter(); + + ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd; + } + + /// + public override void OnExit(State nextState) + { + ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd; + + base.OnExit(nextState); + } + + private void OnScriptsReloadEnd() + { + StateMachine.GoToState(); + } } } diff --git a/Source/Engine/Utilities/State.cs b/Source/Engine/Utilities/State.cs index f77308878..a0797ec0e 100644 --- a/Source/Engine/Utilities/State.cs +++ b/Source/Engine/Utilities/State.cs @@ -12,9 +12,6 @@ namespace FlaxEngine.Utilities /// /// Gets the state machine. /// - /// - /// The state machine. - /// public StateMachine StateMachine => owner; /// diff --git a/Source/Engine/Utilities/StateMachine.cs b/Source/Engine/Utilities/StateMachine.cs index 9966e3378..250d2fbe6 100644 --- a/Source/Engine/Utilities/StateMachine.cs +++ b/Source/Engine/Utilities/StateMachine.cs @@ -35,6 +35,11 @@ namespace FlaxEngine.Utilities /// public event Action StateChanged; + /// + /// Gets the states (read-only). + /// + public IReadOnlyList States => states; + /// /// Gets state of given type. ///