PorygonSharp/PorygonSharp/ScriptOptions.cs

67 lines
2.7 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
// ReSharper disable PrivateFieldCanBeConvertedToLocalVariable
namespace PorygonSharp
{
public abstract class ScriptOptions
{
private readonly IntPtr _ptr;
private delegate void PrintDelegate(string s);
private delegate bool ModuleExistsDelegate(IntPtr namePtr, int size);
private delegate IntPtr ResolveModuleDelegate(IntPtr namePtr, int size);
private readonly PrintDelegate _print;
private readonly ModuleExistsDelegate _moduleExists;
private readonly ResolveModuleDelegate _resolveModule;
protected ScriptOptions()
{
_ptr = Create();
_print = Print;
SetOptionPrintFunc(_ptr, Marshal.GetFunctionPointerForDelegate(_print));
_moduleExists = (namePtr, size) =>
{
var nameArr = new byte[size];
for (var i = 0; i < size; i++)
nameArr[i] = Marshal.ReadByte(namePtr, i);
var name = Encoding.UTF8.GetString(nameArr);
return ModuleExists(name);
};
SetOptionModuleExistsFunc(_ptr, Marshal.GetFunctionPointerForDelegate(_moduleExists));
_resolveModule = (namePtr, size) =>
{
var nameArr = new byte[size];
for (var i = 0; i < size; i++)
nameArr[i] = Marshal.ReadByte(namePtr, i);
var name = Encoding.UTF8.GetString(nameArr);
return ResolveModule(name).GetRawPointer();
};
SetOptionResolveModuleFunc(_ptr, Marshal.GetFunctionPointerForDelegate(_resolveModule));
}
protected abstract void Print(string s);
protected abstract bool ModuleExists(string s);
protected abstract Script ResolveModule(string s);
internal IntPtr GetRawPointer()
{
return _ptr;
}
[DllImport("PorygonLang", EntryPoint = "CreateOptions", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr Create();
[DllImport("PorygonLang", EntryPoint = "SetOptionPrintFunc", CallingConvention = CallingConvention.Cdecl)]
private static extern void SetOptionPrintFunc(IntPtr opt, IntPtr func);
[DllImport("PorygonLang", EntryPoint = "SetOptionModuleExistsFunc", CallingConvention = CallingConvention.Cdecl)]
private static extern void SetOptionModuleExistsFunc(IntPtr opt, IntPtr func);
[DllImport("PorygonLang", EntryPoint = "SetOptionResolveModuleFunc", CallingConvention = CallingConvention.Cdecl)]
private static extern void SetOptionResolveModuleFunc(IntPtr opt, IntPtr func);
}
}