// Copyright (c) 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();
///
/// The assets loading progress handler.
///
public readonly LoadAssetsProgress LoadAssets = new LoadAssetsProgress();
///
/// 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);
RegisterHandler(LoadAssets);
}
///
/// 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;
handler.ProgressFailed += HandlerOnProgressFail;
}
///
/// 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;
handler.ProgressFailed -= HandlerOnProgressFail;
}
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);
Editor.UI.UpdateStatusBar();
}
}
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();
}
}
private void HandlerOnProgressFail(ProgressHandler handler, string message)
{
UpdateProgress();
Editor.UI.ProgressFailed(message);
}
}
}