using System; using System.Collections.Concurrent; namespace PkmnLibSharp { public abstract class PointerWrapper : IDisposable { private readonly IntPtr _ptr; internal IntPtr Ptr { get { if (_isDeleted) { throw new Exception("Pointer access after dispose detected. This is not legal, and will cause native exceptions."); } return _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 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; } } }