using System.Runtime.InteropServices; namespace Whisper.Internal { /// Function pointer to report model loading progress [UnmanagedFunctionPointer( CallingConvention.StdCall )] delegate int pfnLoadProgress( double progress, IntPtr pv ); /// Function pointer to implement cooperative cancellation [UnmanagedFunctionPointer( CallingConvention.StdCall )] delegate int pfnCancel( IntPtr pv ); /// Callback functions for loading models public struct sLoadModelCallbacks { /// Function pointer to report model loading progress [MarshalAs( UnmanagedType.FunctionPtr )] pfnLoadProgress? progress; /// Function pointer to implement cooperative cancellation [MarshalAs( UnmanagedType.FunctionPtr )] pfnCancel? cancel; // Not needed in C#, delegates can capture things IntPtr pv; /// Wrap idiomatic C# things into these low-level C callbacks internal sLoadModelCallbacks( CancellationToken cancelToken, Action? pfnProgress ) { if( cancelToken != CancellationToken.None ) { cancel = delegate ( IntPtr pv ) { if( cancelToken.IsCancellationRequested ) return 1; // S_FALSE return 0; // S_OK }; } else cancel = null; if( null != pfnProgress ) { progress = delegate ( double val, IntPtr pv ) { try { pfnProgress( val ); return 0; // S_OK } catch( Exception ex ) { NativeLogger.captureException( ex ); return ex.HResult; } }; } else progress = null; pv = IntPtr.Zero; } } }