From 2ef1b24042833f78697a89ee8fcbff3b9b9fce6a Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Mon, 29 Mar 2021 12:09:46 +0200 Subject: [PATCH] Further simplified mechanism for creating and pinning callbacks. We don't care about the individual GCHandles so just throw them into a list for easy management. --- Assets/Scripts/Uniquake.cs | 65 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/Assets/Scripts/Uniquake.cs b/Assets/Scripts/Uniquake.cs index 7c65509..19ef280 100644 --- a/Assets/Scripts/Uniquake.cs +++ b/Assets/Scripts/Uniquake.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using UnityEngine; -using UnityEngine.Events; public class Uniquake: MonoBehaviour { @@ -75,7 +74,7 @@ public class Uniquake: MonoBehaviour } [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - private static extern void Uniquake_Echo(UnityCallbacks.DebugLogCallback logCallback, [MarshalAs(UnmanagedType.LPStr)] string message); + private static extern void Uniquake_Echo(DebugLogCallback logCallback, [MarshalAs(UnmanagedType.LPStr)] string message); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] private static extern void Uniquake_Init(IntPtr callbacks, QuakeParms parms); @@ -83,19 +82,25 @@ public class Uniquake: MonoBehaviour [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] private static extern void Uniquake_Update(float deltaTime); - [AOT.MonoPInvokeCallback(typeof(UnityCallbacks.DebugLogCallback))] + private delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)] string message); + + [AOT.MonoPInvokeCallback(typeof(DebugLogCallback))] private static void Callback_DebugLog(string message) { Debug.Log(message); } + + private delegate void DebugLogErrorCallback([MarshalAs(UnmanagedType.LPStr)] string message); - [AOT.MonoPInvokeCallback(typeof(UnityCallbacks.DebugLogErrorCallback))] + [AOT.MonoPInvokeCallback(typeof(DebugLogErrorCallback))] private static void Callback_DebugLogError(string message) { Debug.LogError(message); } - [AOT.MonoPInvokeCallback(typeof(UnityCallbacks.ApplicationQuitCallback))] + private delegate void ApplicationQuitCallback(int exitCode); + + [AOT.MonoPInvokeCallback(typeof(ApplicationQuitCallback))] private static void Callback_ApplicationQuit(int exitCode) { Debug.Log($"Quitting application with exit code: {exitCode}"); @@ -103,26 +108,29 @@ public class Uniquake: MonoBehaviour Application.Quit(exitCode); } - [AOT.MonoPInvokeCallback(typeof(UnityCallbacks.RealtimeSinceStartupCallback))] + private delegate double RealtimeSinceStartupCallback(); + + [AOT.MonoPInvokeCallback(typeof(RealtimeSinceStartupCallback))] private static double Callback_RealtimeSinceStartup() { return Time.realtimeSinceStartupAsDouble; } - private class UnityCallbacks { + private List handles = new List(); private UnityCallbacksContainer container; private GCHandle containerHandle; public UnityCallbacks() { - container = new UnityCallbacksContainer(); - - CreateCallback(Callback_DebugLog, out DebugLogHandle, out container.DebugLogPtr); - CreateCallback(Callback_DebugLogError, out DebugLogErrorHandle, out container.DebugLogErrorPtr); - CreateCallback(Callback_ApplicationQuit, out ApplicationQuitHandle, out container.ApplicationQuitPtr); - CreateCallback(Callback_RealtimeSinceStartup, out RealtimeSinceStartupHandle, out container.RealtimeSinceStartupPtr); + container = new UnityCallbacksContainer + { + DebugLogPtr = CreateCallback(Callback_DebugLog), + DebugLogErrorPtr = CreateCallback(Callback_DebugLogError), + ApplicationQuitPtr = CreateCallback(Callback_ApplicationQuit), + RealtimeSinceStartupPtr = CreateCallback(Callback_RealtimeSinceStartup), + }; containerHandle = GCHandle.Alloc(container, GCHandleType.Pinned); } @@ -131,30 +139,21 @@ public class Uniquake: MonoBehaviour public void Destroy() { - containerHandle.Free(); - DebugLogHandle.Free(); - DebugLogErrorHandle.Free(); - ApplicationQuitHandle.Free(); - RealtimeSinceStartupHandle.Free(); + if (containerHandle.IsAllocated) + containerHandle.Free(); + + foreach (var handle in handles) + { + if (handle.IsAllocated) + handle.Free(); + } } - private static void CreateCallback(TDelegate callback, out GCHandle handle, out IntPtr ptr) + private IntPtr CreateCallback(TDelegate callback) { - handle = GCHandle.Alloc(callback); - ptr = Marshal.GetFunctionPointerForDelegate(callback); + handles.Add(GCHandle.Alloc(callback)); + return Marshal.GetFunctionPointerForDelegate(callback); } - - public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)] string message); - private GCHandle DebugLogHandle; - - public delegate void DebugLogErrorCallback([MarshalAs(UnmanagedType.LPStr)] string message); - private GCHandle DebugLogErrorHandle; - - public delegate void ApplicationQuitCallback(int exitCode); - private GCHandle ApplicationQuitHandle; - - public delegate double RealtimeSinceStartupCallback(); - private GCHandle RealtimeSinceStartupHandle; } [StructLayout(LayoutKind.Sequential, Pack = 0)]