Moved paused from GlobalState to SinglePlayer to prevent errors and unpauses now works using the resume button

This commit is contained in:
Capucho 2020-03-03 19:51:15 +00:00
parent a97b694dfe
commit af21d19ff3
4 changed files with 33 additions and 14 deletions

View File

@ -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);

View File

@ -47,7 +47,6 @@ pub struct GlobalState {
audio: AudioFrontend,
info_message: Option<String>,
singleplayer: Option<Singleplayer>,
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

View File

@ -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(),

View File

@ -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<Msg>,
// 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<Msg>) {
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<Msg>) {
},
}
// 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<Msg>) {
// Clean up the server after a tick.
server.cleanup();
// Wait for the next tick.
clock.tick(Duration::from_millis(1000 / TPS));
}
}