96 lines
2.2 KiB
C#
96 lines
2.2 KiB
C#
|
using System;
|
||
|
using System.Runtime.CompilerServices;
|
||
|
|
||
|
[assembly: InternalsVisibleTo("PkmnLibRSharp")]
|
||
|
namespace PkmnLibSharp.Utils
|
||
|
{
|
||
|
public abstract class ExternPointer<TCache> : 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<TCache>(_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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal 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;
|
||
|
}
|
||
|
|
||
|
internal void Invalidate()
|
||
|
{
|
||
|
_isInvalidated = true;
|
||
|
CacheHandler.RemoveCache(_ptr);
|
||
|
}
|
||
|
|
||
|
~ExternPointer()
|
||
|
{
|
||
|
Dispose();
|
||
|
}
|
||
|
|
||
|
public void Dispose()
|
||
|
{
|
||
|
if (_isDisposed)
|
||
|
return;
|
||
|
if (_isOwner)
|
||
|
{
|
||
|
if (!_isInvalidated)
|
||
|
Destructor();
|
||
|
_isOwner = false;
|
||
|
CacheHandler.RemoveCache(_ptr);
|
||
|
}
|
||
|
_isDisposed = true;
|
||
|
_isInvalidated = true;
|
||
|
}
|
||
|
}
|
||
|
}
|