diff --git a/Qrakhen.Qamp.Core/Values/Native/NativeMember.cs b/Qrakhen.Qamp.Core/Values/Native/NativeMember.cs index e26ff88..3a49c64 100644 --- a/Qrakhen.Qamp.Core/Values/Native/NativeMember.cs +++ b/Qrakhen.Qamp.Core/Values/Native/NativeMember.cs @@ -32,23 +32,66 @@ public static class NativeLinker { private static readonly Dictionary> _linked = []; - public static Value GetMember(TObj obj, string name) + private static Dictionary GetLinkTable() => GetLinkTable(typeof(T)); + + private static Dictionary GetLinkTable(Type type) { - return Value.Void; + if (!_linked.TryGetValue(type, out Dictionary? table)) + { + table = Compile(type); + } + + if (table == null) + { + throw new QampException($"{type.Name} has no native members that could be accessed."); + } + + return table; } - public static void SetMember(TObj obj, string name, Value value) - { + private static M GetNativeMember(string name) where M : NativeMember + => GetNativeMember(typeof(T), name); + private static T GetNativeMember(Type type, string name) + { + if (GetLinkTable(type).TryGetValue(name, out NativeMember? member)) { + if (member is T typedMember) { + return typedMember; + } + } + + throw new QampException($"{type.Name} has no member {name} that could be accessed."); + } + + public static Value GetProperty(TObj obj, string name) + { + var property = GetNativeMember(name); + return Value.Void; //new Value(property.PropertyInfo.GetValue(obj)); + } + + public static void SetProperty(TObj obj, string name, Value value) + { + } public static Value CallMember(TObj obj, string name, Value[] args) { + var method = GetNativeMember(name); return Value.Void; } - private static void Compile(Type type) + private static void Compile(Type type, string method, int argCount) + { + + } + + private static void Compile(Type type, string member) + { + + } + + private static Dictionary Compile(Type type) { var members = type.GetMembers(); var table = new Dictionary(); @@ -78,7 +121,7 @@ public static class NativeLinker table[native.Name] = native; } - _linked[type] = table; + return _linked[type] = table; } } diff --git a/Qrakhen.Qamp.Core/Values/Value.cs b/Qrakhen.Qamp.Core/Values/Value.cs index e7f5eef..66d4a57 100644 --- a/Qrakhen.Qamp.Core/Values/Value.cs +++ b/Qrakhen.Qamp.Core/Values/Value.cs @@ -28,7 +28,6 @@ public readonly record struct Signed(long Value)// : IPrimitive } - public interface IValue { T Data { get; } diff --git a/Qrakhen.Qamp.Core/Values/ValueExtensions.cs b/Qrakhen.Qamp.Core/Values/ValueExtensions.cs index ee246ae..46f64f5 100644 --- a/Qrakhen.Qamp.Core/Values/ValueExtensions.cs +++ b/Qrakhen.Qamp.Core/Values/ValueExtensions.cs @@ -1,8 +1,50 @@ using Qrakhen.Qamp.Core.Execution; +using Qrakhen.Qamp.Core.Values.Objects; namespace Qrakhen.Qamp.Core.Values; internal static class ValueExtensions { + public static Value ToValue(this object obj) + { + if (obj is sbyte _byte) + return new Value((long)_byte); + if (obj is short _short) + return new Value((long)_short); + if (obj is int _int) + return new Value((long)_int); + if (obj is long _long) + return new Value(_long); + if (obj is byte _sbyte) + return new Value((ulong)_sbyte); + if (obj is ushort _ushort) + return new Value((ulong)_ushort); + if (obj is uint _uint) + return new Value((ulong)_uint); + if (obj is ulong _ulong) + return new Value((ulong)_ulong); + + if (obj is bool _bool) + return new Value(_bool); + if (obj is char _char) + return new Value(_char); + if (obj is string _string) + return Objects.String.Make(_string); + + if (obj is float _float) + return new Value(_float); + if (obj is double _double) + return new Value(_double); + + if (obj is Obj _obj) + return Obj.Create(_obj); + + throw new QampException($"Could not convert native system value {obj} to qamp value."); + } + + public static object ToObject(this Value value) + { + + } } \ No newline at end of file diff --git a/Qrakhen.Qamp.Core/Values/ValueType.cs b/Qrakhen.Qamp.Core/Values/ValueType.cs index 8ff2ca4..93a05bb 100644 --- a/Qrakhen.Qamp.Core/Values/ValueType.cs +++ b/Qrakhen.Qamp.Core/Values/ValueType.cs @@ -1,5 +1,29 @@ namespace Qrakhen.Qamp.Core.Values; +// better/smaller/faster idea: +public enum _ValueType : byte +{ + F_Primitive = 0x20, + F_Object = 0x40, + F_Collection = 0x80, + + Void = 0x00, + + Unsigned = 1 | F_Primitive, + Signed = 2 | F_Primitive, + Decimal = 3 | F_Primitive, + Char = 4 | F_Primitive, + Bool = 5 | F_Primitive, +} + +[Flags] +public enum MetaData : ushort +{ + None = 0, + ReadOnly = 0x0001, // hmmmm could be put as either a byte flagset or 2 bools too. cant think of many metadata flags. + Dynamic = 0x0002, +} + /// /// todo: make value type a byte instead to save some memory on values /// edit: if that's even possible with c#'s memory padding @@ -36,7 +60,7 @@ public enum ValueType : ushort Method = Class | Function, Outer = Object | 0x0200, - Complex = Object | 0x0800, + Complex = Object | 0x0800, // unsure if even needed. native does exactly that already. ItemProvider = Object | 0x4000, // accessible with [n] or :n (getters / setters) Array = ItemProvider | 0x0001,