From 2933818eec77c77b2add1f4e8f23b890ce49bac2 Mon Sep 17 00:00:00 2001 From: Riccardo Zaglia Date: Mon, 3 Apr 2023 15:41:58 +0200 Subject: [PATCH] Add option for opening/closing SteamVR with dashboard --- .../src/dashboard/components/connections.rs | 7 ++--- alvr/dashboard/src/dashboard/mod.rs | 2 +- alvr/dashboard/src/main.rs | 30 +++++++++++++++++-- alvr/dashboard/src/steamvr_launcher.rs | 5 +++- alvr/server/src/lib.rs | 11 +++++++ alvr/server/src/web_server.rs | 11 +++---- alvr/session/src/settings.rs | 6 +++- alvr/sockets/src/packets.rs | 5 ++-- 8 files changed, 59 insertions(+), 18 deletions(-) diff --git a/alvr/dashboard/src/dashboard/components/connections.rs b/alvr/dashboard/src/dashboard/components/connections.rs index e13a5da2bb..2c1d67bfde 100644 --- a/alvr/dashboard/src/dashboard/components/connections.rs +++ b/alvr/dashboard/src/dashboard/components/connections.rs @@ -10,10 +10,7 @@ use eframe::{ emath::{Align, Align2}, epaint::Color32, }; -use std::{ - net::{IpAddr, Ipv4Addr}, - thread, -}; +use std::net::{IpAddr, Ipv4Addr}; struct EditPopupState { new_client: bool, @@ -56,7 +53,7 @@ impl ConnectionsTab { }); ui.with_layout(Layout::right_to_left(eframe::emath::Align::Center), |ui| { if ui.button("Launch SteamVR").clicked() { - thread::spawn(|| LAUNCHER.lock().launch_steamvr()); + LAUNCHER.lock().launch_steamvr(); } }); }); diff --git a/alvr/dashboard/src/dashboard/mod.rs b/alvr/dashboard/src/dashboard/mod.rs index 5f287143ab..0eb1ba408c 100644 --- a/alvr/dashboard/src/dashboard/mod.rs +++ b/alvr/dashboard/src/dashboard/mod.rs @@ -252,7 +252,7 @@ impl eframe::App for Dashboard { requests.push(DashboardRequest::RestartSteamvr); } } else if ui.button("Launch SteamVR").clicked() { - thread::spawn(|| LAUNCHER.lock().launch_steamvr()); + LAUNCHER.lock().launch_steamvr(); } ui.horizontal(|ui| { diff --git a/alvr/dashboard/src/main.rs b/alvr/dashboard/src/main.rs index 8570328b52..3291c5ea29 100644 --- a/alvr/dashboard/src/main.rs +++ b/alvr/dashboard/src/main.rs @@ -8,7 +8,7 @@ mod steamvr_launcher; mod theme; use alvr_common::{parking_lot::Mutex, ALVR_VERSION}; -use alvr_sockets::GpuVendor; +use alvr_sockets::{DashboardRequest, GpuVendor}; use dashboard::Dashboard; use data_sources::ServerEvent; use eframe::{egui, IconData, NativeOptions}; @@ -18,10 +18,12 @@ use std::{ sync::{mpsc, Arc}, thread, }; +use steamvr_launcher::LAUNCHER; fn main() { let (server_events_sender, server_events_receiver) = mpsc::channel(); logging_backend::init_logging(server_events_sender.clone()); + let (dashboard_requests_sender, dashboard_requests_receiver) = mpsc::channel(); { let mut data_manager = data_sources::get_local_data_source(); @@ -43,6 +45,14 @@ fn main() { session_ref.server_version = ALVR_VERSION.clone(); session_ref.client_connections.clear(); } + + if data_manager + .settings() + .extra + .open_and_close_steamvr_with_dashboard + { + LAUNCHER.lock().launch_steamvr() + } } let ico = IconDir::read(Cursor::new(include_bytes!("../resources/dashboard.ico"))).unwrap(); @@ -64,9 +74,8 @@ fn main() { }, { let data_thread = Arc::clone(&data_thread); + let dashboard_requests_sender = dashboard_requests_sender.clone(); Box::new(move |creation_context| { - let (dashboard_requests_sender, dashboard_requests_receiver) = mpsc::channel(); - let context = creation_context.egui_ctx.clone(); *data_thread.lock() = Some(thread::spawn(|| { data_sources::data_interop_thread( @@ -86,5 +95,20 @@ fn main() { ) .unwrap(); + if data_sources::get_local_data_source() + .settings() + .extra + .open_and_close_steamvr_with_dashboard + { + dashboard_requests_sender + .send(DashboardRequest::ShutdownSteamvr) + .ok(); + + LAUNCHER.lock().ensure_steamvr_shutdown() + } + + // This is the signal to shutdown the data thread. + drop(dashboard_requests_sender); + data_thread.lock().take().unwrap().join().unwrap(); } diff --git a/alvr/dashboard/src/steamvr_launcher.rs b/alvr/dashboard/src/steamvr_launcher.rs index e8af1bc185..64f088af65 100644 --- a/alvr/dashboard/src/steamvr_launcher.rs +++ b/alvr/dashboard/src/steamvr_launcher.rs @@ -163,7 +163,7 @@ impl Launcher { } } - pub fn restart_steamvr(&self) { + pub fn ensure_steamvr_shutdown(&self) { debug!("Waiting for SteamVR to shutdown..."); let start_time = Instant::now(); while start_time.elapsed() < SHUTDOWN_TIMEOUT && is_steamvr_running() { @@ -171,7 +171,10 @@ impl Launcher { } maybe_kill_steamvr(); + } + pub fn restart_steamvr(&self) { + self.ensure_steamvr_shutdown(); self.launch_steamvr(); } diff --git a/alvr/server/src/lib.rs b/alvr/server/src/lib.rs index 4eab49dcf1..259e339ebd 100644 --- a/alvr/server/src/lib.rs +++ b/alvr/server/src/lib.rs @@ -89,6 +89,7 @@ static VIDEO_RECORDING_FILE: Lazy>> = Lazy::new(|| Mutex::new static DISCONNECT_CLIENT_NOTIFIER: Lazy = Lazy::new(Notify::new); static RESTART_NOTIFIER: Lazy = Lazy::new(Notify::new); +static SHUTDOWN_NOTIFIER: Lazy = Lazy::new(Notify::new); static FRAME_RENDER_VS_CSO: &[u8] = include_bytes!("../cpp/platform/win32/FrameRenderVS.cso"); static FRAME_RENDER_PS_CSO: &[u8] = include_bytes!("../cpp/platform/win32/FrameRenderPS.cso"); @@ -166,6 +167,16 @@ pub fn shutdown_tasks() { WEBSERVER_RUNTIME.lock().take(); } +pub fn notify_shutdown_driver() { + thread::spawn(|| { + SHUTDOWN_NOTIFIER.notify_waiters(); + + shutdown_tasks(); + + unsafe { ShutdownSteamvr() }; + }); +} + pub fn notify_restart_driver() { alvr_events::send_event(EventType::ServerRequestsSelfRestart); diff --git a/alvr/server/src/web_server.rs b/alvr/server/src/web_server.rs index 729f3a6b10..21148769e8 100644 --- a/alvr/server/src/web_server.rs +++ b/alvr/server/src/web_server.rs @@ -109,6 +109,10 @@ async fn http_api( if let Ok(request) = from_request_body::(request).await { match request { DashboardRequest::Ping => (), + DashboardRequest::Log(event) => { + let level = event.severity.into_log_level(); + log::log!(level, "{}", event.content); + } DashboardRequest::GetSession => { alvr_events::send_event(alvr_events::EventType::Session(Box::new( SERVER_DATA_MANAGER.read().session().clone(), @@ -128,15 +132,12 @@ async fn http_api( return reply_json(&ServerResponse::AudioDevices(list)); } } - DashboardRequest::RestartSteamvr => crate::notify_restart_driver(), - DashboardRequest::Log(event) => { - let level = event.severity.into_log_level(); - log::log!(level, "{}", event.content); - } DashboardRequest::CaptureFrame => unsafe { crate::CaptureFrame() }, DashboardRequest::InsertIdr => unsafe { crate::RequestIDR() }, DashboardRequest::StartRecording => crate::create_recording_file(), DashboardRequest::StopRecording => *VIDEO_RECORDING_FILE.lock() = None, + DashboardRequest::RestartSteamvr => crate::notify_restart_driver(), + DashboardRequest::ShutdownSteamvr => crate::notify_shutdown_driver(), } reply(StatusCode::OK)? diff --git a/alvr/session/src/settings.rs b/alvr/session/src/settings.rs index 0ae1bed42a..c6e430309f 100644 --- a/alvr/session/src/settings.rs +++ b/alvr/session/src/settings.rs @@ -741,10 +741,13 @@ pub struct ExtraDesc { help = r#"This controls the driver registration operations while launching SteamVR. Unregister other drivers at startup: This is the recommended option and will handle most interferences from other installed drivers. Unregister ALVR at shutdown: This should be used when you want to load other drivers like for full body tracking. Other VR streaming drivers like Virtual Desktop must be manually unregistered or uninstalled. -No action: All driver registration actions should be performed mnually, ALVR included. This allows to launch SteamVR without launching the dashboard first."# +No action: All driver registration actions should be performed manually, ALVR included. This allows to launch SteamVR without launching the dashboard first."# ))] pub driver_launch_action: DriverLaunchAction, + #[schema(strings(display_name = "Open and close SteamVR with dashboard"))] + pub open_close_steamvr_with_dashboard: bool, + pub notification_level: LogSeverity, pub show_raw_events: bool, @@ -1069,6 +1072,7 @@ pub fn session_settings_default() -> SettingsDefault { driver_launch_action: DriverLaunchActionDefault { variant: DriverLaunchActionDefaultVariant::UnregisterOtherDriversAtStartup, }, + open_close_steamvr_with_dashboard: false, notification_level: LogSeverityDefault { variant: if cfg!(debug_assertions) { LogSeverityDefaultVariant::Info diff --git a/alvr/sockets/src/packets.rs b/alvr/sockets/src/packets.rs index d8fb18f07d..037a65e5c2 100644 --- a/alvr/sockets/src/packets.rs +++ b/alvr/sockets/src/packets.rs @@ -195,6 +195,7 @@ pub struct PathValuePair { #[derive(Serialize, Deserialize, Debug)] pub enum DashboardRequest { Ping, + Log(LogEvent), GetSession, UpdateSession(Box), SetValues(Vec), @@ -203,12 +204,12 @@ pub enum DashboardRequest { action: ClientListAction, }, GetAudioDevices, - RestartSteamvr, CaptureFrame, InsertIdr, StartRecording, StopRecording, - Log(LogEvent), + RestartSteamvr, + ShutdownSteamvr, } #[derive(Serialize, Deserialize, Debug)]