79 lines
2.6 KiB
C#
79 lines
2.6 KiB
C#
using System;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using PorygonSharp.EvalValues;
|
|
using PorygonSharp.Utilities;
|
|
|
|
namespace PorygonSharp.UserData
|
|
{
|
|
internal class UserDataField
|
|
{
|
|
internal delegate IntPtr GetterDelegate(IntPtr ptr);
|
|
internal delegate void SetterDelegate(IntPtr ptr, IntPtr val);
|
|
protected delegate IntPtr CallerDelegate(IntPtr parent, IntPtr scriptOption,
|
|
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int size);
|
|
|
|
protected GetterDelegate _getter;
|
|
protected readonly SetterDelegate _setter;
|
|
|
|
public UserDataField(FieldInfo field)
|
|
{
|
|
_getter = ptr =>
|
|
{
|
|
var obj = GCHandle.FromIntPtr(ptr).Target;
|
|
var value = field.GetValue(obj);
|
|
return EvalValueCreator.CreateValue(value).GetPointer();
|
|
};
|
|
|
|
if (!field.IsInitOnly)
|
|
{
|
|
_setter = (ptr, val) =>
|
|
{
|
|
var obj = GCHandle.FromIntPtr(ptr).Target;
|
|
var evalValue = Caster.Cast(new EvalValue(val), field.FieldType);
|
|
field.SetValue(obj, evalValue);
|
|
};
|
|
}
|
|
}
|
|
|
|
public UserDataField(PropertyInfo property)
|
|
{
|
|
if (property.GetGetMethod(false) != null)
|
|
{
|
|
_getter = ptr =>
|
|
{
|
|
var obj = GCHandle.FromIntPtr(ptr).Target;
|
|
var value = property.GetValue(obj);
|
|
return EvalValueCreator.CreateValue(value).GetPointer();
|
|
};
|
|
}
|
|
if (property.GetSetMethod(false) != null)
|
|
{
|
|
_setter = (ptr, val) =>
|
|
{
|
|
var obj = GCHandle.FromIntPtr(ptr).Target;
|
|
var evalValue = Caster.Cast(new EvalValue(val), property.PropertyType);
|
|
property.SetValue(obj, evalValue);
|
|
};
|
|
}
|
|
}
|
|
|
|
protected UserDataField(){}
|
|
|
|
public UserDataField(GetterDelegate getter, SetterDelegate setter)
|
|
{
|
|
_getter = getter;
|
|
_setter = setter;
|
|
}
|
|
|
|
internal IntPtr GetGetterPointer()
|
|
{
|
|
return _getter == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(_getter);
|
|
}
|
|
|
|
internal IntPtr GetSetterPointer()
|
|
{
|
|
return _setter == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(_setter);
|
|
}
|
|
}
|
|
} |