// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using FlaxEngine;
namespace FlaxEditor.Progress
{
///
/// Base class for all editor handlers used to report actions progress to the user.
///
[HideInEditor]
public abstract class ProgressHandler
{
///
/// Progress handler events delegate.
///
/// The calling handler.
public delegate void ProgressDelegate(ProgressHandler handler);
///
/// Progress failed handler event delegate
///
public delegate void ProgressFailedDelegate(ProgressHandler handler, string message);
private float _progress;
private bool _isActive;
private string _infoText;
///
/// Gets a value indicating whether this handler is active.
///
public bool IsActive => _isActive;
///
/// Gets the current progress (normalized to range [0;1]).
///
public float Progress => _progress;
///
/// Gets the information text.
///
public string InfoText => _infoText;
///
/// Occurs when progress starts (becomes active).
///
public event ProgressDelegate ProgressStart;
///
/// Occurs when progress gets changed (or info text changes).
///
public event ProgressDelegate ProgressChanged;
///
/// Occurs when progress end (becomes inactive).
///
public event ProgressDelegate ProgressEnd;
///
/// Occurs when the progress fails
///
public event ProgressFailedDelegate ProgressFailed;
///
/// Gets a value indicating whether this handler action can be cancelled.
///
public virtual bool CanBeCanceled => false;
///
/// Cancels this progress action.
///
public void Cancel()
{
throw new InvalidOperationException("Cannot cancel this progress action.");
}
///
/// Called when progress action starts.
///
protected virtual void OnStart()
{
if (_isActive)
throw new InvalidOperationException("Already started.");
_isActive = true;
_progress = 0;
_infoText = string.Empty;
ProgressStart?.Invoke(this);
ProgressChanged?.Invoke(this);
}
///
/// Called when progress action gets updated (changed info text or progress value).
///
/// The progress (normalized to range [0;1]).
/// The information text.
protected virtual void OnUpdate(float progress, string infoText)
{
progress = Mathf.Saturate(progress);
if (!Mathf.NearEqual(progress, _progress) || infoText != _infoText)
{
_progress = progress;
_infoText = infoText;
ProgressChanged?.Invoke(this);
}
}
///
/// Called when progress action ends.
///
protected virtual void OnEnd()
{
if (!_isActive)
throw new InvalidOperationException("Already ended.");
_isActive = false;
_progress = 0;
_infoText = string.Empty;
ProgressChanged?.Invoke(this);
ProgressEnd?.Invoke(this);
}
///
/// Called when progress action fails
///
protected virtual void OnFail(string message)
{
if (!_isActive)
throw new InvalidOperationException("Already ended.");
_isActive = false;
_progress = 0;
_infoText = string.Empty;
ProgressFailed?.Invoke(this, message);
}
}
}