From e5a2c6db67ad68a616f5114cc417848f9c80d290 Mon Sep 17 00:00:00 2001 From: Qrakhen Date: Thu, 4 Dec 2025 00:33:20 +0100 Subject: [PATCH] add some of that native stuff --- .../Values/Native/NativeMember.cs | 76 +++++++++++++++++++ Qrakhen.Qamp.Core/Values/Objects/Obj.cs | 2 +- Qrakhen.Qamp.Core/Values/TypeInfo.cs | 9 ++- Qrakhen.Qamp.Core/Values/Value.cs | 2 + 4 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 Qrakhen.Qamp.Core/Values/Native/NativeMember.cs diff --git a/Qrakhen.Qamp.Core/Values/Native/NativeMember.cs b/Qrakhen.Qamp.Core/Values/Native/NativeMember.cs new file mode 100644 index 0000000..27762e9 --- /dev/null +++ b/Qrakhen.Qamp.Core/Values/Native/NativeMember.cs @@ -0,0 +1,76 @@ +using Qrakhen.Qamp.Core.Values.Objects; +using System.Reflection; + +namespace Qrakhen.Qamp.Core.Values.Native; + +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> _members = []; + private static readonly Dictionary> _membersStatic = []; + + private static Dictionary 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)); + } +} \ No newline at end of file diff --git a/Qrakhen.Qamp.Core/Values/Objects/Obj.cs b/Qrakhen.Qamp.Core/Values/Objects/Obj.cs index 7a3265a..8a7fb46 100644 --- a/Qrakhen.Qamp.Core/Values/Objects/Obj.cs +++ b/Qrakhen.Qamp.Core/Values/Objects/Obj.cs @@ -15,4 +15,4 @@ public class Obj(ValueType type) : IValue } public override string ToString() => "Obj"; -} \ No newline at end of file +} diff --git a/Qrakhen.Qamp.Core/Values/TypeInfo.cs b/Qrakhen.Qamp.Core/Values/TypeInfo.cs index ff5c43f..a560145 100644 --- a/Qrakhen.Qamp.Core/Values/TypeInfo.cs +++ b/Qrakhen.Qamp.Core/Values/TypeInfo.cs @@ -1,4 +1,6 @@ -namespace Qrakhen.Qamp.Core.Values; +using Qrakhen.Qamp.Core.Values.Objects; + +namespace Qrakhen.Qamp.Core.Values; public readonly record struct TypeInfo(ValueType Type, Type? ObjectType = null, string? TypeName = null, bool Nullable = false) { @@ -21,6 +23,9 @@ public readonly record struct TypeInfo(ValueType Type, Type? ObjectType = null, public static TypeInfo FromValue(Value value) { - return new TypeInfo(value.Type, value.IsObj ? value.Ptr.Value?.GetType() : null, null); + return new TypeInfo( + value.Type, + value.IsExt ? value.Ptr.Value?.GetType() : null, + value.IsInstance ? value.Ptr.As()?.Class.Name : null); } } \ No newline at end of file diff --git a/Qrakhen.Qamp.Core/Values/Value.cs b/Qrakhen.Qamp.Core/Values/Value.cs index 1838846..ab05c32 100644 --- a/Qrakhen.Qamp.Core/Values/Value.cs +++ b/Qrakhen.Qamp.Core/Values/Value.cs @@ -58,6 +58,8 @@ public readonly struct Value : IValue, ISerialize, IDebug public bool IsString => Is(T.String); public bool IsRef => Is(T.Reference, false); public bool IsObj => Is(T.Object, false); + public bool IsExt => Is(T.Class) || Is(T.Instance); + public bool IsInstance => Is(T.Instance); public bool IsFalsy => IsBool ? Bool == false : Unsigned == 0;