using System.Diagnostics; namespace lib; public readonly ref struct Defer { private readonly Action _onDispose; public Defer( Action onDispose ) { _onDispose = onDispose; } public void Dispose() { _onDispose?.Invoke(); } public static Defer Do( Action action ) => new Defer( action ); } public readonly ref struct Timed { private readonly long _startTimestamp; private readonly Action _onDispose; public Timed( Action onDispose ) { _onDispose = onDispose; _startTimestamp = Stopwatch.GetTimestamp(); } public void Dispose() { // Calculate elapsed ticks long endTimestamp = Stopwatch.GetTimestamp(); long elapsedTicks = endTimestamp - _startTimestamp; // Convert to TimeSpan based on system timer frequency // (Standard formula for high-resolution timing) double seconds = (double)elapsedTicks / Stopwatch.Frequency; var elapsed = TimeSpan.FromSeconds( seconds ); _onDispose?.Invoke( elapsed ); } // Optional: Allow peeking at the time without stopping public TimeSpan Elapsed { get { long current = Stopwatch.GetTimestamp(); return TimeSpan.FromSeconds( (double)( current - _startTimestamp ) / Stopwatch.Frequency ); } } public static Timed Do( Action action ) => new Timed( action ); } static public class Exec { static public void RunIf( bool condition, Action func ) { if( condition ) func(); } static public T RunIf( bool condition, Func func, T ret = default! ) { if( condition ) return func(); return ret; } }