diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index e4e0605839..7b6e2ee78b 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -381,18 +381,16 @@ impl Show { self.want_grab = true; // Unpause the game if we are on singleplayer - if let Some(ref singleplayer) = global_state.singleplayer { + if let Some(singleplayer) = global_state.singleplayer.as_ref() { singleplayer.pause(false); - global_state.paused = false; }; } else { self.esc_menu = true; self.want_grab = false; // Pause the game if we are on singleplayer - if let Some(ref singleplayer) = global_state.singleplayer { + if let Some(singleplayer) = global_state.singleplayer.as_ref() { singleplayer.pause(true); - global_state.paused = true; }; } } @@ -1929,6 +1927,11 @@ impl Hud { self.show.esc_menu = false; self.show.want_grab = false; self.force_ungrab = true; + + // Unpause the game if we are on singleplayer + if let Some(singleplayer) = global_state.singleplayer.as_ref() { + singleplayer.pause(false); + }; }, Some(esc_menu::Event::Logout) => { events.push(Event::Logout); diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index 8379044eea..6cb1ec4e62 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -47,7 +47,6 @@ pub struct GlobalState { audio: AudioFrontend, info_message: Option, singleplayer: Option, - paused: bool, } impl GlobalState { @@ -139,7 +138,6 @@ fn main() { meta, info_message: None, singleplayer: None, - paused: false, }; // Try to load the localization and log missing entries diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index cd79db199d..7670eb1b1e 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -379,7 +379,10 @@ impl PlayState for SessionState { self.inputs.look_dir = cam_dir; - if !global_state.paused { + // Runs if either in a multiplayer server or the singleplayer server is unpaused + if global_state.singleplayer.is_none() + || !global_state.singleplayer.as_ref().unwrap().is_paused() + { // Perform an in-game tick. if let Err(err) = self.tick(clock.get_avg_delta()) { global_state.info_message = @@ -611,7 +614,10 @@ impl PlayState for SessionState { } } - if !global_state.paused { + // Runs if either in a multiplayer server or the singleplayer server is unpaused + if global_state.singleplayer.is_none() + || !global_state.singleplayer.as_ref().unwrap().is_paused() + { // Maintain the scene. self.scene.maintain( global_state.window.renderer_mut(), diff --git a/voxygen/src/singleplayer.rs b/voxygen/src/singleplayer.rs index c03e79457d..d2538c6bf6 100644 --- a/voxygen/src/singleplayer.rs +++ b/voxygen/src/singleplayer.rs @@ -4,6 +4,7 @@ use crossbeam::channel::{unbounded, Receiver, Sender, TryRecvError}; use log::info; use server::{Event, Input, Server, ServerSettings}; use std::{ + sync::atomic::{AtomicBool, Ordering}, thread::{self, JoinHandle}, time::Duration, }; @@ -20,6 +21,8 @@ enum Msg { pub struct Singleplayer { _server_thread: JoinHandle<()>, sender: Sender, + // Wether the server is stopped or not + paused: AtomicBool, } impl Singleplayer { @@ -47,12 +50,21 @@ impl Singleplayer { Singleplayer { _server_thread: thread, sender, + paused: AtomicBool::new(false), }, settings, ) } - pub fn pause(&self, paused: bool) { let _ = self.sender.send(Msg::Pause(paused)); } + /// Returns wether or not the server is paused + pub fn is_paused(&self) -> bool { self.paused.load(Ordering::Relaxed) } + + /// Pauses if true is passed and unpauses if false (Does nothing if in that + /// state already) + pub fn pause(&self, state: bool) { + self.paused.load(Ordering::SeqCst); + let _ = self.sender.send(Msg::Pause(state)); + } } impl Drop for Singleplayer { @@ -70,6 +82,7 @@ fn run_server(mut server: Server, rec: Receiver) { let mut paused = false; loop { + // Check any event such as stopping and pausing match rec.try_recv() { Ok(msg) => match msg { Msg::Stop => break, @@ -81,9 +94,11 @@ fn run_server(mut server: Server, rec: Receiver) { }, } + // Wait for the next tick. + clock.tick(Duration::from_millis(1000 / TPS)); + + // Skip updating the server if it's paused if paused { - // Wait for the next tick. - clock.tick(Duration::from_millis(1000 / TPS)); continue; } @@ -101,8 +116,5 @@ fn run_server(mut server: Server, rec: Receiver) { // Clean up the server after a tick. server.cleanup(); - - // Wait for the next tick. - clock.tick(Duration::from_millis(1000 / TPS)); } }