using System; using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using PkmnLibSharp.FFI; using PkmnLibSharp.Utils; using Interface = PkmnLibSharp.FFI.StaticData.Ability; namespace PkmnLibSharp.StaticData { public class Ability : ExternPointer { [UsedImplicitly] public class CacheData { public string? Name { get; internal set; } public string? Effect { get; internal set; } public DisposableCachedExternArray? Parameters { get; internal set; } } public Ability(string name, string effect, IReadOnlyCollection parameters) { // Passing effect parameters to Rust gives Rust full control over them, and means it can move it. As such // we remove ownership and invalidate the passed parameters. var parameterArray = parameters.Select(x => x.TakeOwnershipAndInvalidate()).ToArray(); var arrayPtr = parameterArray.ArrayPtr(); InitializePointer(Interface.ability_new(name.ToPtr(), effect.ToPtr(), arrayPtr, (ulong)parameters.Count), true); } internal Ability(IdentifiablePointer ptr) : base(ptr, true) { } public string Name => Cache.Name ?? (Cache.Name = Interface.ability_name(Ptr)); public string Effect => Cache.Effect ?? (Cache.Effect = Interface.ability_effect(Ptr)); public IReadOnlyList Parameters => Cache.Parameters ??= new DisposableCachedExternArray( Interface.ability_parameter_length(Ptr), #pragma warning disable IDISP012 arg => new EffectParameter(Interface.ability_parameter_get(Ptr, arg), false)); #pragma warning restore IDISP012 protected override CacheData CreateCache() { return new CacheData(); } protected override void Destructor() { Interface.ability_drop(Ptr); } public override void InvalidateChildren() { if (Cache.Parameters == null) return; for (var index = 0; index < Cache.Parameters.Count; index++) { Cache.Parameters.GetCachedValue(index)?.Invalidate(); } Cache.Parameters.Dispose(); } ~Ability() { Dispose(); } } }