Handle connection event properly
This commit is contained in:
parent
f7255b3617
commit
b615c86820
10 changed files with 82 additions and 30 deletions
9
src/components/map.rs
Normal file
9
src/components/map.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
pub struct Tile {
|
||||||
|
contents: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Map {
|
||||||
|
width: u16,
|
||||||
|
height: u16,
|
||||||
|
tiles: Vec<Tile>,
|
||||||
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
pub mod network;
|
pub mod map;
|
||||||
pub mod transform;
|
pub mod transform;
|
||||||
pub mod viewport;
|
pub mod viewport;
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
||||||
pub struct NetworkConnection {
|
|
||||||
conn_id: u64,
|
|
||||||
}
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
39
src/game.rs
39
src/game.rs
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
pub mod client;
|
|
||||||
|
|
Loading…
Reference in a new issue