using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using ADOFAIRenderer.Core;
using ADOFAIRenderer.Data;
using ADOFAIRenderer.Util;
namespace ADOFAIRenderer.API;
///
/// Fluent builder for configuring and starting a render session.
///
[SuppressMessage("ReSharper", "UnusedType.Global")]
public class RenderSession
{
private bool _auto = true;
///
/// Specifies the types of patches that can be configured for a render session.
///
public enum PatchType
{
///
/// Time-related patch controlling frame timing and clock synchronization.
///
Time,
///
/// Screen-related patch controlling screen resolution.
///
Screen
}
private bool _timePatch = true;
private bool _screenPatch = true;
private string? _outputPath;
private bool _notification = true;
private Func? _endCondition;
private Action? _onComplete;
private Action? _onLastUpdate;
///
/// Sets whether auto mode is enabled.
///
/// true to enable auto mode; otherwise, false. Default is true.
/// The current instance for method chaining.
public RenderSession WithAuto(bool enabled = true)
{
_auto = enabled;
return this;
}
///
/// Sets whether a specific patch type is enabled for the render session.
///
/// The to configure.
/// true to enable the specified patch; otherwise, false. Default is true.
/// The current instance for method chaining.
/// Thrown when an unsupported is provided.
public RenderSession WithPatch(PatchType patchType, bool enabled = true)
{
switch (patchType)
{
case PatchType.Time: _timePatch = enabled; break;
case PatchType.Screen: _screenPatch = enabled; break;
default: throw new ArgumentOutOfRangeException(nameof(patchType), patchType, null);
}
return this;
}
///
/// Sets the custom condition function that determines when the render session should end.
///
/// A delegate returning true when the session end condition is met.
/// The current instance for method chaining.
public RenderSession WithEndCondition(Func endCondition)
{
_endCondition = endCondition;
return this;
}
///
/// Sets the custom output path for the rendered file.
///
/// The file path where the output will be saved, or null to use the default capture directory.
/// The current instance for method chaining.
public RenderSession WithOutputPath(string? outputPath)
{
_outputPath = outputPath;
return this;
}
///
/// Sets whether desktop notifications should be displayed when rendering completes.
///
/// true to enable desktop notifications; otherwise, false.
/// The current instance for method chaining.
public RenderSession WithNotification(bool enabled)
{
_notification = enabled;
return this;
}
///
/// Adds a callback action to be invoked when the render session completes or fails.
///
/// The callback action that receives the resulting .
/// The current instance for method chaining.
public RenderSession OnComplete(Action callback)
{
_onComplete += callback;
return this;
}
///
/// Adds a callback action to be invoked on the last update of each frame in the render session.
///
/// The callback action to execute.
/// The current instance for method chaining.
public RenderSession OnLastUpdate(Action callback)
{
_onLastUpdate += callback;
return this;
}
///
/// Applies the configured flags and initiates the render session.
///
/// The configuration settings for the render session.
/// The file path of the level to render.
/// Thrown when the output directory cannot be determined from the output path.
public void Start(RenderConfig renderConfig, string levelPath)
{
RenderContext.Auto = _auto;
RenderContext.TimePatch = _timePatch;
RenderContext.ScreenPatch = _screenPatch;
RenderContext.OutputPath = _outputPath;
RenderContext.Notification = _notification;
if (_endCondition is not null) RenderContext.EndCondition = _endCondition;
if (_onComplete is not null) RenderContext.OnComplete = _onComplete;
if (_onLastUpdate is not null) RenderContext.OnLastUpdate = _onLastUpdate;
RenderManager.Instance.levelPath = levelPath;
RenderManager.Instance.Configuration = renderConfig;
RenderManager.Instance.stage = RenderStage.Load;
if (_outputPath is null) RenderManager.Instance.SetupCaptureDirectory();
else FileUtil.CreateDirectory(Path.GetDirectoryName(_outputPath) ?? throw new InvalidOperationException());
RenderManager.Instance.SetupGameScene();
}
}