diff --git a/Cargo.lock b/Cargo.lock index 7a3bcde..f70b781 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1405,6 +1405,7 @@ dependencies = [ "built", "clap", "console-subscriber", + "ctrlc", "futures", "futures-locks", "http-body-util", diff --git a/Cargo.toml b/Cargo.toml index 30952d5..0a60a87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ bevy_ecs = "0" bevy_log = "0" clap = { version = "4", features = ["derive", "string"] } console-subscriber = { version = "0", optional = true } +ctrlc = { version = "3", features = ["termination"] } futures = "0" futures-locks = "0" http-body-util = "0" diff --git a/src/events.rs b/src/events.rs index fb2427d..ac9f625 100644 --- a/src/events.rs +++ b/src/events.rs @@ -16,7 +16,7 @@ use hyper_util::rt::TokioIo; use log::{debug, error, info, trace}; use mlua::{Error, Function, IntoLuaMulti, Table}; use ncr::utils::trim_header; -use std::net::SocketAddr; +use std::{net::SocketAddr, process::exit}; use tokio::net::TcpListener; #[allow(clippy::too_many_lines)] @@ -177,26 +177,17 @@ pub async fn handle_event(client: Client, event: Event, state: State) -> Result< Event::Init => { debug!("received initialize event"); - let globals = state.lua.globals(); let ecs = client.ecs.clone(); - globals.set( - "finish_replay_recording", - state.lua.create_function_mut(move |_, (): ()| { - ecs.lock() - .remove_resource::() - .context("recording not active") - .map_err(Error::external)? - .finish() - .map_err(Error::external) - })?, - )?; - globals.set( - "client", - client::Client { - inner: Some(client), - }, - )?; - call_listeners(&state, "init", ()).await; + ctrlc::set_handler(move || { + debug!("finishing replay recording"); + ecs.lock() + .remove_resource::() + .map(Recorder::finish); + exit(0); + })?; + + let globals = state.lua.globals(); + lua_init(client, &state, &globals).await?; let Some(address): Option = globals .get::("HttpAddress") @@ -237,6 +228,29 @@ pub async fn handle_event(client: Client, event: Event, state: State) -> Result< Ok(()) } +async fn lua_init(client: Client, state: &State, globals: &Table) -> Result<()> { + let ecs = client.ecs.clone(); + globals.set( + "finish_replay_recording", + state.lua.create_function_mut(move |_, (): ()| { + ecs.lock() + .remove_resource::() + .context("recording not active") + .map_err(Error::external)? + .finish() + .map_err(Error::external) + })?, + )?; + globals.set( + "client", + client::Client { + inner: Some(client), + }, + )?; + call_listeners(state, "init", ()).await; + Ok(()) +} + async fn call_listeners( state: &State, event_type: &'static str,