qamp/Qrakhen.Qamp.Core/Values/Native/NativeMember.cs

156 lines
4.4 KiB
C#

using Qrakhen.Qamp.Core.Values.Objects;
using System.Reflection;
namespace Qrakhen.Qamp.Core.Values.Native;
public class NativeMemberAttribute(string? name = null) : Attribute
{
public string? Name { get; } = name;
}
public class NativeMember(string name, MemberInfo info)
{
public string Name { get; } = name;
public MemberInfo MemberInfo { get; } = info;
}
public class NativeProperty(string name,
PropertyInfo info,
bool readOnly) : NativeMember(name, info)
{
public bool ReadOnly { get; } = readOnly;
public PropertyInfo PropertyInfo => (MemberInfo as PropertyInfo)!;
}
public class NativeMethod(string name,
MethodInfo info) : NativeMember(name, info)
{
public MethodInfo MethodInfo => (MemberInfo as MethodInfo)!;
}
public static class NativeLinker
{
private static readonly Dictionary<Type, Dictionary<string, NativeMember>> _linked = [];
public static Value GetMember<TObj>(TObj obj, string name)
{
return Value.Void;
}
public static void SetMember<TObj>(TObj obj, string name, Value value)
{
}
public static Value CallMember<TObj>(TObj obj, string name, Value[] args)
{
return Value.Void;
}
private static void Compile(Type type)
{
var members = type.GetMembers();
var table = new Dictionary<string, NativeMember>();
foreach (var member in members)
{
var attr = member.GetCustomAttribute<NativeMemberAttribute>();
if (attr == null)
continue;
NativeMember? native = null;
if (member is PropertyInfo propertyInfo)
{
native = new NativeProperty(attr.Name ?? member.Name,
propertyInfo,
propertyInfo.CanWrite);
}
if (member is MethodInfo methodInfo)
{
native = new NativeMethod(attr.Name ?? methodInfo.Name,
methodInfo);
}
if (native == null)
throw new Exception("meh.");
table[native.Name] = native;
}
_linked[type] = table;
}
}
/*
public delegate Value Getter(Obj? self);
public delegate void Setter(Obj? self, Value value);
public delegate Value Method(Obj? self, Value[] args);
public class NativeMember(string name, bool isStatic)
{
public readonly string Name = name;
public readonly bool IsStatic = isStatic;
}
public class NativeConst(string name, Value value)
: NativeMember(name, true)
{
public readonly Value Value = value;
}
public class NativeGetter(string name, bool isStatic, Getter getter)
: NativeMember(name, isStatic)
{
public readonly Getter Getter = getter;
}
public class NativeSetter(string name, bool isStatic, Getter getter, Setter setter)
: NativeGetter(name, isStatic, getter)
{
public readonly Setter Setter = setter;
}
public class NativeMethod(string name, bool isStatic, Method method)
: NativeMember(name, isStatic)
{
public readonly Method Method = method;
}
public static class Natives
{
private static readonly Dictionary<Type, Dictionary<string, NativeMember>> _members = [];
private static readonly Dictionary<Type, Dictionary<string, NativeMember>> _membersStatic = [];
private static Dictionary<string, NativeMember> Prepare(Type type, string name, bool isStatic)
{
if (!type.IsAssignableTo(typeof(Obj)))
throw new QampException($"Only object types may have native members assigned. The provided type {type} can not have any attached properties or members. Use extensions to handle that type.");
var target = isStatic ? _membersStatic : _members;
if (!target.ContainsKey(type))
target.Add(type, []);
if (target[type].ContainsKey(name))
throw new QampException($"Can not register native {(isStatic ? "static" : "")} member {name} for {type}, that member was already defined.");
return target[type];
}
public static void Register(Type type, NativeMember member)
{
var target = Prepare(type, member.Name, member.IsStatic);
target[member.Name] = member;
}
public static void Register(Type type, string name, Value constant)
{
Register(type, new NativeConst(name, constant));
}
public static void Register(Type type, MethodInfo info, Method method)
{
Register(type, new NativeMethod(info.Name, info.IsStatic, method));
}
}*/