using System; using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("PkmnLibRSharp")] namespace PkmnLibSharp.Utils { public abstract class ExternPointer : IDisposable where TCache : class { private IntPtr _ptr; private bool _isOwner; private bool _isInvalidated; private bool _isDisposed; private TCache? _cache; protected abstract TCache CreateCache(); internal TCache Cache { get { return _cache ??= CacheHandler.GetCache(_ptr, CreateCache); } } protected ExternPointer() { } protected ExternPointer(IntPtr ptr, bool isOwner) { InitializePointer(ptr, isOwner); } protected void InitializePointer(IntPtr ptr, bool isOwner) { _ptr = ptr; _isOwner = isOwner; } protected abstract void Destructor(); internal IntPtr Ptr { get { if (_isInvalidated) { throw new Exception("Pointer was used after invalidate"); } return _ptr; } } private IntPtr TakeOwnership() { if (!_isOwner) { throw new Exception("Tried to take ownership of a non-owned object"); } _isOwner = false; return Ptr; } internal IntPtr TakeOwnershipAndInvalidate() { var ptr = TakeOwnership(); Invalidate(); return ptr; } private void Invalidate() { _isInvalidated = true; CacheHandler.RemoveCache(_ptr); } public void Dispose() { if (_isDisposed) return; if (_isOwner) { if (!_isInvalidated) Destructor(); _isOwner = false; CacheHandler.RemoveCache(_ptr); } _isDisposed = true; _isInvalidated = true; } } }