From 76adbec3bbce74fbf9e40ffd69fff4250dcf853e Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Wed, 17 Apr 2019 08:57:23 -0600 Subject: [PATCH] Add method to drop singleplayer thread Former-commit-id: b62a90728d4e83a005687538e134cee427491052 --- voxygen/src/main.rs | 7 +++- voxygen/src/menu/main/mod.rs | 6 +-- voxygen/src/{menu/main => }/singleplayer.rs | 45 ++++++++++++++++++++- 3 files changed, 52 insertions(+), 6 deletions(-) rename voxygen/src/{menu/main => }/singleplayer.rs (53%) diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index b31bef5e61..ccb2ea0804 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -13,12 +13,14 @@ pub mod session; pub mod ui; pub mod window; pub mod settings; +pub mod singleplayer; // Reexports pub use crate::error::Error; // Standard use std::mem; +use std::thread; // Library use log; @@ -28,13 +30,15 @@ use pretty_env_logger; use crate::{ menu::main::MainMenuState, window::Window, - settings::Settings + settings::Settings, + singleplayer::Singleplayer, }; /// A type used to store state that is shared between all play states pub struct GlobalState { settings: Settings, window: Window, + singleplayer: Option, } impl GlobalState { @@ -88,6 +92,7 @@ fn main() { let mut global_state = GlobalState { settings, window, + singleplayer: None, }; // Set up the initial play state diff --git a/voxygen/src/menu/main/mod.rs b/voxygen/src/menu/main/mod.rs index a427890201..05412179d2 100644 --- a/voxygen/src/menu/main/mod.rs +++ b/voxygen/src/menu/main/mod.rs @@ -1,11 +1,11 @@ mod client_init; mod ui; -mod singleplayer; use super::char_selection::CharSelectionState; use crate::{ window::{Event, Window}, GlobalState, PlayState, PlayStateResult, + singleplayer::Singleplayer, }; use client_init::{ClientInit, Error as InitError}; use common::{clock::Clock, comp}; @@ -103,9 +103,7 @@ impl PlayState for MainMenuState { ))); } MainMenuEvent::StartSingleplayer => { - thread::spawn(move || { - singleplayer::run_server(); - }); + global_state.singleplayer = Some(Singleplayer::new()); } MainMenuEvent::Quit => return PlayStateResult::Shutdown, } diff --git a/voxygen/src/menu/main/singleplayer.rs b/voxygen/src/singleplayer.rs similarity index 53% rename from voxygen/src/menu/main/singleplayer.rs rename to voxygen/src/singleplayer.rs index 93f07030ec..11cfa45da2 100644 --- a/voxygen/src/menu/main/singleplayer.rs +++ b/voxygen/src/singleplayer.rs @@ -2,10 +2,45 @@ use std::time::Duration; use log::info; use server::{Input, Event, Server}; use common::clock::Clock; +use std::{ + thread, + thread::JoinHandle +}; +use std::sync::mpsc::{ + channel, Receiver, Sender +}; const TPS: u64 = 30; -pub fn run_server() { +enum Msg { + Stop, +} + +pub struct Singleplayer { + server_thread: JoinHandle<()>, + sender: Sender, +} + +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) { info!("Starting server-cli..."); // Set up an fps clock @@ -30,6 +65,14 @@ pub fn run_server() { // Clean up the server after a tick server.cleanup(); + match rec.try_recv() { + Ok(msg) => break, + Err(err) => match err { + Empty => (), + Disconnected => break, + }, + } + // Wait for the next tick clock.tick(Duration::from_millis(1000 / TPS)); }