Files
PorygonSharp/PorygonSharp/EvalValue.cs

156 lines
6.2 KiB
C#

using System;
using System.Runtime.InteropServices;
using PorygonSharp.UserData;
namespace PorygonSharp
{
public class EvalValue : IDisposable
{
private IntPtr _handle;
public EvalValue(IntPtr handle)
{
_handle = handle;
}
public static EvalValue CreateValue(object o)
{
var type = o.GetType();
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:
var typeHash = UserDataHandler.GetTypeId(type);
var handle = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
return new EvalValue(CreateUserDataEvalValue(typeHash, GCHandle.ToIntPtr(handle)));
case TypeCode.DateTime:
case TypeCode.DBNull:
case TypeCode.Empty:
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));
}
public void Dispose()
{
if (_handle != IntPtr.Zero)
{
Marshal.FreeHGlobal(_handle);
_handle = IntPtr.Zero;
}
}
public TypeClass GetTypeClass()
{
return (TypeClass)GetTypeClass(_handle);
}
public long EvaluateInteger()
{
return EvaluateInteger(_handle);
}
public double EvaluateFloat()
{
return EvaluateFloat(_handle);
}
public bool EvaluateBool()
{
return EvaluateBool(_handle);
}
public string EvaluateString()
{
var ptr = EvaluateString(_handle);
return Marshal.PtrToStringUni(ptr);
}
public object EvaluateGenericObject()
{
var ptr = EvaluateUserDataObj(_handle);
return GCHandle.FromIntPtr(ptr).Target;
}
public object GetObjectValue()
{
switch (GetTypeClass())
{
case TypeClass.Nil:
return null;
case TypeClass.Number:
return EvaluateInteger();
case TypeClass.Bool:
return EvaluateBool();
case TypeClass.String:
return EvaluateString();
case TypeClass.UserData:
return EvaluateGenericObject();
case TypeClass.Function:
case TypeClass.Table:
case TypeClass.Error:
default:
throw new ArgumentOutOfRangeException();
}
}
internal IntPtr GetPointer()
{
return _handle;
}
[DllImport("libPorygonLang", EntryPoint = "GetEvalValueTypeClass", CallingConvention = CallingConvention.Cdecl)]
private static extern int GetTypeClass(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "GetEvalValueType", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetScriptType(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "EvaluateEvalValueInteger", CallingConvention = CallingConvention.Cdecl)]
private static extern long EvaluateInteger(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "EvaluateEvalValueFloat", CallingConvention = CallingConvention.Cdecl)]
private static extern double EvaluateFloat(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "EvaluateEvalValueBool", CallingConvention = CallingConvention.Cdecl)]
private static extern bool EvaluateBool(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "EvaluateEvalValueString",CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr EvaluateString(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "EvaluateUserDataObj",CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr EvaluateUserDataObj(IntPtr ptr);
[DllImport("libPorygonLang", EntryPoint = "CreateIntegerEvalValue",CallingConvention = CallingConvention.Cdecl)]
private 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);
}
}