Skip to content

Commit

Permalink
Merge pull request #11930 from AvaloniaUI/cleanup-runtime-platform-in…
Browse files Browse the repository at this point in the history
…terface

Cleanup runtime platform classes #2
  • Loading branch information
maxkatz6 committed Jun 30, 2023
2 parents fddb07e + 6499bbd commit 54d1806
Show file tree
Hide file tree
Showing 27 changed files with 270 additions and 321 deletions.
1 change: 1 addition & 0 deletions src/Android/Avalonia.Android/AndroidPlatform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public static class AndroidApplicationExtensions
public static AppBuilder UseAndroid(this AppBuilder builder)
{
return builder
.UseStandardRuntimePlatformSubsystem()
.UseWindowingSubsystem(() => AndroidPlatform.Initialize(), "Android")
.UseSkia();
}
Expand Down
122 changes: 122 additions & 0 deletions src/Avalonia.Base/Compatibility/NativeLibrary.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
using Avalonia.Compatibility;
using Avalonia.Platform.Interop;

namespace Avalonia.Compatibility
{
internal class NativeLibraryEx
{
#if NET6_0_OR_GREATER
public static IntPtr Load(string dll, Assembly assembly) => NativeLibrary.Load(dll, assembly, null);
public static IntPtr Load(string dll) => NativeLibrary.Load(dll);
public static bool TryGetExport(IntPtr handle, string name, out IntPtr address) =>
NativeLibrary.TryGetExport(handle, name, out address);
#else
public static IntPtr Load(string dll, Assembly assembly) => Load(dll);
public static IntPtr Load(string dll)
{
var handle = DlOpen!(dll);
if (handle != IntPtr.Zero)
return handle;
throw new InvalidOperationException("Unable to load " + dll, DlError!());
}

public static bool TryGetExport(IntPtr handle, string name, out IntPtr address)
{
try
{
address = DlSym!(handle, name);
return address != default;
}
catch (Exception)
{
address = default;
return false;
}
}

static NativeLibraryEx()
{
if (OperatingSystemEx.IsWindows())
{
Win32Imports.Init();
}
else if (OperatingSystemEx.IsLinux() || OperatingSystemEx.IsMacOS())
{
var buffer = Marshal.AllocHGlobal(0x1000);
uname(buffer);
var unixName = Marshal.PtrToStringAnsi(buffer);
Marshal.FreeHGlobal(buffer);
if (unixName == "Darwin")
OsXImports.Init();
else
LinuxImports.Init();
}
}

private static Func<string, IntPtr>? DlOpen;
private static Func<IntPtr, string, IntPtr>? DlSym;
private static Func<Exception?>? DlError;

[DllImport("libc")]
static extern int uname(IntPtr buf);

static class Win32Imports
{
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32", EntryPoint = "LoadLibraryW", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern IntPtr LoadLibrary(string lpszLib);

public static void Init()
{
DlOpen = LoadLibrary;
DlSym = GetProcAddress;
DlError = () => new Win32Exception(Marshal.GetLastWin32Error());
}
}

static class LinuxImports
{
[DllImport("libdl.so.2")]
private static extern IntPtr dlopen(string path, int flags);

[DllImport("libdl.so.2")]
private static extern IntPtr dlsym(IntPtr handle, string symbol);

[DllImport("libdl.so.2")]
private static extern IntPtr dlerror();

public static void Init()
{
DlOpen = s => dlopen(s, 1);
DlSym = dlsym;
DlError = () => new InvalidOperationException(Marshal.PtrToStringAnsi(dlerror()));
}
}

static class OsXImports
{
[DllImport("/usr/lib/libSystem.dylib")]
private static extern IntPtr dlopen(string path, int flags);

[DllImport("/usr/lib/libSystem.dylib")]
private static extern IntPtr dlsym(IntPtr handle, string symbol);

[DllImport("/usr/lib/libSystem.dylib")]
private static extern IntPtr dlerror();

public static void Init()
{
DlOpen = s => dlopen(s, 1);
DlSym = dlsym;
DlError = () => new InvalidOperationException(Marshal.PtrToStringAnsi(dlerror()));
}
}
#endif
}
}
16 changes: 2 additions & 14 deletions src/Avalonia.Base/Platform/IRuntimePlatform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,13 @@

namespace Avalonia.Platform
{
[Unstable]
[PrivateApi]
public interface IRuntimePlatform
{
IDisposable StartSystemTimer(TimeSpan interval, Action tick);
RuntimePlatformInfo GetRuntimeInfo();
IUnmanagedBlob AllocBlob(int size);
}

[Unstable]
public interface IUnmanagedBlob : IDisposable
{
IntPtr Address { get; }
int Size { get; }
bool IsDisposed { get; }

}

[Unstable]
[PrivateApi]
public record struct RuntimePlatformInfo
{
public FormFactorType FormFactor => IsDesktop ? FormFactorType.Desktop :
Expand All @@ -29,7 +18,6 @@ public record struct RuntimePlatformInfo
public bool IsMobile { get; set; }
}

[Unstable]
public enum FormFactorType
{
Unknown,
Expand Down
161 changes: 0 additions & 161 deletions src/Avalonia.Base/Platform/Internal/DynLoader.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/Avalonia.Base/Platform/Internal/UnmanagedBlob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Avalonia.Platform.Internal;

internal class UnmanagedBlob : IUnmanagedBlob
internal class UnmanagedBlob
{
private IntPtr _address;
private readonly object _lock = new object();
Expand Down
24 changes: 0 additions & 24 deletions src/Avalonia.Base/Platform/Interop/IDynamicLibraryLoader.cs

This file was deleted.

12 changes: 3 additions & 9 deletions src/Avalonia.Base/Platform/StandardRuntimePlatform.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
using System;
using System.Threading;
using Avalonia.Compatibility;
using Avalonia.Metadata;
using Avalonia.Platform.Internal;

namespace Avalonia.Platform
{
[PrivateApi]
public class StandardRuntimePlatform : IRuntimePlatform
{
public IDisposable StartSystemTimer(TimeSpan interval, Action tick)
{
return new Timer(_ => tick(), null, interval, interval);
}

public IUnmanagedBlob AllocBlob(int size) => new UnmanagedBlob(size);

private static readonly RuntimePlatformInfo s_info = new()
{
IsDesktop = OperatingSystemEx.IsWindows() || OperatingSystemEx.IsMacOS() || OperatingSystemEx.IsLinux(),
IsMobile = OperatingSystemEx.IsAndroid() || OperatingSystemEx.IsIOS()
};



public virtual RuntimePlatformInfo GetRuntimeInfo() => s_info;
}
}
Loading

0 comments on commit 54d1806

Please sign in to comment.