// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; using System.Linq; using FlaxEditor.Progress; using FlaxEditor.Progress.Handlers; namespace FlaxEditor.Modules { /// /// Helper module for engine long-operations progress reporting in the editor (eg. files importing, static light baking, etc.). /// /// public sealed class ProgressReportingModule : EditorModule { private readonly List _handlers = new List(8); /// /// The game building progress handler. /// public readonly BuildingGameProgress BuildingGame = new BuildingGameProgress(); /// /// The assets importing progress handler. /// public readonly ImportAssetsProgress ImportAssets = new ImportAssetsProgress(); /// /// The scripts compilation progress handler. /// public readonly CompileScriptsProgress CompileScripts = new CompileScriptsProgress(); /// /// The lightmaps baking progress handler. /// public readonly BakeLightmapsProgress BakeLightmaps = new BakeLightmapsProgress(); /// /// The environment probes baking progress handler. /// public readonly BakeEnvProbesProgress BakeEnvProbes = new BakeEnvProbesProgress(); /// /// The code editor async open progress handler. /// public readonly CodeEditorOpenProgress CodeEditorOpen = new CodeEditorOpenProgress(); /// /// The navigation mesh building progress handler. /// public readonly NavMeshBuildingProgress NavMeshBuilding = new NavMeshBuildingProgress(); /// /// The scripts project files generation progress handler. /// public readonly GenerateScriptsProjectFilesProgress GenerateScriptsProjectFiles = new GenerateScriptsProjectFilesProgress(); /// /// Gets the first active handler. /// public ProgressHandler FirstActiveHandler => _handlers.FirstOrDefault(x => x.IsActive); /// /// Gets a value indicating whether any progress handler is active. /// public bool IsAnyActive => FirstActiveHandler != null; internal ProgressReportingModule(Editor editor) : base(editor) { InitOrder = 1000; // Register common handlers RegisterHandler(BuildingGame); RegisterHandler(ImportAssets); RegisterHandler(CompileScripts); RegisterHandler(BakeLightmaps); RegisterHandler(BakeEnvProbes); RegisterHandler(CodeEditorOpen); RegisterHandler(NavMeshBuilding); RegisterHandler(GenerateScriptsProjectFiles); } /// /// Registers the handler. /// /// The handler. public void RegisterHandler(ProgressHandler handler) { if (handler == null) throw new ArgumentNullException(); _handlers.Add(handler); handler.ProgressStart += HandlerOnProgressStart; handler.ProgressChanged += HandlerOnProgressChanged; handler.ProgressEnd += HandlerOnProgressEnd; } /// /// Unregisters the handler. /// /// The handler. public void UnregisterHandler(ProgressHandler handler) { if (handler == null) throw new ArgumentNullException(); if (_handlers.Remove(handler) == false) throw new InvalidOperationException("Cannot unregister not registered handler"); handler.ProgressStart -= HandlerOnProgressStart; handler.ProgressChanged -= HandlerOnProgressChanged; handler.ProgressEnd -= HandlerOnProgressEnd; } private void UpdateProgress() { var activeHandler = FirstActiveHandler; bool showProgress = activeHandler != null; Editor.UI.ProgressVisible = showProgress; if (showProgress) { Editor.UI.UpdateProgress(activeHandler.InfoText, activeHandler.Progress); } else { Editor.UI.UpdateProgress(string.Empty, 0); } } private void HandlerOnProgressStart(ProgressHandler handler) { UpdateProgress(); } private void HandlerOnProgressChanged(ProgressHandler handler) { UpdateProgress(); } private void HandlerOnProgressEnd(ProgressHandler handler) { UpdateProgress(); // Flash main window when no stuff to wait for (user could come back to app) if (!IsAnyActive) { Editor.Windows.FlashMainWindow(); } } } }