Skip to content

Commit 4fc9d2f

Browse files
committed
on SteamVR close
* Turns off lighthouses when the SteamVR is turned off.
1 parent 1e644fd commit 4fc9d2f

5 files changed

Lines changed: 126 additions & 44 deletions

File tree

LighthouseV2PowerControl/Form1.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Drawing;
33
using System.Linq;
44
using System.Windows.Forms;
5-
using Valve.VR;
65

76

87
namespace LighthouseV2PowerControl

LighthouseV2PowerControl/LighthouseV2PowerControl.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,13 @@
2020
</Reference>
2121
</ItemGroup>
2222

23+
<ItemGroup>
24+
<None Update="manifest.vrmanifest">
25+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
26+
</None>
27+
<None Update="openvr_api.dll">
28+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
29+
</None>
30+
</ItemGroup>
31+
2332
</Project>

LighthouseV2PowerControl/Program.cs

Lines changed: 101 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,51 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Diagnostics;
43
using System.IO;
54
using System.Text.RegularExpressions;
6-
using System.Threading;
75
using System.Threading.Tasks;
86
using System.Windows.Forms;
9-
using Windows.ApplicationModel.Email.DataProvider;
107
using Windows.Devices.Bluetooth;
118
using Windows.Devices.Bluetooth.GenericAttributeProfile;
129
using Windows.Devices.Enumeration;
13-
using Windows.Media.Capture;
1410
using Windows.Storage.Streams;
1511
using Valve.VR;
12+
using System.Threading;
1613

1714
namespace LighthouseV2PowerControl
1815
{
1916
static class Program
2017
{
21-
private static Guid service = Guid.Parse("00001523-1212-efde-1523-785feabcd124");
22-
private static Guid characteristic = Guid.Parse("00001525-1212-efde-1523-785feabcd124");
23-
private static byte activateByte = 0x01;
24-
private static byte deactivateByte = 0x00;
18+
private static readonly Regex regex = new Regex("^LHB-.{8}");
19+
private static readonly Guid service = Guid.Parse("00001523-1212-efde-1523-785feabcd124");
20+
private static readonly Guid characteristic = Guid.Parse("00001525-1212-efde-1523-785feabcd124");
21+
private static readonly byte activateByte = 0x01;
22+
private static readonly byte deactivateByte = 0x00;
2523
private static List<GattCharacteristic> listGattCharacteristics = new List<GattCharacteristic>();
2624

27-
private static Regex regex = new Regex("^LHB-.{8}");
2825

2926
public delegate void LogHandler(object msg, LogType type);
3027
public static event LogHandler OnLog;
3128
private static Form1 app = null;
3229
private static CVRSystem OVRSystem;
30+
private static bool isEnabledVR = false;
31+
private static Thread onQuitThread;
32+
private static CancellationTokenSource cancellationToken = new CancellationTokenSource();
3333

3434
static void Main(string[] args)
3535
{
3636
Application.SetHighDpiMode(HighDpiMode.SystemAware);
3737
Application.EnableVisualStyles();
3838
Application.SetCompatibleTextRenderingDefault(false);
39-
39+
Application.ApplicationExit += (obj, e) => cancellationToken.Cancel();
4040
app = new Form1();
4141
OnLog += (msg, type) => app.Log(msg, type);
42+
if (args.Length > 0)
43+
{
44+
app.ShowInTaskbar = false;
45+
app.WindowState = FormWindowState.Minimized;
46+
UseArgumentsAsync(args);
47+
}
48+
4249
try
4350
{
4451
EVRInitError error = EVRInitError.None;
@@ -51,35 +58,72 @@ static void Main(string[] args)
5158
{
5259
LogError(error);
5360
}
61+
else
62+
{
63+
isEnabledVR = true;
64+
OVRSystem.AcknowledgeQuit_Exiting();
65+
onQuitThread = new Thread(new ThreadStart(QuitThreadChecker));
66+
onQuitThread.Start();
67+
}
5468
}
5569
catch (Exception e)
5670
{
5771
LogError(e.Message);
5872
}
5973

74+
if (isEnabledVR)
75+
{
76+
SendOnStart();
77+
}
78+
else
79+
{
80+
GetGattCharacteristicsAsync();
81+
}
82+
6083
Stack<EventHandler> eventHandlers = new Stack<EventHandler>(); //Ïðñîòî äëÿ óäîáíîãî íàçíà÷åíèÿ êíîïîê.
6184
eventHandlers.Push(new EventHandler((obj, args) => SendActiveStatus(true)));
6285
eventHandlers.Push(new EventHandler((obj, args) => SendActiveStatus(false)));
63-
eventHandlers.Push(new EventHandler((obj, args) => SetAppManifest()));
64-
eventHandlers.Push(new EventHandler((obj, args) => RmAppManifest()));
86+
eventHandlers.Push(new EventHandler((obj, args) => AppManifest(WithManifestTask.add)));
87+
eventHandlers.Push(new EventHandler((obj, args) => AppManifest(WithManifestTask.rm)));
6588
foreach (Button button in app.GetButtons())
6689
{
6790
button.Click += eventHandlers.Pop();
6891
}
92+
Application.Run(app);
93+
}
6994

70-
if (args.Length > 0)
95+
96+
/// <summary>
97+
/// A thread that does not allow the application to close until the base stations are disabled
98+
/// </summary>
99+
private static void QuitThreadChecker()
100+
{
101+
while (true && !cancellationToken.IsCancellationRequested)
71102
{
72-
app.ShowInTaskbar = false;
73-
app.WindowState = FormWindowState.Minimized;
74-
UseArgumentsAsync(args);
103+
Thread.Sleep(100);
104+
VREvent_t lastEvent = new VREvent_t();
105+
OVRSystem.PollNextEvent(ref lastEvent,
106+
(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VREvent_t)));
107+
if ((EVREventType)lastEvent.eventType == EVREventType.VREvent_Quit)
108+
{
109+
OVRSystem.AcknowledgeQuit_Exiting();
110+
SendOnLighthouseAsync(deactivateByte);
111+
break;
112+
}
75113
}
76-
else
114+
115+
while (!cancellationToken.IsCancellationRequested)
77116
{
78-
GetGattCharacteristicsAsync();
117+
OVRSystem.AcknowledgeQuit_Exiting();
79118
}
80-
Application.Run(app);
119+
Exit();
81120
}
82121

122+
#region Bluetooth
123+
/// <summary>
124+
/// Call once at startup to get the characteristics of all base stations.
125+
/// </summary>
126+
/// <returns></returns>
83127
private static async Task GetGattCharacteristicsAsync()
84128
{
85129
DeviceInformationCollection GatDevices = await DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(service));
@@ -150,10 +194,27 @@ private static async Task SendOnLighthouseAsync(byte byte4send)
150194
}
151195
}
152196
app.BtnActive(true);
197+
if(byte4send == activateByte) return;
198+
cancellationToken.Cancel(); //Äëÿ âûõîäà èç òðåäà è êîððåêòíîãî îòêëþ÷åíèÿ.
153199
}
154200

201+
public static void SendActiveStatus(bool status)
202+
{
203+
SendOnLighthouseAsync((status) ? activateByte : deactivateByte);
204+
}
205+
206+
public static async Task SendOnStart()
207+
{
208+
await GetGattCharacteristicsAsync();
209+
await SendOnLighthouseAsync(activateByte);
210+
}
211+
#endregion
155212

156-
private static async void UseArgumentsAsync(string[] args)
213+
/// <summary>
214+
/// Processing arguments at the start of the application.
215+
/// </summary>
216+
/// <param name="args"></param>
217+
private static async void UseArgumentsAsync(string[] args)
157218
{
158219
await GetGattCharacteristicsAsync();
159220
if (args[0] == "--powerOn")
@@ -166,11 +227,11 @@ private static async void UseArgumentsAsync(string[] args)
166227
}
167228
else if (args[0] == "--reg")
168229
{
169-
SetAppManifest();
230+
AppManifest(WithManifestTask.add);
170231
}
171232
else if (args[0] == "--rm")
172233
{
173-
RmAppManifest();
234+
AppManifest(WithManifestTask.rm);
174235
}
175236
Exit();
176237
}
@@ -187,41 +248,32 @@ private static void LogError(object msg)
187248
OnLog.Invoke(msg, LogType.error);
188249
}
189250

190-
private static void SetAppManifest()
251+
private static void AppManifest(WithManifestTask task)
191252
{
192253
EVRInitError evrInitError = EVRInitError.None;
193254
OpenVR.Init(ref evrInitError, EVRApplicationType.VRApplication_Utility);
194255
if (evrInitError != EVRInitError.None)
195256
{
196257
LogError(evrInitError);
258+
return;
197259
}
198260

199-
EVRApplicationError applicationError = OpenVR.Applications.AddApplicationManifest(Directory.GetCurrentDirectory() + @"\manifest.vrmanifest", false);
200-
if (applicationError != EVRApplicationError.None){
201-
LogError(applicationError);
261+
EVRApplicationError applicationError;
262+
if (task == WithManifestTask.add)
263+
{
264+
applicationError = OpenVR.Applications.AddApplicationManifest(Directory.GetCurrentDirectory() + @"\manifest.vrmanifest", false);
202265
}
203-
Log("Application manifest registered;");
204-
}
205-
206-
private static void RmAppManifest()
207-
{
208-
EVRInitError evrInitError = EVRInitError.None;
209-
OpenVR.Init(ref evrInitError, EVRApplicationType.VRApplication_Utility);
210-
if (evrInitError != EVRInitError.None)
266+
else
211267
{
212-
LogError(evrInitError);
268+
applicationError = OpenVR.Applications.RemoveApplicationManifest(Directory.GetCurrentDirectory() + @"\manifest.vrmanifest");
213269
}
214270

215-
EVRApplicationError applicationError = OpenVR.Applications.RemoveApplicationManifest(Directory.GetCurrentDirectory() + @"\manifest.vrmanifest");
216-
if (applicationError != EVRApplicationError.None){
271+
if (applicationError != EVRApplicationError.None)
272+
{
217273
LogError(applicationError);
274+
return;
218275
}
219-
Log("Application manifest removed;");
220-
}
221-
222-
public static void SendActiveStatus(bool status)
223-
{
224-
SendOnLighthouseAsync((status)? activateByte : deactivateByte);
276+
Log($"Application manifest {((task == WithManifestTask.add)? "registered" : "removed")}");
225277
}
226278

227279
private static void Exit()
@@ -236,4 +288,10 @@ public enum LogType
236288
log,
237289
error
238290
}
291+
292+
public enum WithManifestTask
293+
{
294+
add,
295+
rm
296+
}
239297
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"source": "LighthouseV2PowerControl",
3+
"applications": [{
4+
"app_key": "LighthouseV2PowerControl",
5+
"launch_type": "binary",
6+
"binary_path_windows": "\\LighthouseV2PowerControl.exe",
7+
"is_dashboard_overlay": true,
8+
9+
"strings": {
10+
"en_us": {
11+
"name": "Lighthouse Power Control",
12+
"description": "PowerControl 4 LighthouseV2"
13+
}
14+
}
15+
}]
16+
}
-760 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)