Browse Source

Callback target pointer is now contained within the struct passed to native. Organized yet more code to move generic GCHandle stuff into the base class.

console
Nico de Poel 5 years ago
parent
commit
0fafaf32ad
  1. 15
      Assets/Scripts/CallbackHandler.cs
  2. 20
      Assets/Scripts/SysCalls.cs
  3. 4
      Assets/Scripts/UniQuake.cs
  4. 16
      engine/projects/uniquake/uniquake.c
  5. 8
      engine/projects/uniquake/uniquake.h

15
Assets/Scripts/CallbackHandler.cs

@ -6,17 +6,23 @@ public abstract class CallbackHandler<THandler>
where THandler: CallbackHandler<THandler> where THandler: CallbackHandler<THandler>
{ {
private GCHandle selfHandle; private GCHandle selfHandle;
private GCHandle callbacksHandle;
private List<GCHandle> delegateHandles = new List<GCHandle>(); private List<GCHandle> delegateHandles = new List<GCHandle>();
public IntPtr SelfPtr => GCHandle.ToIntPtr(selfHandle);
public IntPtr ToIntPtr => callbacksHandle.AddrOfPinnedObject();
protected IntPtr SelfPtr => GCHandle.ToIntPtr(selfHandle);
protected CallbackHandler() protected CallbackHandler()
{ {
selfHandle = GCHandle.Alloc(this); selfHandle = GCHandle.Alloc(this);
} }
public virtual void Destroy()
public void Destroy()
{ {
if (callbacksHandle.IsAllocated)
callbacksHandle.Free();
foreach (var handle in delegateHandles) foreach (var handle in delegateHandles)
{ {
if (handle.IsAllocated) if (handle.IsAllocated)
@ -32,6 +38,11 @@ public abstract class CallbackHandler<THandler>
return Marshal.GetFunctionPointerForDelegate(callback); return Marshal.GetFunctionPointerForDelegate(callback);
} }
protected void RegisterCallbacks<TCallbacks>(TCallbacks callbacks)
{
callbacksHandle = GCHandle.Alloc(callbacks, GCHandleType.Pinned);
}
protected static THandler GetSelf(IntPtr target) protected static THandler GetSelf(IntPtr target)
{ {
return (THandler)GCHandle.FromIntPtr(target).Target; return (THandler)GCHandle.FromIntPtr(target).Target;

20
Assets/Scripts/SysCalls.cs

@ -7,38 +7,28 @@ public class SysCalls: CallbackHandler<SysCalls>
private readonly UniQuake uq; private readonly UniQuake uq;
private readonly double startTime; private readonly double startTime;
private Callbacks callbacks;
private GCHandle callbacksHandle;
public IntPtr CallbacksPtr => callbacksHandle.AddrOfPinnedObject();
public SysCalls(UniQuake uniQuake) public SysCalls(UniQuake uniQuake)
{ {
uq = uniQuake; uq = uniQuake;
startTime = Time.timeAsDouble; startTime = Time.timeAsDouble;
callbacks = new Callbacks
var callbacks = new Callbacks
{ {
target = SelfPtr,
SysPrint = CreateCallback<SysPrintCallback>(Callback_SysPrint), SysPrint = CreateCallback<SysPrintCallback>(Callback_SysPrint),
SysError = CreateCallback<SysErrorCallback>(Callback_SysError), SysError = CreateCallback<SysErrorCallback>(Callback_SysError),
SysQuit = CreateCallback<SysQuitCallback>(Callback_SysQuit), SysQuit = CreateCallback<SysQuitCallback>(Callback_SysQuit),
SysFloatTime = CreateCallback<SysFloatTimeCallback>(Callback_SysFloatTime), SysFloatTime = CreateCallback<SysFloatTimeCallback>(Callback_SysFloatTime),
}; };
callbacksHandle = GCHandle.Alloc(callbacks, GCHandleType.Pinned);
}
public override void Destroy()
{
if (callbacksHandle.IsAllocated)
callbacksHandle.Free();
base.Destroy();
RegisterCallbacks(callbacks);
} }
[StructLayout(LayoutKind.Sequential, Pack = 0)] [StructLayout(LayoutKind.Sequential, Pack = 0)]
private class Callbacks private class Callbacks
{ {
public IntPtr target;
public IntPtr SysPrint; public IntPtr SysPrint;
public IntPtr SysError; public IntPtr SysError;
public IntPtr SysQuit; public IntPtr SysQuit;

4
Assets/Scripts/UniQuake.cs

@ -30,7 +30,7 @@ public class UniQuake: MonoBehaviour
sysCalls = new SysCalls(this); sysCalls = new SysCalls(this);
UniQuake_Init(sysCalls.CallbacksPtr, sysCalls.SelfPtr, quakeParms);
UniQuake_Init(quakeParms, sysCalls.ToIntPtr);
} }
void Update() void Update()
@ -50,7 +50,7 @@ public class UniQuake: MonoBehaviour
} }
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void UniQuake_Init(IntPtr callbacks, IntPtr callbackTarget, QuakeParms parms);
private static extern void UniQuake_Init(QuakeParms parms, IntPtr syscalls);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void UniQuake_Update(float deltaTime); private static extern void UniQuake_Update(float deltaTime);

16
engine/projects/uniquake/uniquake.c

@ -7,8 +7,7 @@
#include "../../code/quakedef.h" #include "../../code/quakedef.h"
const unity_callbacks_t *unity_callbacks;
void *unity_callbackTarget;
const unity_syscalls_t *unity_syscalls;
void Sys_Error(char *error, ...) void Sys_Error(char *error, ...)
{ {
@ -19,7 +18,7 @@ void Sys_Error(char *error, ...)
vsprintf(text, error, argptr); vsprintf(text, error, argptr);
va_end(argptr); va_end(argptr);
unity_callbacks->SysError(unity_callbackTarget, text);
unity_syscalls->SysError(unity_syscalls->target, text);
} }
void Sys_Printf(char *fmt, ...) void Sys_Printf(char *fmt, ...)
@ -31,24 +30,23 @@ void Sys_Printf(char *fmt, ...)
vsprintf(text, fmt, argptr); vsprintf(text, fmt, argptr);
va_end(argptr); va_end(argptr);
unity_callbacks->SysPrint(unity_callbackTarget, text);
unity_syscalls->SysPrint(unity_syscalls->target, text);
} }
void Sys_Quit(void) void Sys_Quit(void)
{ {
Host_Shutdown(); Host_Shutdown();
unity_callbacks->SysQuit(unity_callbackTarget);
unity_syscalls->SysQuit(unity_syscalls->target);
} }
double Sys_FloatTime(void) double Sys_FloatTime(void)
{ {
return unity_callbacks->SysFloatTime(unity_callbackTarget);
return unity_syscalls->SysFloatTime(unity_syscalls->target);
} }
UNIQUAKE_API void UniQuake_Init(const unity_callbacks_t *callbacks, void *callbackTarget, quakeparms_t *parms)
UNIQUAKE_API void UniQuake_Init(quakeparms_t *parms, const unity_syscalls_t *syscalls)
{ {
unity_callbacks = callbacks;
unity_callbackTarget = callbackTarget;
unity_syscalls = syscalls;
COM_InitArgv(parms->argc, parms->argv); COM_InitArgv(parms->argc, parms->argv);
parms->argc = com_argc; parms->argc = com_argc;

8
engine/projects/uniquake/uniquake.h

@ -4,12 +4,14 @@
#define UNIQUAKE_API __declspec(dllimport) #define UNIQUAKE_API __declspec(dllimport)
#endif #endif
typedef struct unity_callbacks_s
typedef struct unity_syscalls_s
{ {
void *target;
void(__stdcall *SysPrint)(void *target, const char *msg); void(__stdcall *SysPrint)(void *target, const char *msg);
void(__stdcall *SysError)(void *target, const char *msg); void(__stdcall *SysError)(void *target, const char *msg);
void(__stdcall *SysQuit)(void *target); void(__stdcall *SysQuit)(void *target);
double(__stdcall *SysFloatTime)(void *target); double(__stdcall *SysFloatTime)(void *target);
} unity_callbacks_t;
} unity_syscalls_t;
extern const unity_callbacks_t *unity_callbacks;
extern const unity_syscalls_t *unity_syscalls;
Loading…
Cancel
Save