feat(linux): add graphical platform services
This commit is contained in:
parent
1628d9f587
commit
66f114b258
28 changed files with 1328 additions and 155 deletions
102
src/AcDream.App/Platform/GraphicalHostPlatformServices.cs
Normal file
102
src/AcDream.App/Platform/GraphicalHostPlatformServices.cs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using AcDream.App.Rendering;
|
||||
using AcDream.Runtime.Platform;
|
||||
|
||||
namespace AcDream.App.Platform;
|
||||
|
||||
internal enum GraphicalHostOperatingSystem
|
||||
{
|
||||
Windows,
|
||||
Linux,
|
||||
}
|
||||
|
||||
internal sealed record GraphicalNativeDependency(
|
||||
string Feature,
|
||||
string PublishedFileName);
|
||||
|
||||
internal sealed record GraphicalHostPlatformServices(
|
||||
GraphicalHostOperatingSystem OperatingSystem,
|
||||
Architecture ProcessArchitecture,
|
||||
string RuntimeIdentifier,
|
||||
ApplicationPathSet Paths,
|
||||
IFramePacingWaiterFactory FramePacingWaiters,
|
||||
IReadOnlyList<GraphicalNativeDependency> NativeDependencies)
|
||||
{
|
||||
internal static GraphicalHostPlatformServices Resolve()
|
||||
{
|
||||
GraphicalHostOperatingSystem operatingSystem =
|
||||
DetectOperatingSystem();
|
||||
Architecture architecture = RuntimeInformation.ProcessArchitecture;
|
||||
string runtimeIdentifier = ResolveRuntimeIdentifier(
|
||||
operatingSystem,
|
||||
architecture);
|
||||
|
||||
return new GraphicalHostPlatformServices(
|
||||
operatingSystem,
|
||||
architecture,
|
||||
runtimeIdentifier,
|
||||
ApplicationPathSet.Resolve(),
|
||||
new PlatformFramePacingWaiterFactory(operatingSystem),
|
||||
ResolveNativeDependencies(operatingSystem));
|
||||
}
|
||||
|
||||
internal static GraphicalHostOperatingSystem DetectOperatingSystem()
|
||||
{
|
||||
if (System.OperatingSystem.IsWindows())
|
||||
return GraphicalHostOperatingSystem.Windows;
|
||||
if (System.OperatingSystem.IsLinux())
|
||||
return GraphicalHostOperatingSystem.Linux;
|
||||
|
||||
throw new PlatformNotSupportedException(
|
||||
"acdream graphical hosting supports Windows and Linux.");
|
||||
}
|
||||
|
||||
private static string ResolveRuntimeIdentifier(
|
||||
GraphicalHostOperatingSystem operatingSystem,
|
||||
Architecture architecture)
|
||||
{
|
||||
string architectureName = architecture switch
|
||||
{
|
||||
Architecture.X64 => "x64",
|
||||
Architecture.Arm64 => "arm64",
|
||||
Architecture.X86 => "x86",
|
||||
Architecture.Arm => "arm",
|
||||
_ => throw new PlatformNotSupportedException(
|
||||
$"Unsupported graphical process architecture {architecture}."),
|
||||
};
|
||||
|
||||
if (operatingSystem == GraphicalHostOperatingSystem.Linux
|
||||
&& architecture != Architecture.X64)
|
||||
{
|
||||
throw new PlatformNotSupportedException(
|
||||
"The first acdream Linux graphical package supports linux-x64 only.");
|
||||
}
|
||||
|
||||
string operatingSystemName =
|
||||
operatingSystem == GraphicalHostOperatingSystem.Windows
|
||||
? "win"
|
||||
: "linux";
|
||||
return $"{operatingSystemName}-{architectureName}";
|
||||
}
|
||||
|
||||
private static IReadOnlyList<GraphicalNativeDependency>
|
||||
ResolveNativeDependencies(
|
||||
GraphicalHostOperatingSystem operatingSystem) =>
|
||||
operatingSystem switch
|
||||
{
|
||||
GraphicalHostOperatingSystem.Windows =>
|
||||
[
|
||||
new("window/input", "glfw3.dll"),
|
||||
new("developer UI", "cimgui.dll"),
|
||||
new("audio", "soft_oal.dll"),
|
||||
],
|
||||
GraphicalHostOperatingSystem.Linux =>
|
||||
[
|
||||
new("window/input", "libglfw.so.3"),
|
||||
new("developer UI", "libcimgui.so"),
|
||||
new("audio", "libopenal.so"),
|
||||
],
|
||||
_ => throw new ArgumentOutOfRangeException(
|
||||
nameof(operatingSystem)),
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
using AcDream.Runtime.Platform;
|
||||
|
||||
namespace AcDream.App.Platform;
|
||||
|
||||
internal static class GraphicalLegacyConfigurationMigrator
|
||||
{
|
||||
private static readonly string[] FileNames =
|
||||
[
|
||||
"settings.json",
|
||||
"keybinds.json",
|
||||
];
|
||||
|
||||
internal static IReadOnlyList<string> Migrate(
|
||||
ApplicationPathSet paths)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(paths);
|
||||
if (paths.LegacyConfigDirectory is not { } legacyDirectory
|
||||
|| PathsEqual(legacyDirectory, paths.ConfigDirectory))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
List<string>? migrated = null;
|
||||
foreach (string fileName in FileNames)
|
||||
{
|
||||
string source = Path.Combine(legacyDirectory, fileName);
|
||||
string destination = Path.Combine(
|
||||
paths.ConfigDirectory,
|
||||
fileName);
|
||||
if (!File.Exists(source) || File.Exists(destination))
|
||||
continue;
|
||||
|
||||
Directory.CreateDirectory(paths.ConfigDirectory);
|
||||
File.Copy(source, destination, overwrite: false);
|
||||
(migrated ??= []).Add(destination);
|
||||
}
|
||||
|
||||
return migrated ?? [];
|
||||
}
|
||||
|
||||
private static bool PathsEqual(string left, string right) =>
|
||||
string.Equals(
|
||||
Path.TrimEndingDirectorySeparator(
|
||||
Path.GetFullPath(left)),
|
||||
Path.TrimEndingDirectorySeparator(
|
||||
Path.GetFullPath(right)),
|
||||
OperatingSystem.IsWindows()
|
||||
? StringComparison.OrdinalIgnoreCase
|
||||
: StringComparison.Ordinal);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue