133 lines
3.3 KiB
C#
133 lines
3.3 KiB
C#
using System;
|
|
using System.Runtime.CompilerServices;
|
|
using PkmnLibSharp.FFI;
|
|
|
|
[assembly: InternalsVisibleTo("PkmnLibRSharp")]
|
|
namespace PkmnLibSharp.Utils
|
|
{
|
|
public abstract class ExternPointer<TCache> : BasePointer<TCache>
|
|
where TCache : class
|
|
{
|
|
private bool _isOwner;
|
|
private bool _isInvalidated;
|
|
private bool _isDisposed;
|
|
|
|
protected ExternPointer()
|
|
{
|
|
|
|
}
|
|
|
|
protected ExternPointer(IntPtr ptr, bool isOwner)
|
|
{
|
|
InitializePointer(ptr, isOwner);
|
|
}
|
|
|
|
protected ExternPointer(IdentifiablePointer ptr, bool isOwner) : base(ptr)
|
|
{
|
|
_isOwner = isOwner;
|
|
}
|
|
|
|
|
|
protected void InitializePointer(IntPtr ptr, bool isOwner)
|
|
{
|
|
InitializePointer(ptr);
|
|
_isOwner = isOwner;
|
|
}
|
|
|
|
protected void InitializePointer(IdentifiablePointer ptr, bool isOwner)
|
|
{
|
|
InitializePointer(ptr);
|
|
_isOwner = isOwner;
|
|
}
|
|
|
|
internal override IntPtr Ptr
|
|
{
|
|
get
|
|
{
|
|
if (_isInvalidated)
|
|
{
|
|
throw new Exception("Pointer was used after invalidate");
|
|
}
|
|
return base.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;
|
|
}
|
|
|
|
internal void Invalidate()
|
|
{
|
|
_isInvalidated = true;
|
|
CacheHandler.RemoveCache(Identifier);
|
|
InvalidateChildren();
|
|
}
|
|
|
|
public virtual void InvalidateChildren(){}
|
|
|
|
public override void Dispose()
|
|
{
|
|
if (_isDisposed)
|
|
return;
|
|
if (_isOwner)
|
|
{
|
|
InvalidateChildren();
|
|
if (!_isInvalidated)
|
|
Destructor();
|
|
_isOwner = false;
|
|
CacheHandler.RemoveCache(Identifier);
|
|
}
|
|
_isDisposed = true;
|
|
_isInvalidated = true;
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj is ExternPointer<TCache> other)
|
|
{
|
|
return Identifier == other.Identifier;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected bool Equals(ExternPointer<TCache> other)
|
|
{
|
|
if (Identifier != 0)
|
|
{
|
|
return Identifier == other.Identifier;
|
|
}
|
|
return Ptr == other.Ptr;
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
if (Identifier != 0)
|
|
return (int)Identifier;
|
|
return (int)Ptr;
|
|
}
|
|
|
|
public static bool operator ==(ExternPointer<TCache>? left, ExternPointer<TCache>? right)
|
|
{
|
|
return Equals(left, right);
|
|
}
|
|
|
|
public static bool operator !=(ExternPointer<TCache>? left, ExternPointer<TCache>? right)
|
|
{
|
|
return !Equals(left, right);
|
|
}
|
|
}
|
|
} |