qamp/Qrakhen.Qamp.Core/Values/NativeExtension.cs

53 lines
1.9 KiB
C#

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<ValueType, Register<string, NativeExtension>> _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<Objects.String>()!.Value!.Length), []);
Register(ValueType.String, "IndexOf", (v, p) => new Value((long)v.Ptr.As<Objects.String>()!.Value!.IndexOf(p[0].Ptr.As<Objects.String>()!.Value!)), [ "needle" ]);
}
public override string ToString()
{
return $"{TargetType}.{Name}({string.Join(", ", Parameters)}) (NativeExtension)";
}
}