Handle connection event properly

This commit is contained in:
Hamcha 2020-10-05 02:24:23 +02:00
parent f7255b3617
commit b615c86820
Signed by: hamcha
GPG key ID: 41467804B19A3315
10 changed files with 82 additions and 30 deletions

9
src/components/map.rs Normal file
View file

@ -0,0 +1,9 @@
pub struct Tile {
contents: Vec<u32>,
}
pub struct Map {
width: u16,
height: u16,
tiles: Vec<Tile>,
}

View file

@ -1,3 +1,3 @@
pub mod network; pub mod map;
pub mod transform; pub mod transform;
pub mod viewport; pub mod viewport;

View file

@ -1,4 +0,0 @@
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct NetworkConnection {
conn_id: u64,
}

View file

@ -1,6 +1,5 @@
use ultraviolet::Vec2; use ultraviolet::Vec2;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Transform { pub struct Transform {
pub chunk_id: (u16, u16), pub chunk_id: (u16, u16),
pub position: Vec2, pub position: Vec2,

View file

@ -1,6 +1,5 @@
use ultraviolet::Vec2; use ultraviolet::Vec2;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Viewport { pub struct Viewport {
pub chunk_id: (u16, u16), pub chunk_id: (u16, u16),
pub position: Vec2, pub position: Vec2,

View file

@ -1,4 +1,6 @@
use crate::network::NetworkMessage; use crate::network::{NetworkMessage, NetworkPayload};
use async_std::sync::Arc;
use async_std::sync::RwLock;
use async_std::sync::{Receiver, Sender}; use async_std::sync::{Receiver, Sender};
use shipyard::{error, World}; use shipyard::{error, World};
use std::collections::HashMap; use std::collections::HashMap;
@ -16,7 +18,12 @@ impl Game {
// Create world // Create world
let world = World::default(); let world = World::default();
// Create workload // Create init workload
world.run(|| {
//todo
});
// Create update workload
world.add_workload("update").build(); world.add_workload("update").build();
Game { Game {
@ -30,15 +37,29 @@ impl Game {
self.world.try_run_workload("update") self.world.try_run_workload("update")
} }
pub async fn read_loop(&self, net_in: Receiver<NetworkMessage>) { pub async fn read_loop(game: Arc<RwLock<Self>>, net_in: Receiver<NetworkMessage>) {
loop { loop {
let message = net_in.recv().await.expect("could not read from channel"); let message = net_in.recv().await.expect("could not read from channel");
self.net_out match message.data {
.send(NetworkMessage { NetworkPayload::Connected => {
conn_id: message.conn_id, log::info!("[{:?}] connected", &message.conn_id);
data: tungstenite::Message::text("hello"), game.write()
}) .await
.await; .players
.insert(message.conn_id, Player {});
}
NetworkPayload::Message(msg) => {
log::info!("[{:?}] said {:?}", &message.conn_id, msg);
game.write()
.await
.net_out
.send(NetworkMessage {
conn_id: message.conn_id,
data: NetworkPayload::Message(tungstenite::Message::text("hello")),
})
.await;
}
}
} }
} }
} }

View file

@ -8,6 +8,7 @@ use crate::config::Settings;
use crate::game::Game; use crate::game::Game;
use crate::network::listen; use crate::network::listen;
use async_std::sync::Arc; use async_std::sync::Arc;
use async_std::sync::RwLock;
use async_std::{sync::channel, task}; use async_std::{sync::channel, task};
use env_logger::Env; use env_logger::Env;
use std::time::Duration; use std::time::Duration;
@ -24,17 +25,15 @@ async fn run() {
let (in_s, in_r) = channel(10); let (in_s, in_r) = channel(10);
let (out_s, out_r) = channel(10); let (out_s, out_r) = channel(10);
let game = Arc::new(Game::new(out_s)); let game = Arc::new(RwLock::new(Game::new(out_s)));
let game_read_loop = game.clone(); let game_read_loop = game.clone();
task::spawn(async move { task::spawn(Game::read_loop(game_read_loop, in_r));
game_read_loop.read_loop(in_r).await;
});
task::spawn(async move { task::spawn(async move {
loop { loop {
let game = game.clone(); let game = game.clone();
task::spawn(async move { game.update().expect("update failed") }); task::spawn(async move { game.read().await.update().expect("update failed") });
task::sleep(Duration::from_millis(MIN_UPDATE_MS)).await; task::sleep(Duration::from_millis(MIN_UPDATE_MS)).await;
} }
}); });

View file

@ -11,11 +11,18 @@ use futures_util::{stream::SplitSink, stream::SplitStream, SinkExt, StreamExt};
#[derive(Debug)] #[derive(Debug)]
pub struct NetworkMessage { pub struct NetworkMessage {
pub conn_id: usize, pub conn_id: usize,
pub data: tungstenite::Message, pub data: NetworkPayload,
}
#[derive(Debug)]
pub enum NetworkPayload {
Connected,
Message(tungstenite::Message),
} }
struct Connection { struct Connection {
stream: SplitSink<WebSocketStream<TcpStream>, tungstenite::Message>, stream: SplitSink<WebSocketStream<TcpStream>, tungstenite::Message>,
address: SocketAddr,
conn_id: usize, conn_id: usize,
} }
@ -39,10 +46,14 @@ impl NetworkManager {
.connections .connections
.get_mut(&message.conn_id) .get_mut(&message.conn_id)
.expect("cant send message to an unregistered connection"); .expect("cant send message to an unregistered connection");
conn.stream match message.data {
.send(message.data) NetworkPayload::Message(msg) => conn
.await .stream
.expect("could not send message to connection"); .send(msg)
.await
.expect("could not send message to connection"),
_ => (),
}
} }
} }
@ -70,13 +81,27 @@ async fn accept_connection(
stream: TcpStream, stream: TcpStream,
incoming: Sender<NetworkMessage>, incoming: Sender<NetworkMessage>,
) -> Connection { ) -> Connection {
// Generate random connection id
let conn_id = rand::random(); let conn_id = rand::random();
// Get streams
let ws_stream = accept_async(stream).await.expect("could not accept"); let ws_stream = accept_async(stream).await.expect("could not accept");
log::info!("New WebSocket connection: {}", peer);
let (ws_sender, ws_receiver) = ws_stream.split(); let (ws_sender, ws_receiver) = ws_stream.split();
// Send event to game instance
incoming
.send(NetworkMessage {
conn_id,
data: NetworkPayload::Connected,
})
.await;
// Start read loop
task::spawn(read_loop(ws_receiver, incoming, conn_id)); task::spawn(read_loop(ws_receiver, incoming, conn_id));
// Return connection instance for network manager
Connection { Connection {
stream: ws_sender, stream: ws_sender,
address: peer,
conn_id, conn_id,
} }
} }
@ -87,12 +112,16 @@ async fn read_loop(
conn_id: usize, conn_id: usize,
) { ) {
loop { loop {
let data = stream let message = stream
.next() .next()
.await .await
.expect("failed getting the next message") .expect("failed getting the next message")
.expect("received error while reading"); .expect("received error while reading");
ch.send(NetworkMessage { conn_id, data }).await; ch.send(NetworkMessage {
conn_id,
data: NetworkPayload::Message(message),
})
.await;
} }
} }

View file

View file

@ -1 +1 @@
pub mod client;