PorygonSharp/PorygonSharp/UserData/UserDataField.cs

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);
}
}
}