using Qrakhen.Qamp.Core.Collections; using Qrakhen.Qamp.Core.Values.Objects; namespace Qrakhen.Qamp.Core.Values; public delegate Value ExtensionDelegate(Value target, Value[] parameters); public class NativeExtension( ValueType targetType, string name, ExtensionDelegate callback, string[] parameters) { private static readonly Register> _register = new(); public readonly string Name = name; public readonly ValueType TargetType = targetType; public readonly ExtensionDelegate Callback = callback; public readonly string[] Parameters = parameters.ToArray(); public static NativeExtension? Get(ValueType targetType, string name) { if (!_register.Has(targetType)) return null; if (!_register[targetType].Has(name)) return null; return _register[targetType][name]; } public static void Register(ValueType targetType, string name, ExtensionDelegate callback, params string[] parameters) { if (!_register.Has(targetType)) _register.Add(targetType, new()); if (_register[targetType].Has(name)) throw new QampException($"Extension {name} already exists for type {targetType}."); _register[targetType].Add(name, new NativeExtension(targetType, name, callback, parameters)); } static NativeExtension() { Register(ValueType.String, "Length", (v, p) => new Value((long)v.Ptr.As()!.Value!.Length), []); Register(ValueType.String, "IndexOf", (v, p) => new Value((long)v.Ptr.As()!.Value!.IndexOf(p[0].Ptr.As()!.Value!)), ["needle"]); } public override string ToString() { return $"{TargetType}.{Name}({string.Join(", ", Parameters)}) (NativeExtension)"; } }