mirror of
https://github.com/szymon-jozef/checkers.git
synced 2026-10-27 19:20:44 +01:00
refactor: split chat from game.rs
This commit is contained in:
58
src/ui/macroquad/game/chat.rs
Normal file
58
src/ui/macroquad/game/chat.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use macroquad::{
|
||||
color::WHITE,
|
||||
math::{Rect, vec2},
|
||||
shapes::draw_rectangle,
|
||||
ui::{hash, root_ui, widgets::InputText},
|
||||
window::{screen_height, screen_width},
|
||||
};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
|
||||
use crate::ui::macroquad::game::game::GuiCommands;
|
||||
|
||||
struct Message {
|
||||
sender: String,
|
||||
content: String,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Chat {
|
||||
area: Rect,
|
||||
messages: Vec<Message>,
|
||||
message_buffer: String,
|
||||
}
|
||||
|
||||
impl Chat {
|
||||
pub fn update(&mut self, game_area: &Rect) {
|
||||
self.area = Rect {
|
||||
x: game_area.w,
|
||||
y: 0.0,
|
||||
w: screen_width() * 0.2,
|
||||
h: screen_height(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn push_message(&mut self, sender: String, content: String) {
|
||||
self.messages.push(Message { sender, content });
|
||||
}
|
||||
|
||||
pub fn send_message(&mut self, cmd_sender: Sender<GuiCommands>) {
|
||||
if !self.message_buffer.is_empty() {
|
||||
let _ = // TODO! Check the message before sending
|
||||
cmd_sender
|
||||
.try_send(GuiCommands::Send(self.message_buffer.clone()));
|
||||
self.message_buffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&mut self) {
|
||||
draw_rectangle(self.area.x, self.area.y, self.area.w, self.area.h, WHITE);
|
||||
|
||||
let input_size = vec2(self.area.w, self.area.h * 0.1);
|
||||
let input_pos = vec2(self.area.x, self.area.h - input_size.y);
|
||||
|
||||
InputText::new(hash!())
|
||||
.position(input_pos)
|
||||
.size(input_size)
|
||||
.ui(&mut root_ui(), &mut self.message_buffer);
|
||||
}
|
||||
}
|
||||
263
src/ui/macroquad/game/game.rs
Normal file
263
src/ui/macroquad/game/game.rs
Normal file
@@ -0,0 +1,263 @@
|
||||
use tokio::sync::mpsc::{self, Sender};
|
||||
|
||||
use log::{debug, error, info};
|
||||
use macroquad::{
|
||||
color::GRAY,
|
||||
input::{KeyCode, get_keys_pressed},
|
||||
math::{Rect, Vec2, vec2},
|
||||
shapes::draw_rectangle,
|
||||
ui::{hash, root_ui, widgets::Checkbox},
|
||||
window::{screen_height, screen_width},
|
||||
};
|
||||
use tokio::sync::mpsc::{Receiver, error::TryRecvError::Disconnected};
|
||||
|
||||
use crate::{
|
||||
logic::board::board_view::BoardView,
|
||||
network::{
|
||||
client::Client, message::ServerMessage, network_identity::NetworkIdentity,
|
||||
server::ServerStage,
|
||||
},
|
||||
ui::{macroquad::game::chat::Chat, state::GameContext},
|
||||
};
|
||||
|
||||
pub struct GameClient {
|
||||
cmd_sender: Sender<GuiCommands>,
|
||||
update_receiver: Receiver<ServerMessage>,
|
||||
|
||||
identity: Option<NetworkIdentity>,
|
||||
|
||||
board: BoardView,
|
||||
player_name: String,
|
||||
enemy_name: String, // TODO! Server should give this info to us (it doesn't rn)
|
||||
|
||||
game_state: ServerStage,
|
||||
|
||||
game_area: Rect,
|
||||
game_padding: f32,
|
||||
|
||||
lobby: Lobby,
|
||||
chat: Chat,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Lobby {
|
||||
is_ready: bool,
|
||||
checkbox_pos: Vec2,
|
||||
checkbox_size: Vec2,
|
||||
}
|
||||
|
||||
pub enum GuiCommands {
|
||||
Send(String),
|
||||
|
||||
Ready,
|
||||
Unready,
|
||||
|
||||
Capture,
|
||||
Move,
|
||||
}
|
||||
|
||||
impl GameClient {
|
||||
pub fn new(mut client: Client, context: &GameContext) -> Option<Self> {
|
||||
let Some(update_receiver) = client.get_update_receiver() else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let (cmd_sender, mut cmd_recv) = mpsc::channel::<GuiCommands>(10);
|
||||
|
||||
std::thread::spawn(|| {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap(); // i dont like this
|
||||
|
||||
rt.block_on(async move {
|
||||
loop {
|
||||
match cmd_recv.recv().await {
|
||||
Some(cmd) => match cmd {
|
||||
GuiCommands::Send(content) => {
|
||||
client.send_text_message(content).await;
|
||||
}
|
||||
|
||||
GuiCommands::Ready => {
|
||||
client.signal_readiness().await;
|
||||
}
|
||||
|
||||
GuiCommands::Unready => {
|
||||
client.revoke_readiness().await;
|
||||
}
|
||||
GuiCommands::Capture => todo!(),
|
||||
GuiCommands::Move => todo!(),
|
||||
},
|
||||
|
||||
None => {
|
||||
error!("Connection with cmd thread broken");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let board = BoardView::default();
|
||||
|
||||
let game_stage = ServerStage::default();
|
||||
let mut lobby = Lobby::default();
|
||||
lobby.checkbox_size = vec2(32.0, 16.0);
|
||||
|
||||
let game_area = Rect {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
w: screen_width() * 0.8,
|
||||
h: screen_height(),
|
||||
};
|
||||
let game_padding = 25.0;
|
||||
|
||||
let chat = Chat::default();
|
||||
|
||||
Some(Self {
|
||||
cmd_sender,
|
||||
update_receiver,
|
||||
identity: None,
|
||||
|
||||
board,
|
||||
lobby,
|
||||
|
||||
player_name: "Morbius".to_string(),
|
||||
enemy_name: "Milo".to_string(),
|
||||
|
||||
game_state: game_stage,
|
||||
|
||||
game_area,
|
||||
game_padding,
|
||||
|
||||
chat,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn draw(&mut self) {
|
||||
match self.game_state {
|
||||
ServerStage::Lobby => {
|
||||
self.draw_lobby();
|
||||
}
|
||||
|
||||
ServerStage::Game => {
|
||||
self.draw_game();
|
||||
}
|
||||
|
||||
ServerStage::End => {
|
||||
self.draw_summary_screen();
|
||||
}
|
||||
}
|
||||
self.chat.draw();
|
||||
}
|
||||
|
||||
fn draw_lobby(&mut self) {
|
||||
let lobby = &self.lobby;
|
||||
|
||||
let background_x = lobby.checkbox_size.x * 10.0;
|
||||
let background_y = lobby.checkbox_size.y * 10.0;
|
||||
|
||||
draw_rectangle(
|
||||
lobby.checkbox_pos.x - background_x * 0.5,
|
||||
lobby.checkbox_pos.y - background_y * 0.5,
|
||||
background_x,
|
||||
background_y,
|
||||
GRAY,
|
||||
);
|
||||
|
||||
let before_click: bool = self.lobby.is_ready;
|
||||
Checkbox::new(hash!())
|
||||
.pos(self.lobby.checkbox_pos)
|
||||
.label("Ready")
|
||||
.size(self.lobby.checkbox_size)
|
||||
.ui(&mut root_ui(), &mut self.lobby.is_ready);
|
||||
|
||||
if before_click != self.lobby.is_ready {
|
||||
if self.lobby.is_ready {
|
||||
let _ = self.cmd_sender.try_send(GuiCommands::Ready); // TODO! Maybe handle failure
|
||||
// or something
|
||||
} else {
|
||||
let _ = self.cmd_sender.try_send(GuiCommands::Unready);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_game(&self) {
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn draw_summary_screen(&self) {
|
||||
todo!();
|
||||
}
|
||||
|
||||
/* === UPDATING STUFF ==== */
|
||||
|
||||
pub fn update(&mut self) {
|
||||
self.update_rects();
|
||||
self.update_network();
|
||||
|
||||
match self.game_state {
|
||||
ServerStage::Lobby => self.update_lobby(),
|
||||
ServerStage::Game => todo!(),
|
||||
ServerStage::End => todo!(),
|
||||
}
|
||||
|
||||
for key in get_keys_pressed() {
|
||||
match key {
|
||||
KeyCode::Enter => {
|
||||
self.chat.send_message(self.cmd_sender.clone()); // not sure about cloning this
|
||||
// every message sent. Maybe
|
||||
// Chat should have it's own
|
||||
// clone?
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_network(&mut self) {
|
||||
match self.update_receiver.try_recv() {
|
||||
Ok(msg) => match msg {
|
||||
ServerMessage::GameStart { identity } => {
|
||||
info!("We go identity!");
|
||||
self.identity = Some(identity);
|
||||
}
|
||||
|
||||
ServerMessage::AvailableCaptures { captures } => todo!(),
|
||||
ServerMessage::AvailableMoves { moves } => todo!(),
|
||||
ServerMessage::BroadcastBoardState { board } => todo!(),
|
||||
ServerMessage::BroadcastCurrentTurn { active_player } => todo!(),
|
||||
ServerMessage::BroadCastTextMessage { sender, content } => {
|
||||
debug!("Got message from: {} with content: {}", sender, content);
|
||||
self.chat.push_message(sender, content);
|
||||
}
|
||||
|
||||
ServerMessage::GameEnd { result } => todo!(),
|
||||
|
||||
_ => {} // ignore things that network client handled by itself
|
||||
},
|
||||
|
||||
Err(Disconnected) => {
|
||||
error!("Connection broken!!!!");
|
||||
}
|
||||
|
||||
Err(_) => {} // No messages - nothing wrong (why is this even an error)
|
||||
}
|
||||
}
|
||||
|
||||
fn update_lobby(&mut self) {
|
||||
self.lobby.checkbox_pos = vec2(
|
||||
self.game_area.w / 2.0 - self.lobby.checkbox_size.x / 2.0,
|
||||
self.game_area.h / 2.0,
|
||||
);
|
||||
}
|
||||
|
||||
fn update_rects(&mut self) {
|
||||
self.game_area = Rect {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
w: screen_width() * 0.8,
|
||||
h: screen_height(),
|
||||
};
|
||||
|
||||
self.chat.update(&self.game_area);
|
||||
}
|
||||
}
|
||||
2
src/ui/macroquad/game/mod.rs
Normal file
2
src/ui/macroquad/game/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
mod chat;
|
||||
pub mod game;
|
||||
Reference in New Issue
Block a user