11using System ;
22using System . Collections . Generic ;
3- using System . Diagnostics ;
43using System . IO ;
54using System . Text . RegularExpressions ;
6- using System . Threading ;
75using System . Threading . Tasks ;
86using System . Windows . Forms ;
9- using Windows . ApplicationModel . Email . DataProvider ;
107using Windows . Devices . Bluetooth ;
118using Windows . Devices . Bluetooth . GenericAttributeProfile ;
129using Windows . Devices . Enumeration ;
13- using Windows . Media . Capture ;
1410using Windows . Storage . Streams ;
1511using Valve . VR ;
12+ using System . Threading ;
1613
1714namespace 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}
0 commit comments