Added server-side chunk generation

Former-commit-id: 72e02f8ec711ec4fac3111b591c4b08086dee4e3
This commit is contained in:
Joshua Barretto 2019-04-11 00:41:37 +01:00
parent 3d9f8105e6
commit f27b5fa975
4 changed files with 35 additions and 4 deletions

View File

@ -1,3 +1,4 @@
use vek::*;
use crate::comp;
#[derive(Clone, Serialize, Deserialize)]
@ -14,5 +15,8 @@ pub enum ClientMsg {
vel: comp::phys::Vel,
dir: comp::phys::Dir,
},
TerrainChunkRequest {
key: Vec3<i32>,
},
Disconnect,
}

View File

@ -126,8 +126,12 @@ impl<V: Vox, S: VolSize, M> VolMap<V, S, M> {
self.chunks.insert(key, chunk)
}
pub fn remove(&mut self, key: &Vec3<i32>) -> Option<Chunk<V, S, M>> {
self.chunks.remove(key)
pub fn get_key(&self, key: Vec3<i32>) -> Option<&Chunk<V, S, M>> {
self.chunks.get(&key)
}
pub fn remove(&mut self, key: Vec3<i32>) -> Option<Chunk<V, S, M>> {
self.chunks.remove(&key)
}
pub fn key_pos(&self, key: Vec3<i32>) -> Vec3<i32> {

View File

@ -14,6 +14,7 @@ use std::{
time::Duration,
net::SocketAddr,
sync::mpsc,
collections::HashSet,
};
use specs::{
Entity as EcsEntity,
@ -63,6 +64,7 @@ pub struct Server {
thread_pool: ThreadPool,
chunk_tx: mpsc::Sender<(Vec3<i32>, TerrainChunk)>,
chunk_rx: mpsc::Receiver<(Vec3<i32>, TerrainChunk)>,
pending_chunks: HashSet<Vec3<i32>>,
}
impl Server {
@ -83,6 +85,7 @@ impl Server {
.build(),
chunk_tx,
chunk_rx,
pending_chunks: HashSet::new(),
})
}
@ -200,6 +203,7 @@ impl Server {
let state = &mut self.state;
let mut new_chat_msgs = Vec::new();
let mut disconnected_clients = Vec::new();
let mut requested_chunks = Vec::new();
self.clients.remove_if(|entity, client| {
let mut disconnect = false;
@ -240,6 +244,7 @@ impl Server {
},
ClientState::Connected => match msg {
ClientMsg::Connect { .. } => disconnect = true, // Not allowed when already connected
ClientMsg::Disconnect => disconnect = true,
ClientMsg::Ping => client.postbox.send(ServerMsg::Pong),
ClientMsg::Pong => {},
ClientMsg::Chat(msg) => new_chat_msgs.push((entity, msg)),
@ -248,7 +253,13 @@ impl Server {
state.write_component(entity, vel);
state.write_component(entity, dir);
},
ClientMsg::Disconnect => disconnect = true,
ClientMsg::TerrainChunkRequest { key } => match state.terrain().get_key(key) {
Some(chunk) => client.postbox.send(ServerMsg::TerrainChunkUpdate {
key,
chunk: chunk.clone(),
}),
None => requested_chunks.push(key),
},
},
}
}
@ -297,6 +308,11 @@ impl Server {
});
}
// Generate requested chunks
for key in requested_chunks {
self.generate_chunk(key);
}
Ok(frontend_events)
}
@ -304,6 +320,13 @@ impl Server {
fn sync_clients(&mut self) {
self.clients.notify_connected(ServerMsg::EcsSync(self.state.ecs_mut().next_sync_package()));
}
pub fn generate_chunk(&mut self, key: Vec3<i32>) {
if self.pending_chunks.insert(key) {
let chunk_tx = self.chunk_tx.clone();
self.thread_pool.execute(move || chunk_tx.send((key, World::generate_chunk(key))).unwrap());
}
}
}
impl Drop for Server {

View File

@ -24,7 +24,7 @@ impl World {
Self
}
pub fn generate_chunk(&self, chunk_pos: Vec3<i32>) -> TerrainChunk {
pub fn generate_chunk(chunk_pos: Vec3<i32>) -> TerrainChunk {
// TODO: This is all test code, remove/improve this later
let mut chunk = TerrainChunk::filled(Block::empty(), TerrainChunkMeta::void());