---
source: boltffi_bindgen/src/render/csharp/templates.rs
expression: template.render().unwrap()
---
// <auto-generated>
// This file was generated by BoltFFI. Do not edit.
// </auto-generated>
#nullable enable

using System;
using System.Threading;

namespace Demo
{
    public sealed class Counter : IDisposable
    {
        private IntPtr _handle;

        // Private handle-adopting ctor; used only by chained `: this(...)` and the static factories below.
        private Counter(IntPtr handle)
        {
            _handle = handle;
        }

        public global::System.Threading.Tasks.Task<int> AsyncGet()
            => AsyncGet(global::System.Threading.CancellationToken.None);

        public global::System.Threading.Tasks.Task<int> AsyncGet(global::System.Threading.CancellationToken cancellationToken)
        {
            ThrowIfDisposed();
            return BoltFFIAsync.CallAsync<int>(
                () => NativeMethods.CounterAsyncGet(_handle),
                (future, callbackData, callback) => NativeMethods.CounterAsyncGetPoll(future, callbackData, callback),
                future =>
                {
                    FfiStatus status;
                    int result = NativeMethods.CounterAsyncGetComplete(future, out status);
                    BoltFFIAsync.ThrowIfStatus(status, cancellationToken);
                    return result;
                },
                future => NativeMethods.CounterAsyncGetCancel(future),
                future => NativeMethods.CounterAsyncGetFree(future),
                cancellationToken);
        }

        internal IntPtr RawHandle => _handle;

        private void ThrowIfDisposed()
        {
            if (_handle == IntPtr.Zero) throw new ObjectDisposedException(nameof(Counter));
        }

        public void Dispose()
        {
            IntPtr handle = Interlocked.Exchange(ref _handle, IntPtr.Zero);
            if (handle == IntPtr.Zero) return;
            NativeMethods.CounterFree(handle);
            GC.SuppressFinalize(this);
        }

        ~Counter()
        {
            Dispose();
        }
    }
}
