diff --git a/Mediapipe.Net/Core/Disposable.cs b/Mediapipe.Net/Core/Disposable.cs new file mode 100644 index 0000000..5c132e5 --- /dev/null +++ b/Mediapipe.Net/Core/Disposable.cs @@ -0,0 +1,63 @@ +// Copyright (c) homuler and Vignette +// This file is part of MediaPipe.NET. +// MediaPipe.NET is licensed under the MIT License. See LICENSE for details. + + +using System; +using System.Threading; + +namespace Mediapipe.Net.Core; + +/// +/// based on OpenCvSharp +/// +public abstract class Disposable : IDisposable +{ + private volatile int disposeSignaled = 0; + + public bool IsDisposed { get; protected set; } + protected bool IsOwner { get; private set; } + + protected Disposable() : this(true) { } + + protected Disposable(bool isOwner) + { + IsDisposed = false; + IsOwner = isOwner; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (Interlocked.Exchange(ref disposeSignaled, 1) != 0) + return; + + IsDisposed = true; + + if (disposing) + DisposeManaged(); + + DisposeUnmanaged(); + } + + ~Disposable() + { + Dispose(false); + } + + protected virtual void DisposeManaged() { } + protected virtual void DisposeUnmanaged() { } + + public void TransferOwnership() => IsOwner = false; + + public void ThrowIfDisposed() + { + if (IsDisposed) + throw new ObjectDisposedException(GetType().FullName); + } +} diff --git a/Mediapipe.Net/Core/IMpResourceHandle.cs b/Mediapipe.Net/Core/IMpResourceHandle.cs new file mode 100644 index 0000000..15f5c23 --- /dev/null +++ b/Mediapipe.Net/Core/IMpResourceHandle.cs @@ -0,0 +1,28 @@ +// Copyright (c) homuler and Vignette +// This file is part of MediaPipe.NET. +// MediaPipe.NET is licensed under the MIT License. See LICENSE for details. + +using System; + +namespace Mediapipe.Net.Core; + +public interface IMpResourceHandle : IDisposable +{ + IntPtr MpPtr { get; } + + /// + /// Relinquish the ownership, and release the resource it owns if necessary. + /// This method should be called only if the underlying native api moves the pointer. + /// + /// + /// If the object itself is no longer used, call instead. + /// + void ReleaseMpResource(); + + /// + /// Relinquish the ownership + /// + void TransferOwnership(); + + bool OwnsResource(); +} diff --git a/Mediapipe.Net/Core/InternalException.cs b/Mediapipe.Net/Core/InternalException.cs new file mode 100644 index 0000000..8700f07 --- /dev/null +++ b/Mediapipe.Net/Core/InternalException.cs @@ -0,0 +1,12 @@ +// Copyright (c) homuler and Vignette +// This file is part of MediaPipe.NET. +// MediaPipe.NET is licensed under the MIT License. See LICENSE for details. + +using System; + +namespace Mediapipe.Net.Core; + +public class InternalException : Exception +{ + public InternalException(string message) : base(message) { } +} diff --git a/Mediapipe.Net/Core/MediapipeException.cs b/Mediapipe.Net/Core/MediapipeException.cs new file mode 100644 index 0000000..38e3320 --- /dev/null +++ b/Mediapipe.Net/Core/MediapipeException.cs @@ -0,0 +1,12 @@ +// Copyright (c) homuler and Vignette +// This file is part of MediaPipe.NET. +// MediaPipe.NET is licensed under the MIT License. See LICENSE for details. + +using System; + +namespace Mediapipe.Net.Core; + +public class MediapipeException : Exception +{ + public MediapipeException(string message) : base(message) { } +} diff --git a/Mediapipe.Net/Core/MediapipeNetException.cs b/Mediapipe.Net/Core/MediapipeNetException.cs new file mode 100644 index 0000000..c476eac --- /dev/null +++ b/Mediapipe.Net/Core/MediapipeNetException.cs @@ -0,0 +1,12 @@ +// Copyright (c) homuler and Vignette +// This file is part of MediaPipe.NET. +// MediaPipe.NET is licensed under the MIT License. See LICENSE for details. + +using System; + +namespace Mediapipe.Net.Core; + +public class MediapipeNetException : Exception +{ + public MediapipeNetException(string message) : base(message) { } +} diff --git a/Mediapipe.Net/Core/MpResourceHandle.cs b/Mediapipe.Net/Core/MpResourceHandle.cs new file mode 100644 index 0000000..35208a2 --- /dev/null +++ b/Mediapipe.Net/Core/MpResourceHandle.cs @@ -0,0 +1,76 @@ +// Copyright (c) homuler and Vignette +// This file is part of MediaPipe.NET. +// MediaPipe.NET is licensed under the MIT License. See LICENSE for details. + +using System; +using System.Runtime.InteropServices; +using Mediapipe.Net.Native; +using static Mediapipe.Net.Native.MpReturnCodeExtension; + +namespace Mediapipe.Net.Core; + +public abstract class MpResourceHandle : Disposable, IMpResourceHandle +{ + protected IntPtr Ptr; + + protected MpResourceHandle(bool isOwner = true) : this(IntPtr.Zero, isOwner) { } + + protected MpResourceHandle(IntPtr ptr, bool isOwner = true) : base(isOwner) + { + Ptr = ptr; + } + + #region IMpResourceHandle + public IntPtr MpPtr + { + get + { + ThrowIfDisposed(); + return Ptr; + } + } + + public void ReleaseMpResource() + { + if (OwnsResource()) + DeleteMpPtr(); + + TransferOwnership(); + } + + public bool OwnsResource() => IsOwner && Ptr != IntPtr.Zero; + #endregion + + protected override void DisposeUnmanaged() + { + if (OwnsResource()) + DeleteMpPtr(); + + ReleaseMpPtr(); + base.DisposeUnmanaged(); + } + + /// + /// Forgets the pointer address. + /// After calling this method, will return false. + /// + protected void ReleaseMpPtr() => Ptr = IntPtr.Zero; + + /// + /// Release the memory (call `delete` or `delete[]`) whether or not it owns it. + /// + /// In most cases, this method should not be called directly. + protected abstract void DeleteMpPtr(); + + protected delegate MpReturnCode StringOutFunc(IntPtr ptr, out IntPtr strPtr); + protected string? MarshalStringFromNative(StringOutFunc func) + { + func(MpPtr, out IntPtr strPtr).Assert(); + GC.KeepAlive(this); + + string? str = Marshal.PtrToStringAnsi(strPtr); + UnsafeNativeMethods.delete_array__PKc(strPtr); + + return str; + } +} diff --git a/Mediapipe.Net/Core/SharedPtrHandle.cs b/Mediapipe.Net/Core/SharedPtrHandle.cs new file mode 100644 index 0000000..b688eed --- /dev/null +++ b/Mediapipe.Net/Core/SharedPtrHandle.cs @@ -0,0 +1,18 @@ +// Copyright (c) homuler and Vignette +// This file is part of MediaPipe.NET. +// MediaPipe.NET is licensed under the MIT License. See LICENSE for details. + +using System; + +namespace Mediapipe.Net.Core; + +public abstract class SharedPtrHandle : MpResourceHandle +{ + protected SharedPtrHandle(IntPtr ptr, bool isOwner = true) : base(ptr, isOwner) { } + + /// The owning pointer + public abstract IntPtr Get(); + + /// Release the owning pointer + public abstract void Reset(); +} diff --git a/Mediapipe.Net/Core/UniquePtrHandle.cs b/Mediapipe.Net/Core/UniquePtrHandle.cs new file mode 100644 index 0000000..c749515 --- /dev/null +++ b/Mediapipe.Net/Core/UniquePtrHandle.cs @@ -0,0 +1,18 @@ +// Copyright (c) homuler and Vignette +// This file is part of MediaPipe.NET. +// MediaPipe.NET is licensed under the MIT License. See LICENSE for details. + +using System; + +namespace Mediapipe.Net.Core; + +public abstract class UniquePtrHandle : MpResourceHandle +{ + protected UniquePtrHandle(IntPtr ptr, bool isOwner = true) : base(ptr, isOwner) { } + + /// The owning pointer + public abstract IntPtr Get(); + + /// Release the owning pointer + public abstract IntPtr Release(); +}