diff --git a/Cargo.lock b/Cargo.lock index ea87229dc9..0c89dbfed2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -747,7 +747,7 @@ dependencies = [ "actix-web 4.0.0-beta.10", "actix-web-actors", "actix_helpers", - "clap 2.34.0", + "clap", "easyenv", "eframe", "egui", @@ -790,7 +790,7 @@ version = "0.0.1" dependencies = [ "anyhow", "chrono", - "clap 2.34.0", + "clap", "config", "container_common", "database_queries", @@ -1407,28 +1407,6 @@ dependencies = [ "vec_map", ] -[[package]] -name = "clap" -version = "4.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335867764ed2de42325fafe6d18b8af74ba97ee0c590fa016f157535b42ab04b" -dependencies = [ - "atty", - "bitflags", - "clap_lex", - "strsim 0.10.0", - "termcolor", -] - -[[package]] -name = "clap_lex" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] - [[package]] name = "clipboard-win" version = "4.5.0" @@ -1960,8 +1938,7 @@ version = "0.0.1" dependencies = [ "anyhow", "chrono", - "clap 2.34.0", - "clap 4.0.18", + "clap", "config", "container_common", "dotenv", @@ -1979,7 +1956,6 @@ version = "0.0.1" dependencies = [ "anyhow", "chrono", - "clap 4.0.18", "config", "container_common", "dotenv", @@ -2201,7 +2177,7 @@ version = "0.0.1" dependencies = [ "anyhow", "chrono", - "clap 2.34.0", + "clap", "cloud_storage", "config", "container_common", @@ -3474,7 +3450,7 @@ version = "0.0.1" dependencies = [ "anyhow", "chrono", - "clap 2.34.0", + "clap", "cloud_storage", "config", "container_common", @@ -4532,12 +4508,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "os_str_bytes" -version = "6.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9" - [[package]] name = "osmesa-sys" version = "0.1.2" @@ -6869,7 +6839,7 @@ version = "0.0.1" dependencies = [ "anyhow", "chrono", - "clap 2.34.0", + "clap", "cloud_storage", "config", "container_common", @@ -6900,7 +6870,7 @@ version = "0.0.1" dependencies = [ "anyhow", "chrono", - "clap 2.34.0", + "clap", "cloud_storage", "config", "container_common", @@ -7319,7 +7289,7 @@ dependencies = [ "anyhow", "buckets", "chrono", - "clap 2.34.0", + "clap", "cloud_storage", "config", "container_common", @@ -7350,7 +7320,7 @@ version = "0.0.1" dependencies = [ "anyhow", "chrono", - "clap 2.34.0", + "clap", "cloud_storage", "config", "container_common", diff --git a/crates/programs/aichatbot-sidecar/src/gui/gui.rs b/crates/programs/aichatbot-sidecar/src/gui/gui.rs index 6639d0142f..91e2755a01 100644 --- a/crates/programs/aichatbot-sidecar/src/gui/gui.rs +++ b/crates/programs/aichatbot-sidecar/src/gui/gui.rs @@ -1,22 +1,35 @@ +use std::sync::Arc; use eframe::egui; -use log::info; +use log::{error, info}; +use crate::shared_state::control_state::ControlState; pub struct AppGui { + // NB: This is not the authoritative set of state. + // These will be copied into the shared server state. filename: String, default_directory: String, + is_paused: bool, + + control_state: Arc, } -impl Default for AppGui { - fn default() -> Self { +impl AppGui { + pub fn new(control_state: Arc) -> Self { Self { filename: "".to_string(), default_directory: "".to_string(), + is_paused: false, + control_state, } } } impl eframe::App for AppGui { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + if let Err(e) = self.control_state.set_is_paused(self.is_paused) { + error!("Couldn't set paused state: {:?}", e); + } + egui::CentralPanel::default().show(ctx, |ui| { ui.heading("AiChatBot Sidecar"); ui.horizontal(|ui| { @@ -29,6 +42,11 @@ impl eframe::App for AppGui { ui.text_edit_singleline(&mut self.default_directory) .labelled_by(name_label.id); }); + ui.horizontal(|ui| { + let name_label = ui.label("Is Paused?: "); + ui.checkbox(&mut self.is_paused, "Is Paused?") + .labelled_by(name_label.id); + }); }); } } diff --git a/crates/programs/aichatbot-sidecar/src/gui/launch_gui.rs b/crates/programs/aichatbot-sidecar/src/gui/launch_gui.rs index 45a20767ed..f6f33b05f1 100644 --- a/crates/programs/aichatbot-sidecar/src/gui/launch_gui.rs +++ b/crates/programs/aichatbot-sidecar/src/gui/launch_gui.rs @@ -1,8 +1,10 @@ +use std::sync::Arc; use crate::gui::gui::AppGui; use eframe::egui; use errors::AnyhowResult; +use crate::shared_state::control_state::ControlState; -pub fn launch_gui() -> AnyhowResult<()> { +pub fn launch_gui(control_state: Arc) -> AnyhowResult<()> { // Log to stdout (if you run with `RUST_LOG=debug`). //tracing_subscriber::fmt::init(); @@ -11,10 +13,12 @@ pub fn launch_gui() -> AnyhowResult<()> { ..Default::default() }; + let app_state = AppGui::new(control_state); + let result = eframe::run_native( "AiChatBot Sidecar", options, - Box::new(|_cc| Box::new(AppGui::default())), + Box::new(|_cc| Box::new(app_state)), ); Ok(()) diff --git a/crates/programs/aichatbot-sidecar/src/main.rs b/crates/programs/aichatbot-sidecar/src/main.rs index c1c0ac6f1b..564f0e489c 100644 --- a/crates/programs/aichatbot-sidecar/src/main.rs +++ b/crates/programs/aichatbot-sidecar/src/main.rs @@ -5,24 +5,24 @@ pub mod gui; pub mod jobs; pub mod main_loop; -pub mod state; +pub mod shared_state; pub mod web_server; #[macro_use] extern crate serde_derive; +use actix_web::{HttpResponse, HttpServer, web}; +use clap::{App, Arg}; +use crate::gui::launch_gui::launch_gui; +use crate::main_loop::main_loop; +use crate::shared_state::control_state::ControlState; +use crate::web_server::launch_web_server::launch_web_server; +use errors::AnyhowResult; +use log::info; +use std::sync::Arc; use std::thread; use std::time::Duration; use tokio::runtime::Runtime; -//use actix_rt::Runtime; -use actix_web::{HttpResponse, HttpServer, web}; -use clap::{App, Arg}; -use crate::main_loop::main_loop; -use errors::AnyhowResult; -use log::info; -use crate::gui::launch_gui::launch_gui; -use crate::web_server::launch_web_server::launch_web_server; -//#[tokio::main] #[actix_web::main] pub async fn main() -> AnyhowResult<()> { easyenv::init_all_with_default_logging(Some("info")); @@ -42,31 +42,28 @@ pub async fn main() -> AnyhowResult<()> { // .takes_value(true)) // .get_matches(); - - info!("Get runtime..."); + let control_state = Arc::new(ControlState::new()); let tokio_runtime = Runtime::new()?; - - //info!("Starting main loop..."); + info!("Starting async processes..."); tokio_runtime.spawn(async { - info!("STARTING MAIN LOOP..."); let _r = main_loop().await; }); - //tokio_runtime.spawn(async { - // info!("LAUNCHING GUI..."); - //}); - info!("Starting web server..."); + let control_state2 = control_state.clone(); + thread::spawn(move || { - let server_future = launch_web_server(); + let server_future = launch_web_server(control_state2); actix_web::rt::System::new().block_on(server_future) }); - let _r = launch_gui(); + info!("Starting GUI ..."); + + let _r = launch_gui(control_state.clone()); Ok(()) } diff --git a/crates/programs/aichatbot-sidecar/src/shared_state/control_state.rs b/crates/programs/aichatbot-sidecar/src/shared_state/control_state.rs new file mode 100644 index 0000000000..b18c3279af --- /dev/null +++ b/crates/programs/aichatbot-sidecar/src/shared_state/control_state.rs @@ -0,0 +1,34 @@ +use std::sync::{Arc, LockResult, RwLock}; +use errors::{anyhow, AnyhowResult}; + +pub struct ControlState { + /// Whether the playback should be paused + /// Unreal Engine will get this over HTTP and know whether to no-op. + is_paused: Arc>, +} + +impl ControlState { + + pub fn new() -> Self { + ControlState { + is_paused: Arc::new(RwLock::new(false)), + } + } + + pub fn is_paused(&self) -> AnyhowResult { + match self.is_paused.read() { + Ok(value) => Ok(*value), + Err(err) => Err(anyhow!("lock error: {:?}", err)), + } + } + + pub fn set_is_paused(&self, new_value: bool) -> AnyhowResult<()> { + match self.is_paused.write() { + Ok(mut value) => { + *value = new_value; + Ok(()) + }, + Err(err) => Err(anyhow!("lock error: {:?}", err)), + } + } +} diff --git a/crates/programs/aichatbot-sidecar/src/state/job_state.rs b/crates/programs/aichatbot-sidecar/src/shared_state/job_state.rs similarity index 100% rename from crates/programs/aichatbot-sidecar/src/state/job_state.rs rename to crates/programs/aichatbot-sidecar/src/shared_state/job_state.rs diff --git a/crates/programs/aichatbot-sidecar/src/shared_state/mod.rs b/crates/programs/aichatbot-sidecar/src/shared_state/mod.rs new file mode 100644 index 0000000000..3b54ff9e8d --- /dev/null +++ b/crates/programs/aichatbot-sidecar/src/shared_state/mod.rs @@ -0,0 +1,2 @@ +pub mod control_state; +pub mod job_state; \ No newline at end of file diff --git a/crates/programs/aichatbot-sidecar/src/state/mod.rs b/crates/programs/aichatbot-sidecar/src/state/mod.rs deleted file mode 100644 index 6c29638ff2..0000000000 --- a/crates/programs/aichatbot-sidecar/src/state/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod server_state; -pub mod job_state; \ No newline at end of file diff --git a/crates/programs/aichatbot-sidecar/src/state/server_state.rs b/crates/programs/aichatbot-sidecar/src/state/server_state.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/crates/programs/aichatbot-sidecar/src/web_server/handlers/get_next_audio_file_handler.rs b/crates/programs/aichatbot-sidecar/src/web_server/handlers/get_next_audio_file_handler.rs index 4793ea66c6..e99ea8375e 100644 --- a/crates/programs/aichatbot-sidecar/src/web_server/handlers/get_next_audio_file_handler.rs +++ b/crates/programs/aichatbot-sidecar/src/web_server/handlers/get_next_audio_file_handler.rs @@ -1,6 +1,9 @@ +use std::sync::Arc; use actix_http::StatusCode; use actix_web::{HttpRequest, HttpResponse, ResponseError, web}; +use log::error; use http_server_common::response::serialize_as_json_error::serialize_as_json_error; +use crate::shared_state::control_state::ControlState; #[derive(Serialize)] pub struct GetNextAudioFileResponse { @@ -34,12 +37,18 @@ impl std::fmt::Display for GetNextAudioFileError { pub async fn get_next_audio_file_handler( _http_request: HttpRequest, - //_server_state: web::Data> + control_state: web::Data> ) -> Result { + let is_paused = control_state.is_paused() + .map_err(|err| { + error!("Error: {:?}", err); + GetNextAudioFileError::ServerError + })?; + let response = GetNextAudioFileResponse { success: true, - is_paused: false, + is_paused, }; let body = serde_json::to_string(&response) diff --git a/crates/programs/aichatbot-sidecar/src/web_server/launch_web_server.rs b/crates/programs/aichatbot-sidecar/src/web_server/launch_web_server.rs index 8cf022d719..f346dd4754 100644 --- a/crates/programs/aichatbot-sidecar/src/web_server/launch_web_server.rs +++ b/crates/programs/aichatbot-sidecar/src/web_server/launch_web_server.rs @@ -1,13 +1,22 @@ +use std::sync::Arc; use actix_helpers::route_builder::RouteBuilder; use actix_web::{App, HttpResponse, HttpServer, web}; use crate::web_server::handlers::get_next_audio_file_handler::get_next_audio_file_handler; use errors::AnyhowResult; use http_server_common::endpoints::root_index::get_root_index; +use crate::shared_state::control_state::ControlState; +use crate::web_server::server_state::ServerState; + +pub async fn launch_web_server(control_state: Arc) -> AnyhowResult<()> { + + let server_state = Arc::new(ServerState { + control_state: control_state.clone(), + }); -pub async fn launch_web_server() -> AnyhowResult<()> { HttpServer::new(move || { - let app = App::new(); - //.app_data(web::Data::new(server_state_arc.firehose_publisher.clone())) + let app = App::new() + .app_data(web::Data::new(control_state.clone())) + .app_data(web::Data::new(server_state.clone())); let mut route_builder = RouteBuilder::from_app(app); diff --git a/crates/programs/aichatbot-sidecar/src/web_server/mod.rs b/crates/programs/aichatbot-sidecar/src/web_server/mod.rs index 3abd1a2bc8..42d5a7d424 100644 --- a/crates/programs/aichatbot-sidecar/src/web_server/mod.rs +++ b/crates/programs/aichatbot-sidecar/src/web_server/mod.rs @@ -1,2 +1,3 @@ pub mod handlers; -pub mod launch_web_server; \ No newline at end of file +pub mod launch_web_server; +pub mod server_state; \ No newline at end of file diff --git a/crates/programs/aichatbot-sidecar/src/web_server/server_state.rs b/crates/programs/aichatbot-sidecar/src/web_server/server_state.rs new file mode 100644 index 0000000000..c5b30544ef --- /dev/null +++ b/crates/programs/aichatbot-sidecar/src/web_server/server_state.rs @@ -0,0 +1,7 @@ +use std::sync::Arc; +use crate::shared_state::control_state::ControlState; + +#[derive(Clone)] +pub struct ServerState { + pub control_state: Arc, +}