using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
namespace ADOFAIRenderer.API;
///
/// Represents the result and metadata of a completed or canceled render session.
///
///
/// Passed to the completion callback registered with . Immutable.
///
[SuppressMessage("ReSharper", "UnusedType.Global")]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
public class RenderResult
{
///
/// Indicates whether the rendering session completed successfully.
///
public bool Success { get; }
///
/// The output path of the rendered video file: the path given to as passed
/// (relative if it was relative), or the path of the time-stamped file in the output directory chosen in the mod
/// settings (by default <game root>/Render).
/// Empty string if rendering failed or was cancelled (the unfinished file is deleted).
///
public string OutputPath { get; }
///
/// Total number of video frames sent to the encoder.
///
public long TotalFrames { get; }
///
/// The calculated video duration in seconds: divided by the effective video frame rate
/// (min of the configured VideoFPS and RenderFPS); 0 when the frame rate is not positive.
///
public double VideoDuration { get; }
///
/// Total wall-clock time spent rendering, from the end of the countdown (start of capture) to the end of the render.
///
public TimeSpan RenderDuration { get; }
///
/// File size of the output video in bytes (0 if failed or file does not exist).
///
public long FileSizeBytes { get; }
///
/// Error message or reason if rendering failed or was canceled; null on success.
/// A cancelled render has "Rendering was cancelled by user."; a failed render has "Rendering failed: " followed by
/// the reason. Use to test the outcome; the texts are meant for display.
///
public string? ErrorMessage { get; }
///
/// Initializes a new instance of the class.
///
/// Whether the render session completed successfully.
/// The absolute output path of the rendered video file.
/// Total number of video frames sent to the encoder.
/// Calculated video duration in seconds.
/// Total wall-clock time spent rendering.
/// File size of the output video in bytes.
/// Error message or reason if failed or canceled; otherwise, null.
public RenderResult(
bool success,
string outputPath,
long totalFrames,
double videoDuration,
TimeSpan renderDuration,
long fileSizeBytes = 0,
string? errorMessage = null)
{
Success = success;
OutputPath = outputPath;
TotalFrames = totalFrames;
VideoDuration = videoDuration;
RenderDuration = renderDuration;
FileSizeBytes = fileSizeBytes;
ErrorMessage = errorMessage;
}
///
/// Creates a successful instance from the specified render metrics.
///
/// The path to the rendered video file.
/// Total number of video frames sent to the encoder.
/// The effective frames per second used to compute video duration.
/// Total wall-clock time spent rendering.
/// A new representing a successful render session.
/// The file size is read from disk; it is 0 when the file does not exist or cannot be read.
internal static RenderResult CreateSuccess(string outputPath, long totalFrames, double fps, TimeSpan renderDuration)
{
var fileSizeBytes = 0L;
if (!string.IsNullOrEmpty(outputPath) && File.Exists(outputPath))
{
try { fileSizeBytes = new FileInfo(outputPath).Length; }
catch { /* ignored */ }
}
var videoDuration = fps > 0 ? totalFrames / fps : 0.0;
return new RenderResult(true, outputPath, totalFrames, videoDuration, renderDuration, fileSizeBytes);
}
///
/// Creates a failed or cancelled instance.
///
/// Error message or reason for failure/cancellation.
/// Total number of video frames sent to the encoder prior to termination.
/// The effective frames per second used to compute video duration.
/// Total wall-clock time spent rendering prior to termination.
/// A new representing a failed or canceled render session.
/// OutputPath is empty and FileSizeBytes is 0. A null message is replaced by a generic one.
internal static RenderResult CreateFailure(string? errorMessage, long totalFrames, double fps, TimeSpan renderDuration)
{
var videoDuration = fps > 0 ? totalFrames / fps : 0.0;
return new RenderResult(false, string.Empty, totalFrames, videoDuration, renderDuration, 0, errorMessage ?? "Rendering failed or was cancelled.");
}
///
/// Returns a string summarizing the render result metrics or failure reason.
///
/// A string representation of the .
public override string ToString()
{
return Success
? $"[RenderResult: Success, Output={OutputPath}, Frames={TotalFrames}, VideoDuration={VideoDuration:F2}s, Time={RenderDuration.TotalSeconds:F1}s, Size={FileSizeBytes / 1024.0 / 1024.0:F2}MB]"
: $"[RenderResult: Failed/Cancelled, Error={ErrorMessage ?? "Unknown"}]";
}
}