feat(linux): add graphical platform services

This commit is contained in:
Erik 2026-07-27 11:54:59 +02:00
parent 1628d9f587
commit 66f114b258
28 changed files with 1328 additions and 155 deletions

View file

@ -1,4 +1,5 @@
using AcDream.Headless.Configuration;
using AcDream.Runtime.Platform;
namespace AcDream.Headless.Platform;
@ -14,86 +15,24 @@ internal sealed record HeadlessPathSet(
ArgumentNullException.ThrowIfNull(overrides);
platform ??= HeadlessPlatformEnvironment.Instance;
string config;
string data;
string cache;
if (platform.IsWindows)
try
{
string roaming = RequireFolder(
platform,
Environment.SpecialFolder.ApplicationData);
string local = RequireFolder(
platform,
Environment.SpecialFolder.LocalApplicationData);
config = Path.Combine(roaming, "acdream");
data = Path.Combine(local, "acdream");
cache = Path.Combine(local, "acdream", "cache");
ApplicationPathSet paths = ApplicationPathSet.Resolve(
overrides.ConfigDirectory,
overrides.DataDirectory,
overrides.CacheDirectory,
platform);
return new HeadlessPathSet(
paths.ConfigDirectory,
paths.DataDirectory,
paths.CacheDirectory);
}
else
catch (Exception exception)
when (exception is ArgumentException
or InvalidOperationException
or NotSupportedException)
{
string home = RequireFolder(
platform,
Environment.SpecialFolder.UserProfile);
config = ResolveXdg(
platform,
"XDG_CONFIG_HOME",
Path.Combine(home, ".config"),
"acdream");
data = ResolveXdg(
platform,
"XDG_DATA_HOME",
Path.Combine(home, ".local", "share"),
"acdream");
cache = ResolveXdg(
platform,
"XDG_CACHE_HOME",
Path.Combine(home, ".cache"),
"acdream");
throw new HeadlessConfigurationException(exception.Message);
}
return new HeadlessPathSet(
Normalize(overrides.ConfigDirectory ?? config, platform),
Normalize(overrides.DataDirectory ?? data, platform),
Normalize(overrides.CacheDirectory ?? cache, platform));
}
private static string ResolveXdg(
IHeadlessPlatformEnvironment platform,
string variable,
string fallback,
string leaf)
{
string? configured = platform.GetEnvironmentVariable(variable);
string root = string.IsNullOrWhiteSpace(configured)
? fallback
: configured;
return Path.Combine(root, leaf);
}
private static string RequireFolder(
IHeadlessPlatformEnvironment platform,
Environment.SpecialFolder folder)
{
string value = platform.GetFolderPath(folder);
if (string.IsNullOrWhiteSpace(value))
{
throw new HeadlessConfigurationException(
$"The operating system did not provide {folder}.");
}
return value;
}
private static string Normalize(
string path,
IHeadlessPlatformEnvironment platform)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new HeadlessConfigurationException(
"Headless directories cannot be empty.");
}
return Path.TrimEndingDirectorySeparator(
Path.GetFullPath(path, platform.CurrentDirectory));
}
}

View file

@ -1,11 +1,10 @@
using AcDream.Runtime.Platform;
namespace AcDream.Headless.Platform;
internal interface IHeadlessPlatformEnvironment
: IApplicationPathEnvironment
{
bool IsWindows { get; }
string CurrentDirectory { get; }
string? GetEnvironmentVariable(string name);
string GetFolderPath(Environment.SpecialFolder folder);
}
internal sealed class HeadlessPlatformEnvironment