mirror of
https://github.com/ZuneDev/MicrosoftIris.git
synced 2026-07-27 13:13:29 -07:00
More engine API work
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.Iris.Render.Engine;
|
||||
|
||||
// Every UIXrender export that hands an opaque "pointer" back to a caller (schema objects,
|
||||
// XML readers, rich-text objects, bitmaps, data queries, ...) uses this: the managed
|
||||
// object is pinned by a GCHandle and the caller only ever sees the GCHandle's IntPtr.
|
||||
// This is the same convention SpRenderThreadInit already established for its thread
|
||||
// handle -- centralised here so ~10 subsystems don't each re-derive it.
|
||||
//
|
||||
// Deliberately not a "real" pointer: the original native library handed out genuine C++
|
||||
// object pointers, but nothing outside UIXrender is allowed to dereference these (the
|
||||
// managed declarations all type them as opaque IntPtr/HANDLE), so an indirection is
|
||||
// both safe and much harder to corrupt.
|
||||
internal static class HandleTable
|
||||
{
|
||||
public static IntPtr Alloc(object value) =>
|
||||
value == null ? IntPtr.Zero : GCHandle.ToIntPtr(GCHandle.Alloc(value, GCHandleType.Normal));
|
||||
|
||||
public static T Get<T>(IntPtr handle) where T : class =>
|
||||
handle == IntPtr.Zero ? null : GCHandle.FromIntPtr(handle).Target as T;
|
||||
|
||||
public static bool TryGet<T>(IntPtr handle, out T value) where T : class
|
||||
{
|
||||
value = Get<T>(handle);
|
||||
return value != null;
|
||||
}
|
||||
|
||||
public static void Free(IntPtr handle)
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
return;
|
||||
|
||||
GCHandle gc = GCHandle.FromIntPtr(handle);
|
||||
if (gc.IsAllocated)
|
||||
{
|
||||
(gc.Target as IDisposable)?.Dispose();
|
||||
gc.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user