You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

102 lines
2.8 KiB

using System;
using System.Runtime.InteropServices;
using UnityEngine;
public class SysCalls: CallbackHandler<SysCalls>
{
private readonly UniQuake uq;
private readonly double startTime;
private Callbacks callbacks;
private GCHandle callbacksHandle;
public IntPtr CallbacksPtr => callbacksHandle.AddrOfPinnedObject();
public SysCalls(UniQuake uniQuake)
{
uq = uniQuake;
startTime = Time.timeAsDouble;
callbacks = new Callbacks
{
SysPrint = CreateCallback<SysPrintCallback>(Callback_SysPrint),
SysError = CreateCallback<SysErrorCallback>(Callback_SysError),
SysQuit = CreateCallback<SysQuitCallback>(Callback_SysQuit),
SysFloatTime = CreateCallback<SysFloatTimeCallback>(Callback_SysFloatTime),
};
callbacksHandle = GCHandle.Alloc(callbacks, GCHandleType.Pinned);
}
public override void Destroy()
{
if (callbacksHandle.IsAllocated)
callbacksHandle.Free();
base.Destroy();
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class Callbacks
{
public IntPtr SysPrint;
public IntPtr SysError;
public IntPtr SysQuit;
public IntPtr SysFloatTime;
}
private delegate void SysPrintCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string message);
[AOT.MonoPInvokeCallback(typeof(SysPrintCallback))]
private static void Callback_SysPrint(IntPtr target, string message)
{
GetSelf(target).Print(message);
}
private void Print(string message)
{
Debug.Log(message);
}
private delegate void SysErrorCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string message);
[AOT.MonoPInvokeCallback(typeof(SysErrorCallback))]
private static void Callback_SysError(IntPtr target, string message)
{
GetSelf(target).Error(message);
}
private void Error(string message)
{
Debug.LogError(message);
// TODO: kill execution of the DLL entirely (Sys_Quit expects immediate exit, which this doesn't do)
Application.Quit(1);
}
private delegate void SysQuitCallback(IntPtr target);
[AOT.MonoPInvokeCallback(typeof(SysQuitCallback))]
private static void Callback_SysQuit(IntPtr target)
{
GetSelf(target).Quit();
}
private void Quit()
{
Debug.Log($"Quitting application normally");
Application.Quit(0);
}
private delegate double SysFloatTimeCallback(IntPtr target);
[AOT.MonoPInvokeCallback(typeof(SysFloatTimeCallback))]
private static double Callback_SysFloatTime(IntPtr target)
{
return GetSelf(target).FloatTime();
}
private double FloatTime()
{
return Time.timeAsDouble - startTime;
}
}