aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorArne Dußin2021-02-04 14:15:20 +0100
committerArne Dußin2021-02-04 14:15:20 +0100
commitc0f8c067f6226981dc657a5a13fe0c0c5b0734d9 (patch)
treea3f5aa2eedb6fa3215e05d582a51855ee6563402 /src/server
parent5652a771352ca0c9c344cd8d28dab291e8c415dc (diff)
downloadgraf_karto-c0f8c067f6226981dc657a5a13fe0c0c5b0734d9.tar.gz
graf_karto-c0f8c067f6226981dc657a5a13fe0c0c5b0734d9.zip
Make the server started by the client shut down
Before, the server thread would just continue running, after the window had been closed. This is fixed now, with the server thread being controlled by an atomic bool.
Diffstat (limited to 'src/server')
-rw-r--r--src/server/mod.rs129
1 files changed, 69 insertions, 60 deletions
diff --git a/src/server/mod.rs b/src/server/mod.rs
index c9550f7..4f95378 100644
--- a/src/server/mod.rs
+++ b/src/server/mod.rs
@@ -5,6 +5,8 @@ use crate::net::Cargo;
use crate::world::World;
use std::io;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::Arc;
use std::thread::{self, JoinHandle};
/// The default port the dedicated graf karto server runs on.
@@ -25,85 +27,92 @@ pub fn start_with_port(port: u16, ipv4: bool) -> Result<JoinHandle<()>, io::Erro
let addr = unspecified(port, ipv4);
let conn_man = ConnectionManager::start(addr)?;
- Ok(start(conn_man))
+ Ok(start(conn_man).0)
}
/// Starts a thread on any free system port. Returns an error in case that's not
/// possible.
-pub fn start_any_port(ipv4: bool) -> Result<(JoinHandle<()>, u16), io::Error> {
+pub fn start_any_port(ipv4: bool) -> Result<(JoinHandle<()>, Arc<AtomicBool>, u16), io::Error> {
let addr = unspecified(0, ipv4);
let conn_man = ConnectionManager::start(addr)?;
let port = conn_man.port();
- Ok((start(conn_man), port))
+ let (handle, running) = start(conn_man);
+ Ok((handle, running, port))
}
-fn start(conn_man: ConnectionManager<Cargo>) -> JoinHandle<()> {
+fn start(conn_man: ConnectionManager<Cargo>) -> (JoinHandle<()>, Arc<AtomicBool>) {
info!("Server started on port {}", conn_man.port());
+ let running = Arc::new(AtomicBool::new(true));
+ let running_cl = running.clone();
let mut world = World::new();
- thread::spawn(move || loop {
- if let Some((user, cargo)) = conn_man.next_packet() {
- match cargo {
- Cargo::AddRoom(room) => {
- let room_id = world.push_room(room.clone());
- conn_man.broadcast(Cargo::SetRoom((room_id, room)));
- }
- Cargo::AddIcon(icon) => {
- let icon_id = world.push_icon(icon.clone());
- conn_man.broadcast(Cargo::SetIcon((icon_id, icon)));
- }
- Cargo::AddWall(wall) => {
- let wall_id = world.push_wall(wall.clone());
- conn_man.broadcast(Cargo::SetWall((wall_id, wall)));
- }
- Cargo::SetRoom((id, new)) => {
- if let Some(old) = world.get_room_mut(id) {
- *old = new;
- } else {
- error!(
- "Unable to change room. Room with id `{}` does not exist.",
- id
- );
+ let handle = thread::spawn(move || {
+ while running_cl.load(Ordering::Relaxed) {
+ if let Some((_user, cargo)) = conn_man.next_packet() {
+ match cargo {
+ Cargo::AddRoom(room) => {
+ let room_id = world.push_room(room.clone());
+ conn_man.broadcast(Cargo::SetRoom((room_id, room)));
}
- }
- Cargo::SetIcon((id, new)) => {
- if let Some(old) = world.get_icon_mut(id) {
- *old = new;
- } else {
- error!(
- "Unable to change icon. Icon with id `{}` does not exist.",
- id
- );
+ Cargo::AddIcon(icon) => {
+ let icon_id = world.push_icon(icon.clone());
+ conn_man.broadcast(Cargo::SetIcon((icon_id, icon)));
}
- }
- Cargo::SetWall((id, new)) => {
- if let Some(old) = world.get_wall_mut(id) {
- *old = new;
- } else {
- error!(
- "Unable to change wall. Wall with id `{}` does not exist.",
- id
- );
+ Cargo::AddWall(wall) => {
+ let wall_id = world.push_wall(wall.clone());
+ conn_man.broadcast(Cargo::SetWall((wall_id, wall)));
}
- }
- Cargo::ClearAll => {
- world.clear();
- conn_man.broadcast(Cargo::ClearAll);
- }
- Cargo::Remove(id) => {
- if world.remove(id) {
- conn_man.broadcast(Cargo::Remove(id));
- } else {
- error!("Unable to remove item. No item with id `{}` found.", id);
+ Cargo::SetRoom((id, new)) => {
+ if let Some(old) = world.get_room_mut(id) {
+ *old = new;
+ } else {
+ error!(
+ "Unable to change room. Room with id `{}` does not exist.",
+ id
+ );
+ }
+ }
+ Cargo::SetIcon((id, new)) => {
+ if let Some(old) = world.get_icon_mut(id) {
+ *old = new;
+ } else {
+ error!(
+ "Unable to change icon. Icon with id `{}` does not exist.",
+ id
+ );
+ }
+ }
+ Cargo::SetWall((id, new)) => {
+ if let Some(old) = world.get_wall_mut(id) {
+ *old = new;
+ } else {
+ error!(
+ "Unable to change wall. Wall with id `{}` does not exist.",
+ id
+ );
+ }
+ }
+ Cargo::ClearAll => {
+ world.clear();
+ conn_man.broadcast(Cargo::ClearAll);
+ }
+ Cargo::Remove(id) => {
+ if world.remove(id) {
+ conn_man.broadcast(Cargo::Remove(id));
+ } else {
+ error!("Unable to remove item. No item with id `{}` found.", id);
+ }
+ }
+ Cargo::ApplyMatrix((_id, _matrix)) => unimplemented!(),
+ Cargo::AddMapData(_) | Cargo::UpdateMapData(_) => {
+ error!("This packet is not allowed in the client -> server direction");
}
- }
- Cargo::ApplyMatrix((_id, _matrix)) => unimplemented!(),
- Cargo::AddMapData(_) | Cargo::UpdateMapData(_) => {
- error!("This packet is not allowed in the client -> server direction");
}
}
}
- })
+ });
+
+ (handle, running)
}