Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 52 additions & 8 deletions VRCFaceTracking/Services/OpenVRService.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
using System.Reflection;
using System.Diagnostics;
using System.Reflection;
using Microsoft.Extensions.Logging;
using Valve.VR;
using VRCFaceTracking.Core.Contracts.Services;

namespace VRCFaceTracking.Services;

public class OpenVRService
{
private CVRSystem _system;
private readonly ILogger<OpenVRService> _logger;

public OpenVRService(ILogger<OpenVRService> logger)
private readonly IMainService _mainService;
private Thread? _eventPollingThread;
private readonly CancellationTokenSource _pollingCts = new();

public OpenVRService(ILogger<OpenVRService> logger, IMainService mainService)
{
_logger = logger;
_mainService = mainService;
}

public bool Initialize()
{
EVRInitError error = EVRInitError.None;
_system = OpenVR.Init(ref error, EVRApplicationType.VRApplication_Background);

if (error != EVRInitError.None)
{
_logger.LogWarning("Failed to initialize OpenVR: {0}", error);
IsInitialized = false;
return IsInitialized;
}

// Our app.vrmanifest is next to the executable, so we can just use the current directory of the executable
var currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
var fullManifestPath = Path.Combine(currentDirectory, "app.vrmanifest"); // Replace is for Linux
Expand All @@ -36,21 +42,59 @@ public bool Initialize()
IsInitialized = false;
return IsInitialized;
}

_logger.LogInformation("Successfully initialized OpenVR");

IsInitialized = true;

StartEventPolling();

return IsInitialized;
}

private void StartEventPolling()
{
_eventPollingThread = new Thread(() =>
{
var vrEvent = new VREvent_t();
var eventSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VREvent_t));

while (!_pollingCts.IsCancellationRequested)
{
while (_system.PollNextEvent(ref vrEvent, eventSize))
{
if ((EVREventType)vrEvent.eventType == EVREventType.VREvent_Quit)
{
_logger.LogInformation("SteamVR is shutting down. Exiting VRCFT.");
_system.AcknowledgeQuit_Exiting();

// Teardown modules first to kill child processes,
// then force-exit the application.
_mainService.Teardown().GetAwaiter().GetResult();
Core.Utils.KillAllProcessesOfName("VRCFaceTracking.ModuleProcess");
Environment.Exit(0);
return;
}
}

Thread.Sleep(200);
}
})
{
IsBackground = true,
Name = "OpenVR Event Polling"
};
_eventPollingThread.Start();
}

public void InitIfNotAlready()
{
if (!IsInitialized)
{
Initialize();
}
}

public bool IsInitialized { get; private set; }

public bool AutoStart
Expand Down