PkmnLibRSharp/PkmnLibRSharp/Utils/ExternPointer.cs

133 lines
3.3 KiB
C#
Raw Normal View History

2022-09-18 16:02:27 +00:00
using System;
using System.Runtime.CompilerServices;
2022-10-08 11:42:30 +00:00
using PkmnLibSharp.FFI;
2022-09-18 16:02:27 +00:00
[assembly: InternalsVisibleTo("PkmnLibRSharp")]
namespace PkmnLibSharp.Utils
{
2022-10-08 11:42:30 +00:00
public abstract class ExternPointer<TCache> : BasePointer<TCache>
2022-09-18 16:02:27 +00:00
where TCache : class
{
private bool _isOwner;
private bool _isInvalidated;
private bool _isDisposed;
protected ExternPointer()
{
}
protected ExternPointer(IntPtr ptr, bool isOwner)
{
InitializePointer(ptr, isOwner);
}
2022-10-08 11:42:30 +00:00
protected ExternPointer(IdentifiablePointer ptr, bool isOwner) : base(ptr)
{
_isOwner = isOwner;
}
2022-09-18 16:02:27 +00:00
protected void InitializePointer(IntPtr ptr, bool isOwner)
{
2022-10-08 11:42:30 +00:00
InitializePointer(ptr);
_isOwner = isOwner;
}
protected void InitializePointer(IdentifiablePointer ptr, bool isOwner)
{
InitializePointer(ptr);
2022-09-18 16:02:27 +00:00
_isOwner = isOwner;
}
2022-10-08 11:42:30 +00:00
internal override IntPtr Ptr
2022-09-18 16:02:27 +00:00
{
get
{
if (_isInvalidated)
{
throw new Exception("Pointer was used after invalidate");
}
2022-10-08 11:42:30 +00:00
return base.Ptr;
2022-09-18 16:02:27 +00:00
}
}
private IntPtr TakeOwnership()
2022-09-18 16:02:27 +00:00
{
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;
}
2022-10-01 13:39:33 +00:00
internal void Invalidate()
2022-09-18 16:02:27 +00:00
{
_isInvalidated = true;
2022-10-08 11:42:30 +00:00
CacheHandler.RemoveCache(Identifier);
2022-10-01 13:39:33 +00:00
InvalidateChildren();
2022-09-18 16:02:27 +00:00
}
2022-10-01 13:39:33 +00:00
public virtual void InvalidateChildren(){}
2022-09-18 16:02:27 +00:00
2022-10-08 11:42:30 +00:00
public override void Dispose()
2022-09-18 16:02:27 +00:00
{
if (_isDisposed)
return;
if (_isOwner)
{
2022-10-01 13:39:33 +00:00
InvalidateChildren();
2022-09-18 16:02:27 +00:00
if (!_isInvalidated)
Destructor();
_isOwner = false;
2022-10-08 11:42:30 +00:00
CacheHandler.RemoveCache(Identifier);
2022-09-18 16:02:27 +00:00
}
_isDisposed = true;
_isInvalidated = true;
2022-10-08 11:42:30 +00:00
GC.SuppressFinalize(this);
2022-09-18 16:02:27 +00:00
}
2023-04-15 07:58:21 +00:00
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);
}
2022-09-18 16:02:27 +00:00
}
}