128 lines
4.3 KiB
C#
128 lines
4.3 KiB
C#
#nullable enable
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace ShrinkSDK.Runtime
|
|
{
|
|
public enum ShrinkLogLevel { Trace, Debug, Information, Warning, Error }
|
|
|
|
public interface IShrinkLogger
|
|
{
|
|
void Log(ShrinkLogLevel level, string message, Exception? exception = null);
|
|
}
|
|
|
|
public interface IShrinkMainThreadDispatcher
|
|
{
|
|
bool IsMainThread { get; }
|
|
bool TryPost(Action action);
|
|
}
|
|
|
|
public interface IShrinkClock
|
|
{
|
|
DateTimeOffset UtcNow { get; }
|
|
double UnscaledTimeSeconds { get; }
|
|
}
|
|
|
|
public interface IShrinkPathProvider
|
|
{
|
|
string PersistentDataPath { get; }
|
|
string TemporaryDataPath { get; }
|
|
}
|
|
|
|
public interface IShrinkScreenshotProvider
|
|
{
|
|
ValueTask<byte[]> CapturePngAsync(CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface IShrinkApplicationLifecycle
|
|
{
|
|
event Action? Paused;
|
|
event Action? Resumed;
|
|
event Action? Exiting;
|
|
}
|
|
|
|
public static class ShrinkLoggerExtensions
|
|
{
|
|
public static void Error(this IShrinkLogger logger, string message, Exception? exception = null) =>
|
|
logger.Log(ShrinkLogLevel.Error, message, exception);
|
|
}
|
|
|
|
public static class ShrinkRuntimeServices
|
|
{
|
|
private static IShrinkLogger _logger = new ConsoleLogger();
|
|
private static IShrinkMainThreadDispatcher _dispatcher = new InlineDispatcher();
|
|
private static IShrinkClock _clock = new SystemClock();
|
|
private static IShrinkPathProvider _paths = new SystemPaths();
|
|
|
|
public static IShrinkLogger Logger => _logger;
|
|
public static IShrinkMainThreadDispatcher Dispatcher => _dispatcher;
|
|
public static IShrinkClock Clock => _clock;
|
|
public static IShrinkPathProvider Paths => _paths;
|
|
public static IShrinkScreenshotProvider? Screenshots { get; private set; }
|
|
public static IShrinkApplicationLifecycle? Lifecycle { get; private set; }
|
|
|
|
public static void Configure(IShrinkLogger logger, IShrinkMainThreadDispatcher dispatcher,
|
|
IShrinkClock clock, IShrinkPathProvider paths,
|
|
IShrinkScreenshotProvider? screenshots = null, IShrinkApplicationLifecycle? lifecycle = null)
|
|
{
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
_dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
|
|
_clock = clock ?? throw new ArgumentNullException(nameof(clock));
|
|
_paths = paths ?? throw new ArgumentNullException(nameof(paths));
|
|
Screenshots = screenshots;
|
|
Lifecycle = lifecycle;
|
|
}
|
|
|
|
private sealed class ConsoleLogger : IShrinkLogger
|
|
{
|
|
public void Log(ShrinkLogLevel level, string message, Exception? exception = null)
|
|
{
|
|
Console.WriteLine($"[{level}] {message}");
|
|
if (exception != null) Console.WriteLine(exception);
|
|
}
|
|
}
|
|
|
|
private sealed class InlineDispatcher : IShrinkMainThreadDispatcher
|
|
{
|
|
public bool IsMainThread => true;
|
|
public bool TryPost(Action action)
|
|
{
|
|
if (action == null) return false;
|
|
action();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private sealed class SystemClock : IShrinkClock
|
|
{
|
|
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
|
|
public DateTimeOffset UtcNow => DateTimeOffset.UtcNow;
|
|
public double UnscaledTimeSeconds => _stopwatch.Elapsed.TotalSeconds;
|
|
}
|
|
|
|
private sealed class SystemPaths : IShrinkPathProvider
|
|
{
|
|
public string PersistentDataPath => Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ShrinkSDK");
|
|
public string TemporaryDataPath => Path.GetTempPath();
|
|
}
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
|
|
public sealed class ShrinkCodeGenWovenAttribute : Attribute
|
|
{
|
|
public ShrinkCodeGenWovenAttribute(string weaverVersion, string inputMvid)
|
|
{
|
|
WeaverVersion = weaverVersion;
|
|
InputMvid = inputMvid;
|
|
}
|
|
|
|
public string WeaverVersion { get; }
|
|
public string InputMvid { get; }
|
|
}
|
|
}
|