51 lines
2.0 KiB
C#
51 lines
2.0 KiB
C#
using System;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using PorygonSharp.EvalValues;
|
|
using PorygonSharp.Utilities;
|
|
|
|
namespace PorygonSharp.UserData
|
|
{
|
|
public class UserDataBinaryOperation
|
|
{
|
|
private delegate IntPtr BinaryFunctionDelegate(IntPtr objectPtr, IntPtr variable);
|
|
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
|
private readonly BinaryFunctionDelegate _func;
|
|
private readonly MethodInfo _info;
|
|
private readonly Type _parameterType;
|
|
internal IntPtr Handle { get; private set; }
|
|
private UserDataBinaryOperation(MethodInfo info)
|
|
{
|
|
_info = info;
|
|
_func = Invoke;
|
|
_parameterType = info.GetParameters()[1].ParameterType;
|
|
}
|
|
|
|
public static UserDataBinaryOperation Create(MethodInfo info)
|
|
{
|
|
var op = new UserDataBinaryOperation(info);
|
|
var funcPtr = Marshal.GetFunctionPointerForDelegate(op._func);
|
|
var secParType = ScriptType.ScriptTypeHandler.GetScriptType(op._parameterType);
|
|
var returnType = ScriptType.ScriptTypeHandler.GetScriptType(op._info.ReturnType);
|
|
if (!secParType.HasValue || !returnType.HasValue)
|
|
{
|
|
return null;
|
|
}
|
|
op.Handle = CreateUserdataBinaryOperation(funcPtr, secParType.Value, returnType.Value);
|
|
return op;
|
|
}
|
|
|
|
private IntPtr Invoke(IntPtr objectPtr, IntPtr variable)
|
|
{
|
|
var a = GCHandle.FromIntPtr(objectPtr).Target;
|
|
var b = new EvalValue(variable);
|
|
var bVal = Caster.Cast(b, _parameterType);
|
|
var o = _info.Invoke(null, new[] {a, bVal});
|
|
return EvalValueCreator.CreateValue(o).GetPointer();
|
|
}
|
|
|
|
|
|
[DllImport("PorygonLang", EntryPoint = "CreateUserdataBinaryOperation", CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern IntPtr CreateUserdataBinaryOperation(IntPtr func, IntPtr secondParameterType, IntPtr returnType);
|
|
}
|
|
} |