PorygonSharp/PorygonSharp/EvalValues/EvalValueCreator.cs

83 lines
4.0 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using PorygonSharp.UserData;
namespace PorygonSharp.EvalValues
{
public static class EvalValueCreator
{
public static EvalValue CreateValue(object o)
{
var type = o.GetType();
if (type.IsEnum)
{
var typeHash = UserDataHandler.GetTypeId(type);
var handle = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle)));
}
var typeCode = Type.GetTypeCode(type);
switch (typeCode)
{
case TypeCode.Boolean:
return new EvalValue(CreateBoolEvalValue((bool)o));
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return new EvalValue(CreateIntegerEvalValue(Convert.ToInt64(o)));
case TypeCode.Char:
case TypeCode.String:
return new EvalValue(CreateStringEvalValue(o.ToString()));
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return new EvalValue(CreateFloatEvalValue(Convert.ToDouble(o)));
case TypeCode.Object:
if (typeof(IList).IsAssignableFrom(type))
return CreateListEvalValue((IList)o, type);
var typeHash = UserDataHandler.GetTypeId(type);
var handle = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle)));
default:
throw new Exception($"Type {type} is not currently available as EvalValue");
}
}
public static EvalValue FunctionEvalValue(IntPtr func, IntPtr parent)
{
return new EvalValue(CreateFunctionEvalValue(func, parent));
}
private static EvalValue CreateListEvalValue(IList collection, Type type)
{
var helper = new ListEvalValue(collection, type);
var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollection, helper.Getter, helper.Setter,
helper.GetIterator);
return new EvalValue(ptr);
}
[DllImport("libPorygonLang", EntryPoint = "CreateIntegerEvalValue",CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr CreateIntegerEvalValue(long l);
[DllImport("libPorygonLang", EntryPoint = "CreateFloatEvalValue",CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateFloatEvalValue(double d);
[DllImport("libPorygonLang", EntryPoint = "CreateBoolEvalValue",CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateBoolEvalValue(bool b);
[DllImport("libPorygonLang", EntryPoint = "CreateStringEvalValue",CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateStringEvalValue(string s);
[DllImport("libPorygonLang", EntryPoint = "CreateUserDataEvalValue",CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateUserDataEvalValue(uint typeHash, IntPtr obj);
[DllImport("libPorygonLang", EntryPoint = "CreateFunctionEvalValue",CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent);
[DllImport("libPorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateCollectionValue(IntPtr type, IntPtr parent, IntPtr getter, IntPtr setter,
IntPtr iterator);
}
}