Browse Source

Split all of the callback modules' native interop boilerplate code off into separate partial class files, to keep the actual logic code clean and easy to read.

console
Nico de Poel 5 years ago
parent
commit
754812d63e
  1. 61
      Assets/Scripts/Modules/RenderModule.Interop.cs
  2. 3
      Assets/Scripts/Modules/RenderModule.Interop.cs.meta
  3. 60
      Assets/Scripts/Modules/RenderModule.cs
  4. 161
      Assets/Scripts/Modules/SystemModule.Interop.cs
  5. 3
      Assets/Scripts/Modules/SystemModule.Interop.cs.meta
  6. 156
      Assets/Scripts/Modules/SystemModule.cs

61
Assets/Scripts/Modules/RenderModule.Interop.cs

@ -0,0 +1,61 @@
using System;
using System.Runtime.InteropServices;
using AOT;
using UnityEngine;
public partial class RenderModule: CallbackHandler<RenderModule>
{
private const int MaxAliasFrames = 256; // Should match MAXALIASFRAMES
private void BuildCallbacks()
{
var callbacks = new Callbacks
{
target = TargetPtr,
UploadAliasModel = CreateCallback<UploadAliasModelCallback>(Callback_UploadAliasModel),
};
RegisterCallbacks(callbacks);
}
/// <summary>
/// This matches unity_modcalls_t from mod_uniquake.c in native code.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class Callbacks
{
public IntPtr target;
public IntPtr UploadAliasModel;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private delegate int UploadAliasModelCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string name,
QAliasHeader header, IntPtr frames, [MarshalAs(UnmanagedType.LPArray, SizeConst = MaxAliasFrames)]
IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts);
[MonoPInvokeCallback(typeof(UploadAliasModelCallback))]
private static int Callback_UploadAliasModel(IntPtr target, string name, QAliasHeader header, IntPtr frames,
IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts)
{
if (header == null)
{
Debug.LogWarning($"Uploading invalid alias model, name = {name}");
return 0;
}
if (frames != IntPtr.Zero)
header.frames = frames.ToStructArray<QAliasFrameDesc>(header.numFrames);
var poseVertices = new QTriVertex[header.numFrames][];
for (int i = 0; i < header.numFrames && i < MaxAliasFrames; ++i)
{
poseVertices[i] = poseVerts[i].ToStructArray<QTriVertex>(header.numVerts);
}
return GetSelf(target).UploadAliasModel(name, header, poseVertices,
triangles.ToStructArray<QTriangle>(header.numTriangles),
stVerts.ToStructArray<QSTVert>(header.numVerts));
}
}

3
Assets/Scripts/Modules/RenderModule.Interop.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 32320d2ca59f42cc8cc141d36574d8a7
timeCreated: 1618133895

60
Assets/Scripts/Modules/RenderModule.cs

@ -1,67 +1,13 @@
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using AOT;
using UnityEngine;
using UnityEngine;
public class RenderModule : CallbackHandler<RenderModule>
public partial class RenderModule
{ {
private const int MaxAliasFrames = 256; // Should match MAXALIASFRAMES
private readonly UniQuake uq; private readonly UniQuake uq;
public RenderModule(UniQuake uniQuake) public RenderModule(UniQuake uniQuake)
{ {
uq = uniQuake; uq = uniQuake;
var callbacks = new Callbacks
{
target = TargetPtr,
UploadAliasModel = CreateCallback<UploadAliasModelCallback>(Callback_UploadAliasModel),
};
RegisterCallbacks(callbacks);
}
/// <summary>
/// This matches unity_modcalls_t from mod_uniquake.c in native code.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class Callbacks
{
public IntPtr target;
public IntPtr UploadAliasModel;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private delegate int UploadAliasModelCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string name,
QAliasHeader header, IntPtr frames, [MarshalAs(UnmanagedType.LPArray, SizeConst = MaxAliasFrames)]
IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts);
[MonoPInvokeCallback(typeof(UploadAliasModelCallback))]
private static int Callback_UploadAliasModel(IntPtr target, string name, QAliasHeader header, IntPtr frames, IntPtr[] poseVerts, IntPtr triangles, IntPtr stVerts)
{
if (header == null)
{
Debug.LogWarning($"Uploading invalid alias model, name = {name}");
return 0;
}
if (frames != IntPtr.Zero)
header.frames = frames.ToStructArray<QAliasFrameDesc>(header.numFrames);
var poseVertices = new QTriVertex[header.numFrames][];
for (int i = 0; i < header.numFrames && i < MaxAliasFrames; ++i)
{
poseVertices[i] = poseVerts[i].ToStructArray<QTriVertex>(header.numVerts);
}
return GetSelf(target).UploadAliasModel(name, header, poseVertices,
triangles.ToStructArray<QTriangle>(header.numTriangles),
stVerts.ToStructArray<QSTVert>(header.numVerts));
BuildCallbacks();
} }
private int UploadAliasModel(string name, QAliasHeader header, QTriVertex[][] poseVertices, QTriangle[] triangles, QSTVert[] stVertices) private int UploadAliasModel(string name, QAliasHeader header, QTriVertex[][] poseVertices, QTriangle[] triangles, QSTVert[] stVertices)

161
Assets/Scripts/Modules/SystemModule.Interop.cs

@ -0,0 +1,161 @@
using System;
using System.Runtime.InteropServices;
using AOT;
public partial class SystemModule: CallbackHandler<SystemModule>
{
private void BuildCallbacks()
{
var callbacks = new Callbacks
{
target = TargetPtr,
SysPrint = CreateCallback<SysPrintCallback>(Callback_SysPrint),
SysError = CreateCallback<SysErrorCallback>(Callback_SysError),
SysQuit = CreateCallback<SysQuitCallback>(Callback_SysQuit),
SysDoubleTime = CreateCallback<SysDoubleTimeCallback>(Callback_SysDoubleTime),
SysFileOpenRead = CreateCallback<SysFileOpenReadCallback>(Callback_SysFileOpenRead),
SysFileOpenWrite = CreateCallback<SysFileOpenWriteCallback>(Callback_SysFileOpenWrite),
SysFileClose = CreateCallback<SysFileCloseCallback>(Callback_SysFileClose),
SysFileSeek = CreateCallback<SysFileSeekCallback>(Callback_SysFileSeek),
SysFileRead = CreateCallback<SysFileReadCallback>(Callback_SysFileRead),
SysFileWrite = CreateCallback<SysFileWriteCallback>(Callback_SysFileWrite),
SysFileTime = CreateCallback<SysFileTimeCallback>(Callback_SysFileTime),
SysMkDir = CreateCallback<SysMkDirCallback>(Callback_SysMkDir),
};
RegisterCallbacks(callbacks);
}
/// <summary>
/// This matches struct unity_syscalls_s from uniquake.h in native code.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class Callbacks
{
public IntPtr target;
public IntPtr SysPrint;
public IntPtr SysError;
public IntPtr SysQuit;
public IntPtr SysDoubleTime;
public IntPtr SysFileOpenRead;
public IntPtr SysFileOpenWrite;
public IntPtr SysFileClose;
public IntPtr SysFileSeek;
public IntPtr SysFileRead;
public IntPtr SysFileWrite;
public IntPtr SysFileTime;
public IntPtr SysMkDir;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysPrintCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string message);
[MonoPInvokeCallback(typeof(SysPrintCallback))]
private static void Callback_SysPrint(IntPtr target, string message)
{
GetSelf(target).Print(message);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysErrorCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string message);
[MonoPInvokeCallback(typeof(SysErrorCallback))]
private static void Callback_SysError(IntPtr target, string message)
{
GetSelf(target).Error(message);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysQuitCallback(IntPtr target);
[MonoPInvokeCallback(typeof(SysQuitCallback))]
private static void Callback_SysQuit(IntPtr target)
{
GetSelf(target).Quit();
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate double SysDoubleTimeCallback(IntPtr target);
[MonoPInvokeCallback(typeof(SysDoubleTimeCallback))]
private static double Callback_SysDoubleTime(IntPtr target)
{
return GetSelf(target).DoubleTime();
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileOpenReadCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string path, out int handle);
[MonoPInvokeCallback(typeof(SysFileOpenReadCallback))]
private static int Callback_SysFileOpenRead(IntPtr target, string path, out int handle)
{
return GetSelf(target).FileOpenRead(path, out handle);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileOpenWriteCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string path);
[MonoPInvokeCallback(typeof(SysFileOpenWriteCallback))]
private static int Callback_SysFileOpenWrite(IntPtr target, string path)
{
return GetSelf(target).FileOpenWrite(path);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysFileCloseCallback(IntPtr target, int handle);
[MonoPInvokeCallback(typeof(SysFileCloseCallback))]
private static void Callback_SysFileClose(IntPtr target, int handle)
{
GetSelf(target).FileClose(handle);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysFileSeekCallback(IntPtr target, int handle, int position);
[MonoPInvokeCallback(typeof(SysFileSeekCallback))]
private static void Callback_SysFileSeek(IntPtr target, int handle, int position)
{
GetSelf(target).FileSeek(handle, position);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileReadCallback(IntPtr target, int handle, IntPtr dest, int count);
[MonoPInvokeCallback(typeof(SysFileReadCallback))]
private static int Callback_SysFileRead(IntPtr target, int handle, IntPtr dest, int count)
{
return GetSelf(target).FileRead(handle, dest, count);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileWriteCallback(IntPtr target, int handle, IntPtr data, int count);
[MonoPInvokeCallback(typeof(SysFileWriteCallback))]
private static int Callback_SysFileWrite(IntPtr target, int handle, IntPtr data, int count)
{
return GetSelf(target).FileWrite(handle, data, count);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileTimeCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string path);
[MonoPInvokeCallback(typeof(SysFileTimeCallback))]
private static int Callback_SysFileTime(IntPtr target, string path)
{
return GetSelf(target).FileTime(path);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysMkDirCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string path);
[MonoPInvokeCallback(typeof(SysMkDirCallback))]
private static void Callback_SysMkDir(IntPtr target, string path)
{
GetSelf(target).MkDir(path);
}
}

3
Assets/Scripts/Modules/SystemModule.Interop.cs.meta

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0a237031e45b41deaed58a305beb273f
timeCreated: 1618133546

156
Assets/Scripts/Modules/SystemModule.cs

@ -1,10 +1,9 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using AOT;
using UnityEngine; using UnityEngine;
public class SystemModule: CallbackHandler<SystemModule>
public partial class SystemModule
{ {
private const int MaxFileHandles = 50; private const int MaxFileHandles = 50;
@ -15,27 +14,7 @@ public class SystemModule: CallbackHandler<SystemModule>
public SystemModule(UniQuake uniQuake) public SystemModule(UniQuake uniQuake)
{ {
uq = uniQuake; uq = uniQuake;
var callbacks = new Callbacks
{
target = TargetPtr,
SysPrint = CreateCallback<SysPrintCallback>(Callback_SysPrint),
SysError = CreateCallback<SysErrorCallback>(Callback_SysError),
SysQuit = CreateCallback<SysQuitCallback>(Callback_SysQuit),
SysDoubleTime = CreateCallback<SysDoubleTimeCallback>(Callback_SysDoubleTime),
SysFileOpenRead = CreateCallback<SysFileOpenReadCallback>(Callback_SysFileOpenRead),
SysFileOpenWrite = CreateCallback<SysFileOpenWriteCallback>(Callback_SysFileOpenWrite),
SysFileClose = CreateCallback<SysFileCloseCallback>(Callback_SysFileClose),
SysFileSeek = CreateCallback<SysFileSeekCallback>(Callback_SysFileSeek),
SysFileRead = CreateCallback<SysFileReadCallback>(Callback_SysFileRead),
SysFileWrite = CreateCallback<SysFileWriteCallback>(Callback_SysFileWrite),
SysFileTime = CreateCallback<SysFileTimeCallback>(Callback_SysFileTime),
SysMkDir = CreateCallback<SysMkDirCallback>(Callback_SysMkDir),
};
RegisterCallbacks(callbacks);
BuildCallbacks();
} }
public override void Destroy() public override void Destroy()
@ -49,96 +28,28 @@ public class SystemModule: CallbackHandler<SystemModule>
base.Destroy(); base.Destroy();
} }
/// <summary>
/// This matches struct unity_syscalls_s from uniquake.h in native code.
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class Callbacks
{
public IntPtr target;
public IntPtr SysPrint;
public IntPtr SysError;
public IntPtr SysQuit;
public IntPtr SysDoubleTime;
public IntPtr SysFileOpenRead;
public IntPtr SysFileOpenWrite;
public IntPtr SysFileClose;
public IntPtr SysFileSeek;
public IntPtr SysFileRead;
public IntPtr SysFileWrite;
public IntPtr SysFileTime;
public IntPtr SysMkDir;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysPrintCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string message);
[MonoPInvokeCallback(typeof(SysPrintCallback))]
private static void Callback_SysPrint(IntPtr target, string message)
{
GetSelf(target).Print(message);
}
private void Print(string message) private void Print(string message)
{ {
// Debug.Log(message); // TODO: collect logs per frame and print after each Update loop // Debug.Log(message); // TODO: collect logs per frame and print after each Update loop
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysErrorCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string message);
[MonoPInvokeCallback(typeof(SysErrorCallback))]
private static void Callback_SysError(IntPtr target, string message)
{
GetSelf(target).Error(message);
}
private void Error(string message) private void Error(string message)
{ {
// Use an exception to emulate Quake's behavior of immediately terminating the game's code execution on error // Use an exception to emulate Quake's behavior of immediately terminating the game's code execution on error
throw new QuakeException(message, 1); throw new QuakeException(message, 1);
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysQuitCallback(IntPtr target);
[MonoPInvokeCallback(typeof(SysQuitCallback))]
private static void Callback_SysQuit(IntPtr target)
{
GetSelf(target).Quit();
}
private void Quit() private void Quit()
{ {
// This exception will be caught by the UniQuake update loop where the game will be shut down // This exception will be caught by the UniQuake update loop where the game will be shut down
throw new QuakeException("Quitting application normally"); throw new QuakeException("Quitting application normally");
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate double SysDoubleTimeCallback(IntPtr target);
[MonoPInvokeCallback(typeof(SysDoubleTimeCallback))]
private static double Callback_SysDoubleTime(IntPtr target)
{
return GetSelf(target).DoubleTime();
}
private double DoubleTime() private double DoubleTime()
{ {
return uq.CurrentTime; return uq.CurrentTime;
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileOpenReadCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string path, out int handle);
[MonoPInvokeCallback(typeof(SysFileOpenReadCallback))]
private static int Callback_SysFileOpenRead(IntPtr target, string path, out int handle)
{
return GetSelf(target).FileOpenRead(path, out handle);
}
private int FileOpenRead(string path, out int handle) private int FileOpenRead(string path, out int handle)
{ {
int i = FindFileHandle(); int i = FindFileHandle();
@ -157,15 +68,6 @@ public class SystemModule: CallbackHandler<SystemModule>
} }
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileOpenWriteCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string path);
[MonoPInvokeCallback(typeof(SysFileOpenWriteCallback))]
private static int Callback_SysFileOpenWrite(IntPtr target, string path)
{
return GetSelf(target).FileOpenWrite(path);
}
private int FileOpenWrite(string path) private int FileOpenWrite(string path)
{ {
int i = FindFileHandle(); int i = FindFileHandle();
@ -195,15 +97,6 @@ public class SystemModule: CallbackHandler<SystemModule>
return -1; return -1;
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysFileCloseCallback(IntPtr target, int handle);
[MonoPInvokeCallback(typeof(SysFileCloseCallback))]
private static void Callback_SysFileClose(IntPtr target, int handle)
{
GetSelf(target).FileClose(handle);
}
private void FileClose(int handle) private void FileClose(int handle)
{ {
if (handle < 0 || handle >= MaxFileHandles) if (handle < 0 || handle >= MaxFileHandles)
@ -216,15 +109,6 @@ public class SystemModule: CallbackHandler<SystemModule>
fileHandles[handle] = null; fileHandles[handle] = null;
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysFileSeekCallback(IntPtr target, int handle, int position);
[MonoPInvokeCallback(typeof(SysFileSeekCallback))]
private static void Callback_SysFileSeek(IntPtr target, int handle, int position)
{
GetSelf(target).FileSeek(handle, position);
}
private void FileSeek(int handle, int position) private void FileSeek(int handle, int position)
{ {
if (handle < 0 || handle >= MaxFileHandles) if (handle < 0 || handle >= MaxFileHandles)
@ -236,15 +120,6 @@ public class SystemModule: CallbackHandler<SystemModule>
fileHandles[handle].Seek(position, SeekOrigin.Begin); fileHandles[handle].Seek(position, SeekOrigin.Begin);
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileReadCallback(IntPtr target, int handle, IntPtr dest, int count);
[MonoPInvokeCallback(typeof(SysFileReadCallback))]
private static int Callback_SysFileRead(IntPtr target, int handle, IntPtr dest, int count)
{
return GetSelf(target).FileRead(handle, dest, count);
}
private int FileRead(int handle, IntPtr dest, int count) private int FileRead(int handle, IntPtr dest, int count)
{ {
if (handle < 0 || handle >= MaxFileHandles) if (handle < 0 || handle >= MaxFileHandles)
@ -259,15 +134,6 @@ public class SystemModule: CallbackHandler<SystemModule>
return numRead; return numRead;
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileWriteCallback(IntPtr target, int handle, IntPtr data, int count);
[MonoPInvokeCallback(typeof(SysFileWriteCallback))]
private static int Callback_SysFileWrite(IntPtr target, int handle, IntPtr data, int count)
{
return GetSelf(target).FileWrite(handle, data, count);
}
private int FileWrite(int handle, IntPtr data, int count) private int FileWrite(int handle, IntPtr data, int count)
{ {
if (handle < 0 || handle >= MaxFileHandles) if (handle < 0 || handle >= MaxFileHandles)
@ -282,15 +148,6 @@ public class SystemModule: CallbackHandler<SystemModule>
return count; return count;
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int SysFileTimeCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string path);
[MonoPInvokeCallback(typeof(SysFileTimeCallback))]
private static int Callback_SysFileTime(IntPtr target, string path)
{
return GetSelf(target).FileTime(path);
}
private int FileTime(string path) private int FileTime(string path)
{ {
// It would logically make more sense to return an actual file write time here, // It would logically make more sense to return an actual file write time here,
@ -298,15 +155,6 @@ public class SystemModule: CallbackHandler<SystemModule>
return File.Exists(path) ? 1 : -1; return File.Exists(path) ? 1 : -1;
} }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SysMkDirCallback(IntPtr target, [MarshalAs(UnmanagedType.LPStr)] string path);
[MonoPInvokeCallback(typeof(SysMkDirCallback))]
private static void Callback_SysMkDir(IntPtr target, string path)
{
GetSelf(target).MkDir(path);
}
private void MkDir(string path) private void MkDir(string path)
{ {
try try

Loading…
Cancel
Save