using nspector.Native.NVAPI2;
using System;
using nvw = nspector.Native.NVAPI2.NvapiDrsWrapper;
namespace nspector.Common
{
public class DrsSessionScope
{
public static volatile IntPtr GlobalSession;
public static volatile bool HoldSession = true;
private static object _Sync = new object();
public static T DrsSession<T>(Func<IntPtr, T> action, bool forceNonGlobalSession = false, bool preventLoadSettings = false)
{
lock (_Sync)
{
if (!HoldSession || forceNonGlobalSession)
return NonGlobalDrsSession<T>(action, preventLoadSettings);
if (GlobalSession == IntPtr.Zero)
{
#pragma warning disable CS0420
var csRes = nvw.DRS_CreateSession(ref GlobalSession);
#pragma warning restore CS0420
if (csRes != NvAPI_Status.NVAPI_OK)
throw new NvapiException("DRS_CreateSession", csRes);
if (!preventLoadSettings)
{
var nvRes = nvw.DRS_LoadSettings(GlobalSession);
if (nvRes != NvAPI_Status.NVAPI_OK)
throw new NvapiException("DRS_LoadSettings", nvRes);
}
}
}
if (GlobalSession != IntPtr.Zero)
{
return action(GlobalSession);
}
throw new Exception(nameof(GlobalSession) + " is Zero!");
}
public static void DestroyGlobalSession()
{
lock (_Sync)
{
if (GlobalSession != IntPtr.Zero)
{
var csRes = nvw.DRS_DestroySession(GlobalSession);
GlobalSession = IntPtr.Zero;
}
}
}
private static T NonGlobalDrsSession<T>(Func<IntPtr, T> action, bool preventLoadSettings = false)
{
IntPtr hSession = IntPtr.Zero;
var csRes = nvw.DRS_CreateSession(ref hSession);
if (csRes != NvAPI_Status.NVAPI_OK)
throw new NvapiException("DRS_CreateSession", csRes);
try
{
if (!preventLoadSettings)
{
var nvRes = nvw.DRS_LoadSettings(hSession);
if (nvRes != NvAPI_Status.NVAPI_OK)
throw new NvapiException("DRS_LoadSettings", nvRes);
}
return action(hSession);
}
finally
{
var nvRes = nvw.DRS_DestroySession(hSession);
if (nvRes != NvAPI_Status.NVAPI_OK)
throw new NvapiException("DRS_DestroySession", nvRes);
}
}
}
}