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;
}
}
}