From 42ec20842550cddb7249a5dc653a04cbcfbb32ef Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sun, 3 May 2020 17:14:07 +0200 Subject: [PATCH] Cache created wrappers for pointers, so we can resolve them later. --- PkmnLibSharp/Library/EffectParameter.cs | 3 +-- PkmnLibSharp/Library/Forme.cs | 17 ++++++++++++++--- PkmnLibSharp/Library/LearnableMoves.cs | 4 ++-- PkmnLibSharp/Library/MoveData.cs | 2 +- PkmnLibSharp/Library/Species.cs | 2 +- PkmnLibSharp/PointerWrapper.cs | 23 ++++++++++++++++++++++- 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/PkmnLibSharp/Library/EffectParameter.cs b/PkmnLibSharp/Library/EffectParameter.cs index 2d201c8..be613ee 100644 --- a/PkmnLibSharp/Library/EffectParameter.cs +++ b/PkmnLibSharp/Library/EffectParameter.cs @@ -54,8 +54,7 @@ namespace PkmnLibSharp.Library } - - internal override void DeletePtr() + protected override void DeletePtr() { Creatureliblibrary.Generated.EffectParameter.Destruct(Ptr); } diff --git a/PkmnLibSharp/Library/Forme.cs b/PkmnLibSharp/Library/Forme.cs index fb2cf90..f9dece0 100644 --- a/PkmnLibSharp/Library/Forme.cs +++ b/PkmnLibSharp/Library/Forme.cs @@ -67,7 +67,6 @@ namespace PkmnLibSharp.Library return _abilities; } } - public ImmutableArray HiddenAbilities { get @@ -89,13 +88,25 @@ namespace PkmnLibSharp.Library } } + public LearnableMoves Moves + { + get + { + if (_moves != null) return _moves; + var movesPtr = SpeciesVariant.GetLearnableAttacks(Ptr); + if (!TryResolvePointer(movesPtr, out _moves)) + { + _moves = new LearnableMoves(movesPtr); + } + return _moves; + } + } public int GetPkmnType(int index) { return Types[index]; } - public static unsafe Forme Create(string name, float height, float weight, uint baseExperience, byte[] types, ushort baseHealth, ushort baseAttack, ushort baseDefense, ushort baseSpecialAttack, ushort baseSpecialDefense, ushort baseSpeed, string[] abilities, string[] hiddenAbilities, @@ -125,7 +136,7 @@ namespace PkmnLibSharp.Library { } - internal override void DeletePtr() + protected override void DeletePtr() { SpeciesVariant.Destruct(Ptr); } diff --git a/PkmnLibSharp/Library/LearnableMoves.cs b/PkmnLibSharp/Library/LearnableMoves.cs index cc12de3..e7aeb5d 100644 --- a/PkmnLibSharp/Library/LearnableMoves.cs +++ b/PkmnLibSharp/Library/LearnableMoves.cs @@ -5,7 +5,7 @@ namespace PkmnLibSharp.Library { public class LearnableMoves : PointerWrapper { - private LearnableMoves(IntPtr ptr) : base(ptr) + internal LearnableMoves(IntPtr ptr) : base(ptr) { } @@ -21,7 +21,7 @@ namespace PkmnLibSharp.Library LearnableAttacks.AddLevelAttack(Ptr, level, move.Ptr); } - internal override void DeletePtr() + protected override void DeletePtr() { LearnableAttacks.Destruct(Ptr); } diff --git a/PkmnLibSharp/Library/MoveData.cs b/PkmnLibSharp/Library/MoveData.cs index 8c6df79..e356ba5 100644 --- a/PkmnLibSharp/Library/MoveData.cs +++ b/PkmnLibSharp/Library/MoveData.cs @@ -50,7 +50,7 @@ namespace PkmnLibSharp.Library { } - internal override void DeletePtr() + protected override void DeletePtr() { AttackData.Destruct(Ptr); } diff --git a/PkmnLibSharp/Library/Species.cs b/PkmnLibSharp/Library/Species.cs index 391804e..6d23e00 100644 --- a/PkmnLibSharp/Library/Species.cs +++ b/PkmnLibSharp/Library/Species.cs @@ -20,7 +20,7 @@ namespace PkmnLibSharp.Library return new Species(ptr); } - internal override void DeletePtr() + protected override void DeletePtr() { PokemonSpecies.Destruct(Ptr); } diff --git a/PkmnLibSharp/PointerWrapper.cs b/PkmnLibSharp/PointerWrapper.cs index 8857f4b..e0dc841 100644 --- a/PkmnLibSharp/PointerWrapper.cs +++ b/PkmnLibSharp/PointerWrapper.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; namespace PkmnLibSharp { @@ -7,16 +8,36 @@ namespace PkmnLibSharp internal readonly IntPtr Ptr; private bool _isDeleted = false; + private static readonly ConcurrentDictionary> Cached = + new ConcurrentDictionary>(); + protected PointerWrapper(IntPtr ptr) { Ptr = ptr; + var weakRef = new WeakReference(this); + Cached.TryAdd(ptr, weakRef); } - internal abstract void DeletePtr(); + internal static bool TryResolvePointer(IntPtr p, out T result) where T : PointerWrapper + { + if (Cached.TryGetValue(p, out var val)) + { + if (val.TryGetTarget(out var target)) + { + result = (T) target; + return true; + } + } + result = null; + return false; + } + + protected abstract void DeletePtr(); public virtual void Dispose() { if (_isDeleted) return; + Cached.TryRemove(Ptr, out _); DeletePtr(); _isDeleted = true; }