Compare commits

..

No commits in common. "6189b82bd38340bcb1a4eedb4e871b4c8054451b" and "e661526e783762a08a15e693036239569d279a99" have entirely different histories.

5 changed files with 41 additions and 89 deletions

View File

@ -1,10 +1,13 @@
use std::sync::Arc; use std::sync::Arc;
use futures::{select, FutureExt}; use futures::{select, FutureExt};
use tokio::sync::Mutex;
use crate::{msg, GlobalState}; use hexland_server::{
use crate::game::{channel_pair, Channel, GameController}; channel_pair,
use crate::message::{Message, MessageWebSocket}; message::{Message, MessageWebSocket},
msg, Channel, GameController, GlobalState,
};
pub struct Client { pub struct Client {
global_state: Arc<GlobalState>, global_state: Arc<GlobalState>,
@ -44,18 +47,19 @@ impl Client {
match msg.command.as_str() { match msg.command.as_str() {
"HOST" => { "HOST" => {
let room_code = self.global_state.code_generator.lock().await.generate(); let room_code = self.global_state.code_generator.lock().await.generate();
let game_controller = GameController::default(); let mut game_controller = GameController::default();
let (client_channel, server_channel) = channel_pair(); let (client_channel, server_channel) = channel_pair();
self.channel = Some(client_channel); self.channel = Some(client_channel);
game_controller.channels.lock().await.push(server_channel); game_controller.channels.push(server_channel);
let game_controller = Arc::new(Mutex::new(game_controller));
self.global_state self.global_state
.rooms .rooms
.lock() .lock()
.await .await
.insert(room_code.clone(), game_controller.clone()); .insert(room_code.clone(), Arc::clone(&game_controller));
tokio::spawn(async move { game_controller.run_loop().await }); tokio::spawn(async move { game_loop(game_controller) });
self.ws.send(msg!(ROOM_CODE, room_code)).await.unwrap(); self.ws.send(msg!(ROOM_CODE, room_code)).await.unwrap();
} }
"JOIN" => { "JOIN" => {
@ -65,9 +69,10 @@ impl Client {
match room { match room {
Some(room) => { Some(room) => {
let mut room = room.lock().await;
let (client_channel, server_channel) = channel_pair(); let (client_channel, server_channel) = channel_pair();
self.channel = Some(client_channel); self.channel = Some(client_channel);
room.channels.lock().await.push(server_channel); room.channels.push(server_channel);
self.ws.send(msg!(JOIN_OK)).await.unwrap(); self.ws.send(msg!(JOIN_OK)).await.unwrap();
} }
None => { None => {
@ -88,3 +93,7 @@ impl Client {
self.ws.send(msg).await.unwrap(); self.ws.send(msg).await.unwrap();
} }
} }
fn game_loop(_gc: Arc<Mutex<GameController>>) {
todo!();
}

View File

@ -1,70 +0,0 @@
use std::sync::Arc;
use tokio::sync::{ mpsc, Mutex };
use tokio::sync::mpsc::error::TryRecvError;
use crate::message::Message;
#[derive(Clone)]
pub struct GameController {
pub channels: Arc<Mutex<Channels>>,
}
impl std::default::Default for GameController {
fn default() -> Self {
let channels = Arc::new(Mutex::new(Channels::default()));
GameController { channels }
}
}
pub struct Channel {
pub tx: mpsc::Sender<Message>,
pub rx: mpsc::Receiver<Message>,
}
#[derive(Default)]
pub struct Channels(Vec<Channel>);
impl Channels {
pub fn try_recv(&mut self) -> Result<Message, TryRecvError> {
for channel in self.0.iter_mut() {
let res = channel.rx.try_recv();
if !(res == Err(TryRecvError::Empty)) {
return res
}
}
Err(TryRecvError::Empty)
}
pub async fn broadcast(&mut self, msg: Message) {
for channel in self.0.iter_mut() {
channel.tx.send(msg.clone()).await.unwrap();
}
}
pub fn push(&mut self, channel: Channel) {
self.0.push(channel);
}
}
pub fn channel_pair() -> (Channel, Channel) {
let (atx, brx) = mpsc::channel(32);
let (btx, arx) = mpsc::channel(32);
(Channel { tx: atx, rx: arx }, Channel { tx: btx, rx: brx })
}
impl GameController {
pub async fn run_loop(&self) {
loop {
let mut channels = self.channels.lock().await;
if let Ok(msg) = channels.try_recv() {
dispatch(&mut channels, msg).await;
}
}
}
}
async fn dispatch(channels: &mut Channels, msg: Message) {
match msg.command.as_str() {
"CHAT" => channels.broadcast(msg).await,
_ => ()
};
}

View File

@ -1,18 +1,30 @@
use std::collections::HashMap; use std::{collections::HashMap, sync::Arc};
use std::sync::Arc;
use tokio::sync::Mutex; use tokio::sync::{mpsc, Mutex};
pub mod game;
pub mod message; pub mod message;
pub mod client; use message::Message;
use game::GameController;
mod code_generator; mod code_generator;
use code_generator::CodeGenerator; use code_generator::CodeGenerator;
#[derive(Default)] #[derive(Default)]
pub struct GlobalState { pub struct GlobalState {
pub code_generator: Arc<Mutex<CodeGenerator>>, pub code_generator: Arc<Mutex<CodeGenerator>>,
pub rooms: Arc<Mutex<HashMap<String, GameController>>>, pub rooms: Arc<Mutex<HashMap<String, Arc<Mutex<GameController>>>>>,
}
pub struct Channel {
pub tx: mpsc::Sender<Message>,
pub rx: mpsc::Receiver<Message>,
}
pub fn channel_pair() -> (Channel, Channel) {
let (atx, brx) = mpsc::channel(32);
let (btx, arx) = mpsc::channel(32);
(Channel { tx: atx, rx: arx }, Channel { tx: btx, rx: brx })
}
#[derive(Default)]
pub struct GameController {
pub channels: Vec<Channel>,
} }

View File

@ -2,10 +2,11 @@ use std::{io::Error as IoError, sync::Arc};
use tokio::net::TcpListener; use tokio::net::TcpListener;
use hexland_server::GlobalState;
use hexland_server::client::Client;
use hexland_server::message::MessageWebSocket; use hexland_server::message::MessageWebSocket;
use hexland_server::GlobalState;
mod client;
use client::Client;
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), IoError> { async fn main() -> Result<(), IoError> {

View File

@ -5,7 +5,7 @@ use lazy_static::lazy_static;
use tokio::net::TcpStream; use tokio::net::TcpStream;
use tokio_tungstenite::{tungstenite::Message as WsMessage, WebSocketStream}; use tokio_tungstenite::{tungstenite::Message as WsMessage, WebSocketStream};
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug)]
pub struct Message { pub struct Message {
pub command: String, pub command: String,
pub args: Vec<String>, pub args: Vec<String>,