mirror of
https://github.com/szymon-jozef/checkers.git
synced 2026-10-27 19:20:44 +01:00
refactor: refactor unnecessary code from the network client
I have no idea why I complicated it so much yesterday, I had a brain fart or something
This commit is contained in:
@@ -5,12 +5,9 @@ use std::{
|
|||||||
|
|
||||||
use checkers::{
|
use checkers::{
|
||||||
logic::board::pawn::{CapturePath, MovePath},
|
logic::board::pawn::{CapturePath, MovePath},
|
||||||
network::{
|
network::{client::Client, message::ServerMessage, network_identity::NetworkIdentity},
|
||||||
client::{Client, ClientData},
|
|
||||||
network_identity::NetworkIdentity,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use log::{error, info, warn};
|
use log::{error, warn};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
const QUIT_COMMAND: &str = "/quit";
|
const QUIT_COMMAND: &str = "/quit";
|
||||||
@@ -86,9 +83,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
let (client_sender, mut client_receiver) = mpsc::channel(1024);
|
|
||||||
|
|
||||||
client.set_update_sender(client_sender);
|
|
||||||
client.update();
|
client.update();
|
||||||
|
|
||||||
let (stdin_sender, mut stdin_receiver) = mpsc::channel(1024);
|
let (stdin_sender, mut stdin_receiver) = mpsc::channel(1024);
|
||||||
@@ -108,6 +102,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut client_receiver = client
|
||||||
|
.get_update_receiver()
|
||||||
|
.expect("Could not get update receiver from the network client");
|
||||||
|
|
||||||
let help_msg: String = format!(
|
let help_msg: String = format!(
|
||||||
"\n┌────Help────────────────────────────
|
"\n┌────Help────────────────────────────
|
||||||
│\t {} - quit
|
│\t {} - quit
|
||||||
@@ -122,55 +120,58 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
QUIT_COMMAND, HELP_COMMAND, READY_COMMAND, SEND_COMMAND, CAPTURE_COMMAND, MOVE_COMMAND
|
QUIT_COMMAND, HELP_COMMAND, READY_COMMAND, SEND_COMMAND, CAPTURE_COMMAND, MOVE_COMMAND
|
||||||
);
|
);
|
||||||
|
|
||||||
info!("───────Type /help for help───────");
|
println!("───────Type /help for help───────");
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
msg = client_receiver.recv() => {
|
msg = client_receiver.recv() => {
|
||||||
match msg {
|
match msg {
|
||||||
Some(ClientData::GameStart {
|
Some(ServerMessage::GameStart {
|
||||||
identity,
|
identity,
|
||||||
}) => {
|
}) => {
|
||||||
info!(
|
println!(
|
||||||
"Got new identity: {}",
|
"Got new identity: {}",
|
||||||
identity
|
identity
|
||||||
);
|
);
|
||||||
context.identity = Some(identity);
|
context.identity = Some(identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ClientData::BoardView(view)) => {
|
Some(ServerMessage::BroadcastBoardState{board}) => {
|
||||||
info!("New board state:\n{}", view.to_string(&context.identity.as_ref().unwrap().id));
|
println!("New board state:\n{}", board.to_string(&context.identity.as_ref().unwrap().id));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ClientData::CurrentTurn(current_turn)) => {
|
Some(ServerMessage::BroadcastCurrentTurn{active_player}) => {
|
||||||
context.is_my_turn = current_turn == context.identity.as_ref().expect("Server sent us new current turn without telling us who we are!").id;
|
context.is_my_turn = active_player == context.identity.as_ref().expect("Server sent us new current turn without telling us who we are!").id;
|
||||||
if context.is_my_turn {
|
if context.is_my_turn {
|
||||||
info!("It's our turn!");
|
println!("It's our turn!");
|
||||||
} else {
|
} else {
|
||||||
info!("It's the turn of our enemy!");
|
println!("It's the turn of our enemy!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ClientData::AvailableCaptures(capture_paths)) => {
|
Some(ServerMessage::AvailableCaptures{captures}) => {
|
||||||
info!("Available captures paths: {:?}", capture_paths);
|
println!("Available captures paths: {:?}", captures);
|
||||||
context.available_moves = None;
|
context.available_moves = None;
|
||||||
context.available_captures = Some(capture_paths);
|
context.available_captures = Some(captures);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ClientData::AvailableMoves(move_paths)) => {
|
Some(ServerMessage::AvailableMoves{moves}) => {
|
||||||
info!("Available moves: {:?}", move_paths);
|
println!("Available moves: {:?}", moves);
|
||||||
context.available_moves = Some(move_paths);
|
context.available_moves = Some(moves);
|
||||||
context.available_captures = None;
|
context.available_captures = None;
|
||||||
},
|
},
|
||||||
|
|
||||||
Some(ClientData::TextMessage {sender, content}) => {
|
Some(ServerMessage::BroadCastTextMessage {sender, content}) => {
|
||||||
info!("[{}] - {}", sender, content);
|
println!("[{}] - {}", sender, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ClientData::GameEnd(game_result)) => {
|
Some(ServerMessage::GameEnd{result}) => {
|
||||||
info!("Game has ended with the result: {:?}", game_result);
|
println!("Game has ended with the result: {:?}", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(_) => {
|
||||||
|
error!("This shouldn't happen");
|
||||||
|
} // ignore messages already handled by the network client
|
||||||
|
|
||||||
None => {
|
None => {
|
||||||
warn!("Connection broken! Stopping");
|
warn!("Connection broken! Stopping");
|
||||||
break Ok(());
|
break Ok(());
|
||||||
@@ -189,11 +190,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
match CliCommands::try_from(cmd) {
|
match CliCommands::try_from(cmd) {
|
||||||
Ok(cmd) => match cmd {
|
Ok(cmd) => match cmd {
|
||||||
CliCommands::Quit => {
|
CliCommands::Quit => {
|
||||||
info!("Bye bye");
|
println!("Bye bye");
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
CliCommands::Help => {
|
CliCommands::Help => {
|
||||||
info!("{}", help_msg);
|
println!("{}", help_msg);
|
||||||
}
|
}
|
||||||
CliCommands::Ready => {
|
CliCommands::Ready => {
|
||||||
client.signal_readiness().await;
|
client.signal_readiness().await;
|
||||||
|
|||||||
@@ -1,25 +1,16 @@
|
|||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info};
|
||||||
use tokio::sync::mpsc::{self, Receiver, Sender};
|
use tokio::sync::mpsc::{self, Receiver, Sender};
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
logic::{
|
logic::{board::pawn::CapturePath, math::position::Position},
|
||||||
board::{
|
|
||||||
board_view::BoardView,
|
|
||||||
pawn::{CapturePath, MovePath},
|
|
||||||
},
|
|
||||||
game_master::GameResult,
|
|
||||||
math::position::Position,
|
|
||||||
},
|
|
||||||
network::{
|
network::{
|
||||||
connection::{Connection, ConnectionType},
|
connection::{Connection, ConnectionType},
|
||||||
message::{
|
message::{
|
||||||
ClientMessage::{self, SignalReadiness, TextMessage},
|
ClientMessage::{self},
|
||||||
Message, ServerMessage,
|
Message, ServerMessage,
|
||||||
},
|
},
|
||||||
network_identity::NetworkIdentity,
|
|
||||||
},
|
},
|
||||||
settings::{client_settings::ClientSettings, general_settings::SettingsLike},
|
settings::{client_settings::ClientSettings, general_settings::SettingsLike},
|
||||||
};
|
};
|
||||||
@@ -31,30 +22,13 @@ pub enum ClientCommands {
|
|||||||
SendReady,
|
SendReady,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data that network client gives to normal client. I have no better idea for this name, hence this
|
|
||||||
/// comment
|
|
||||||
pub enum ClientData {
|
|
||||||
GameStart { identity: NetworkIdentity },
|
|
||||||
GameEnd(GameResult),
|
|
||||||
|
|
||||||
AvailableCaptures(Vec<CapturePath>),
|
|
||||||
AvailableMoves(Vec<MovePath>),
|
|
||||||
|
|
||||||
BoardView(BoardView),
|
|
||||||
CurrentTurn(Uuid),
|
|
||||||
|
|
||||||
TextMessage { sender: String, content: String },
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
conn_reciever_incoming: Option<Receiver<(SocketAddr, Message<ServerMessage>)>>,
|
conn_reciever_incoming: Option<Receiver<(SocketAddr, Message<ServerMessage>)>>,
|
||||||
conn_sender_outgoing: Sender<Message<ClientMessage>>,
|
conn_sender_outgoing: Sender<Message<ClientMessage>>,
|
||||||
settings: ClientSettings,
|
settings: ClientSettings,
|
||||||
|
|
||||||
commands_sender: Option<Sender<ClientCommands>>,
|
update_sender: Sender<ServerMessage>,
|
||||||
commands_receiver: Option<Receiver<ClientCommands>>,
|
update_receiver: Option<Receiver<ServerMessage>>,
|
||||||
|
|
||||||
update_sender: Option<Sender<ClientData>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
@@ -67,7 +41,7 @@ impl Client {
|
|||||||
Connection::new(ConnectionType::Server, conn_sender);
|
Connection::new(ConnectionType::Server, conn_sender);
|
||||||
let conn_sender_outgoing = conn.get_sender();
|
let conn_sender_outgoing = conn.get_sender();
|
||||||
|
|
||||||
let (commands_sender, commands_receiver) = mpsc::channel(1024);
|
let (update_sender, update_receiver) = mpsc::channel(1024);
|
||||||
|
|
||||||
if !conn.connect_to_server(settings.server_url).await {
|
if !conn.connect_to_server(settings.server_url).await {
|
||||||
error!("Could not connect with the server: {}", settings.server_url);
|
error!("Could not connect with the server: {}", settings.server_url);
|
||||||
@@ -84,29 +58,11 @@ impl Client {
|
|||||||
|
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
commands_receiver: Some(commands_receiver),
|
update_sender,
|
||||||
commands_sender: Some(commands_sender),
|
update_receiver: Some(update_receiver),
|
||||||
|
|
||||||
update_sender: None,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_commands_sender(&mut self) -> Option<Sender<ClientCommands>> {
|
|
||||||
if self.commands_sender.is_none() {
|
|
||||||
warn!("Tried taking commands sender a second time! This shouldn't happen");
|
|
||||||
}
|
|
||||||
self.commands_sender.take()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_update_sender(&mut self, sender: Sender<ClientData>) {
|
|
||||||
if self.update_sender.is_some() {
|
|
||||||
warn!("Cannot set update sender a second time!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.update_sender = Some(sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
let Some(mut conn_reciever_incoming) = self.conn_reciever_incoming.take() else {
|
let Some(mut conn_reciever_incoming) = self.conn_reciever_incoming.take() else {
|
||||||
error!("Tried updating, but there's no conn_reciever of incoming messages!");
|
error!("Tried updating, but there's no conn_reciever of incoming messages!");
|
||||||
@@ -115,17 +71,8 @@ impl Client {
|
|||||||
|
|
||||||
let conn_sender = self.conn_sender_outgoing.clone();
|
let conn_sender = self.conn_sender_outgoing.clone();
|
||||||
|
|
||||||
let Some(update_sender) = self.update_sender.take() else {
|
|
||||||
error!("Update sender is missing. Cannot update!");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(mut commands_receiver) = self.commands_receiver.take() else {
|
|
||||||
error!("Commands receiver is missing! Cannot update.");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let settings = self.settings.clone();
|
let settings = self.settings.clone();
|
||||||
|
let update_sender = self.update_sender.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
@@ -154,120 +101,22 @@ impl Client {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerMessage::GameStart {
|
_ => { // Pass all messages that require player intervention to the
|
||||||
identity,
|
// local client
|
||||||
} => {
|
let _ = update_sender.send(msg.content).await;
|
||||||
debug!("Got GameStart message! Identity: {}", identity);
|
|
||||||
let _ = update_sender.send(ClientData::GameStart { identity }).await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerMessage::BroadcastCurrentTurn { active_player } => {
|
|
||||||
let _ = update_sender.send(ClientData::CurrentTurn(active_player)).await;
|
|
||||||
},
|
|
||||||
ServerMessage::BroadcastBoardState { board } => {
|
|
||||||
let _ = update_sender.send(ClientData::BoardView(board)).await;
|
|
||||||
},
|
|
||||||
|
|
||||||
ServerMessage::BroadCastTextMessage {sender, content} => {
|
|
||||||
let _ = update_sender.send(ClientData::TextMessage {sender, content}).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ServerMessage::AvailableCaptures { captures } => {
|
|
||||||
let _ = update_sender.send(ClientData::AvailableCaptures(captures)).await;
|
|
||||||
},
|
|
||||||
|
|
||||||
ServerMessage::AvailableMoves { moves } => {
|
|
||||||
let _ = update_sender.send(ClientData::AvailableMoves(moves)).await;
|
|
||||||
},
|
|
||||||
|
|
||||||
ServerMessage::GameEnd { result } => {
|
|
||||||
let _ = update_sender.send(ClientData::GameEnd(result)).await;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error!("Connection broken!");
|
error!("Connection broken!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oldest_cmd = commands_receiver.recv() => {
|
|
||||||
if let Some(oldest_cmd) = oldest_cmd {
|
|
||||||
match oldest_cmd {
|
|
||||||
ClientCommands::SendCapture(capture_path) => {
|
|
||||||
debug!("Sending capture path: {:?}", capture_path);
|
|
||||||
let msg = Message::new(ClientMessage::RequestCapture { capture_path });
|
|
||||||
send_message(msg, &conn_sender).await;
|
|
||||||
},
|
|
||||||
|
|
||||||
ClientCommands::SendMove { from, to } => {
|
|
||||||
debug!("Sending move from: {} to: {}", from, to);
|
|
||||||
let msg = Message::new(ClientMessage::RequestMove { from, to});
|
|
||||||
send_message(msg, &conn_sender).await;
|
|
||||||
},
|
|
||||||
|
|
||||||
ClientCommands::SendText(content) => {
|
|
||||||
debug!("Seding text message: {}", content);
|
|
||||||
let msg = Message::new(TextMessage(content));
|
|
||||||
send_message(msg, &conn_sender).await;
|
|
||||||
},
|
|
||||||
|
|
||||||
ClientCommands::SendReady => {
|
|
||||||
debug!("Signaling readiness!");
|
|
||||||
let msg = Message::new(SignalReadiness);
|
|
||||||
send_message(msg, &conn_sender).await;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
error!("Couldn't decipher the command!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_capture(&mut self, capture: CapturePath) {
|
async fn send_message(&mut self, msg: Result<Message<ClientMessage>, postcard::Error>) {
|
||||||
debug!("Requesting sending capture: {:?}", capture);
|
|
||||||
if let Some(sender) = &self.commands_sender {
|
|
||||||
let _ = sender.send(ClientCommands::SendCapture(capture)).await;
|
|
||||||
} else {
|
|
||||||
error!("Command sender not set!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_move(&mut self, from: Position, to: Position) {
|
|
||||||
debug!("Requested sending move from: {} to: {}", from, to);
|
|
||||||
if let Some(sender) = &self.commands_sender {
|
|
||||||
let _ = sender.send(ClientCommands::SendMove { from, to }).await;
|
|
||||||
} else {
|
|
||||||
error!("Command sender not set!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_text_message(&mut self, content: String) {
|
|
||||||
if let Some(sender) = &self.commands_sender {
|
|
||||||
let _ = sender.send(ClientCommands::SendText(content)).await;
|
|
||||||
} else {
|
|
||||||
error!("Command sender not set!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn signal_readiness(&mut self) {
|
|
||||||
if let Some(sender) = &self.commands_sender {
|
|
||||||
let _ = sender.send(ClientCommands::SendReady).await;
|
|
||||||
} else {
|
|
||||||
error!("Command sender not set!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send_message(
|
|
||||||
msg: Result<Message<ClientMessage>, postcard::Error>,
|
|
||||||
sender: &Sender<Message<ClientMessage>>,
|
|
||||||
) {
|
|
||||||
debug!("Sending message to the server!");
|
debug!("Sending message to the server!");
|
||||||
let _ = match msg {
|
let _ = match msg {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -275,10 +124,40 @@ async fn send_message(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Ok(msg) => {
|
Ok(msg) => {
|
||||||
if let Err(e) = sender.send(msg).await {
|
if let Err(e) = self.conn_sender_outgoing.send(msg).await {
|
||||||
error!("Error while sending a message to connection thread: {}", e);
|
error!("Error while sending a message to connection thread: {}", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn send_capture(&mut self, capture_path: CapturePath) {
|
||||||
|
debug!("Requesting sending capture: {:?}", capture_path);
|
||||||
|
|
||||||
|
let msg = Message::new(ClientMessage::RequestCapture { capture_path });
|
||||||
|
self.send_message(msg).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_move(&mut self, from: Position, to: Position) {
|
||||||
|
debug!("Requested sending move from: {} to: {}", from, to);
|
||||||
|
let msg = Message::new(ClientMessage::RequestMove { from, to });
|
||||||
|
self.send_message(msg).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_text_message(&mut self, content: String) {
|
||||||
|
debug!("Sending text message with content: [{}]", content);
|
||||||
|
let msg = Message::new(ClientMessage::TextMessage(content));
|
||||||
|
self.send_message(msg).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn signal_readiness(&mut self) {
|
||||||
|
debug!("Signaling readiness to the server...");
|
||||||
|
let msg = Message::new(ClientMessage::SignalReadiness);
|
||||||
|
self.send_message(msg).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_update_receiver(&mut self) -> Option<Receiver<ServerMessage>> {
|
||||||
|
self.update_receiver.take()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user