wip connect

This commit is contained in:
griffi-gh 2023-02-13 04:12:02 +01:00
parent 72d8e17b43
commit 71f89e8f28
5 changed files with 72 additions and 8 deletions

View file

@ -1,13 +1,13 @@
use shipyard::{Unique, Component}; use shipyard::{Unique, Component};
// disconnected => connect => join => load => ingame // disconnected => connect => join => load => ingame
#[derive(Unique, Component)] #[derive(Unique, Component, PartialEq, Eq, Clone, Copy)]
pub enum ClientJoinState { pub enum ClientJoinState {
/// Not connected yet /// Not connected yet
Disconnected, Disconnected,
/// Client has connected to the game, but hasn't authenticated yet /// Client has connected to the game, but hasn't authenticated yet
Connected, Connected,
/// Client has joined the game, but haven't loaded the world yet /// Client has joined the game, but hasn't loaded the world yet
Joined, Joined,
/// Client is currently ingame /// Client is currently ingame
InGame, InGame,

View file

@ -0,0 +1,12 @@
use kubi_shared::networking::state::ClientJoinState;
use shipyard::{UniqueViewMut, UniqueView};
use crate::state::{NextState, GameState};
pub fn switch_to_loading_if_connected(
mut next_state: UniqueViewMut<NextState>,
client_state: UniqueView<ClientJoinState>,
) {
if *client_state == ClientJoinState::Joined {
next_state.0 = Some(GameState::LoadingWorld);
}
}

View file

@ -39,12 +39,14 @@ pub(crate) mod networking;
pub(crate) mod init; pub(crate) mod init;
pub(crate) mod color; pub(crate) mod color;
pub(crate) mod loading_screen; pub(crate) mod loading_screen;
pub(crate) mod connecting_screen;
use world::{ use world::{
init_game_world, init_game_world,
loading::update_loaded_world_around_player, loading::update_loaded_world_around_player,
raycast::update_raycasts, raycast::update_raycasts,
queue::apply_queued_blocks queue::apply_queued_blocks,
tasks::inject_network_responses_into_manager_queue
}; };
use player::spawn_player; use player::spawn_player;
use prefabs::load_prefabs; use prefabs::load_prefabs;
@ -74,11 +76,12 @@ use block_placement::block_placement_system;
use delta_time::{DeltaTime, init_delta_time}; use delta_time::{DeltaTime, init_delta_time};
use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now};
use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow};
use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state}; use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state, is_connecting};
use networking::{update_networking, is_multiplayer, disconnect_on_exit}; use networking::{update_networking, is_multiplayer, disconnect_on_exit};
use init::initialize_from_args; use init::initialize_from_args;
use gui::{render_gui, init_gui, update_gui}; use gui::{render_gui, init_gui, update_gui};
use loading_screen::update_loading_screen; use loading_screen::update_loading_screen;
use connecting_screen::switch_to_loading_if_connected;
fn startup() -> Workload { fn startup() -> Workload {
( (
@ -104,10 +107,13 @@ fn update() -> Workload {
update_window_size, update_window_size,
update_cursor_lock_state, update_cursor_lock_state,
process_inputs, process_inputs,
( (
update_networking update_networking,
inject_network_responses_into_manager_queue,
).into_workload().run_if(is_multiplayer), ).into_workload().run_if(is_multiplayer),
(
switch_to_loading_if_connected
).into_workload().run_if(is_connecting),
( (
update_loading_screen, update_loading_screen,
).into_workload().run_if(is_loading), ).into_workload().run_if(is_loading),

View file

@ -35,6 +35,12 @@ pub fn is_changing_state(
state.0.is_some() state.0.is_some()
} }
pub fn is_connecting(
state: UniqueView<GameState>
) -> bool {
*state == GameState::Connecting
}
pub fn is_ingame( pub fn is_ingame(
state: UniqueView<GameState> state: UniqueView<GameState>
) -> bool { ) -> bool {

View file

@ -1,13 +1,15 @@
use flume::{Sender, Receiver}; use flume::{Sender, Receiver};
use glam::IVec3; use glam::IVec3;
use shipyard::Unique; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage};
use shipyard::{Unique, UniqueView, View, IntoIter};
use rayon::{ThreadPool, ThreadPoolBuilder}; use rayon::{ThreadPool, ThreadPoolBuilder};
use super::{ use super::{
chunk::BlockData, chunk::BlockData,
mesh::{generate_mesh, data::MeshGenData}, mesh::{generate_mesh, data::MeshGenData},
worldgen::generate_world, worldgen::generate_world,
}; };
use crate::rendering::world::ChunkVertex; use crate::{rendering::world::ChunkVertex, networking::{UdpClient, NetworkEvent}};
use kubi_udp::client::ClientEvent;
pub enum ChunkTask { pub enum ChunkTask {
LoadChunk { LoadChunk {
@ -43,6 +45,11 @@ impl ChunkTaskManager {
pool: ThreadPoolBuilder::new().num_threads(4).build().unwrap() pool: ThreadPoolBuilder::new().num_threads(4).build().unwrap()
} }
} }
pub fn add_sussy_response(&self, response: ChunkTaskResponse) {
// this WILL get stuck if the channel is bounded
// don't make the channel bounded ever
self.channel.0.send(response).unwrap()
}
pub fn spawn_task(&self, task: ChunkTask) { pub fn spawn_task(&self, task: ChunkTask) {
let sender = self.channel.0.clone(); let sender = self.channel.0.clone();
self.pool.spawn(move || { self.pool.spawn(move || {
@ -62,3 +69,36 @@ impl ChunkTaskManager {
self.channel.1.try_recv().ok() self.channel.1.try_recv().ok()
} }
} }
pub fn spawn_task_or_get_from_network_if_possible(client: Option<&mut UdpClient>, manager: &mut ChunkTaskManager, task: ChunkTask) {
match &task {
ChunkTask::LoadChunk { seed, position } => {
match client {
Some(client) => {
client.0.send_message(ClientToServerMessage::ChunkRequest { chunk: position.to_array() }).unwrap();
},
None => {
manager.spawn_task(task)
}
}
},
_ => {
manager.spawn_task(task)
}
}
}
//TODO get rid of this, this is awfulll
pub fn inject_network_responses_into_manager_queue(
manager: UniqueView<ChunkTaskManager>,
events: View<NetworkEvent>
) {
for event in events.iter() {
if let ClientEvent::MessageReceived(ServerToClientMessage::ChunkResponse { chunk, data }) = &event.0 {
let position = IVec3::from_array(*chunk);
manager.add_sussy_response(ChunkTaskResponse::LoadedChunk {
position, chunk_data: data.clone()
});
}
}
}