Add method to drop singleplayer thread

Former-commit-id: b62a90728d4e83a005687538e134cee427491052
This commit is contained in:
Louis Pearson 2019-04-17 08:57:23 -06:00
parent 7ec6e09332
commit 76adbec3bb
3 changed files with 52 additions and 6 deletions

View File

@ -13,12 +13,14 @@ pub mod session;
pub mod ui; pub mod ui;
pub mod window; pub mod window;
pub mod settings; pub mod settings;
pub mod singleplayer;
// Reexports // Reexports
pub use crate::error::Error; pub use crate::error::Error;
// Standard // Standard
use std::mem; use std::mem;
use std::thread;
// Library // Library
use log; use log;
@ -28,13 +30,15 @@ use pretty_env_logger;
use crate::{ use crate::{
menu::main::MainMenuState, menu::main::MainMenuState,
window::Window, window::Window,
settings::Settings settings::Settings,
singleplayer::Singleplayer,
}; };
/// A type used to store state that is shared between all play states /// A type used to store state that is shared between all play states
pub struct GlobalState { pub struct GlobalState {
settings: Settings, settings: Settings,
window: Window, window: Window,
singleplayer: Option<Singleplayer>,
} }
impl GlobalState { impl GlobalState {
@ -88,6 +92,7 @@ fn main() {
let mut global_state = GlobalState { let mut global_state = GlobalState {
settings, settings,
window, window,
singleplayer: None,
}; };
// Set up the initial play state // Set up the initial play state

View File

@ -1,11 +1,11 @@
mod client_init; mod client_init;
mod ui; mod ui;
mod singleplayer;
use super::char_selection::CharSelectionState; use super::char_selection::CharSelectionState;
use crate::{ use crate::{
window::{Event, Window}, window::{Event, Window},
GlobalState, PlayState, PlayStateResult, GlobalState, PlayState, PlayStateResult,
singleplayer::Singleplayer,
}; };
use client_init::{ClientInit, Error as InitError}; use client_init::{ClientInit, Error as InitError};
use common::{clock::Clock, comp}; use common::{clock::Clock, comp};
@ -103,9 +103,7 @@ impl PlayState for MainMenuState {
))); )));
} }
MainMenuEvent::StartSingleplayer => { MainMenuEvent::StartSingleplayer => {
thread::spawn(move || { global_state.singleplayer = Some(Singleplayer::new());
singleplayer::run_server();
});
} }
MainMenuEvent::Quit => return PlayStateResult::Shutdown, MainMenuEvent::Quit => return PlayStateResult::Shutdown,
} }

View File

@ -2,10 +2,45 @@ use std::time::Duration;
use log::info; use log::info;
use server::{Input, Event, Server}; use server::{Input, Event, Server};
use common::clock::Clock; use common::clock::Clock;
use std::{
thread,
thread::JoinHandle
};
use std::sync::mpsc::{
channel, Receiver, Sender
};
const TPS: u64 = 30; const TPS: u64 = 30;
pub fn run_server() { enum Msg {
Stop,
}
pub struct Singleplayer {
server_thread: JoinHandle<()>,
sender: Sender<Msg>,
}
impl Singleplayer {
pub fn new() -> Self {
let (sender, reciever) = channel();
let thread = thread::spawn(move || {
run_server(reciever);
});
Singleplayer {
server_thread: thread,
sender,
}
}
}
impl Drop for Singleplayer {
fn drop(&mut self) {
self.sender.send(Msg::Stop);
}
}
fn run_server(rec: Receiver<Msg>) {
info!("Starting server-cli..."); info!("Starting server-cli...");
// Set up an fps clock // Set up an fps clock
@ -30,6 +65,14 @@ pub fn run_server() {
// Clean up the server after a tick // Clean up the server after a tick
server.cleanup(); server.cleanup();
match rec.try_recv() {
Ok(msg) => break,
Err(err) => match err {
Empty => (),
Disconnected => break,
},
}
// Wait for the next tick // Wait for the next tick
clock.tick(Duration::from_millis(1000 / TPS)); clock.tick(Duration::from_millis(1000 / TPS));
} }