summaryrefslogtreecommitdiffstats
path: root/WhisperNet/Internal/sLoadModelCallbacks.cs
blob: 07f51999e5d5bd426d37e28437b0b20573755243 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System.Runtime.InteropServices;

namespace Whisper.Internal
{
	/// <summary>Function pointer to report model loading progress</summary>
	[UnmanagedFunctionPointer( CallingConvention.StdCall )]
	delegate int pfnLoadProgress( double progress, IntPtr pv );

	/// <summary>Function pointer to implement cooperative cancellation</summary>
	[UnmanagedFunctionPointer( CallingConvention.StdCall )]
	delegate int pfnCancel( IntPtr pv );

	/// <summary>Callback functions for loading models</summary>
	public struct sLoadModelCallbacks
	{
		/// <summary>Function pointer to report model loading progress</summary>
		[MarshalAs( UnmanagedType.FunctionPtr )]
		pfnLoadProgress? progress;

		/// <summary>Function pointer to implement cooperative cancellation</summary>
		[MarshalAs( UnmanagedType.FunctionPtr )]
		pfnCancel? cancel;

		// Not needed in C#, delegates can capture things
		IntPtr pv;

		/// <summary>Wrap idiomatic C# things into these low-level C callbacks</summary>
		internal sLoadModelCallbacks( CancellationToken cancelToken, Action<double>? 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;
		}
	}
}