use std::sync::Arc; use crate::data::GameRules; use actix::prelude::*; use actix::{Actor, Context, Handler}; use uuid::Uuid; pub trait Player { fn get_name(&self) -> &str; fn get_uid(&self) -> Uuid; fn query_boats_layout(&self, rules: &GameRules); } #[derive(Default, Eq, PartialEq, Debug, Copy, Clone)] enum GameStatus { #[default] Created, WaitingForBoatsDisposition, } pub struct Game { rules: GameRules, players: Vec>, status: GameStatus, } impl Game { pub fn new(rules: GameRules) -> Self { Self { rules, players: vec![], status: GameStatus::Created, } } /// Once the two player has been registered, the game may start fn query_boats_disposition(&mut self) { assert_eq!(self.status, GameStatus::Created); self.status = GameStatus::WaitingForBoatsDisposition; self.players[0].query_boats_layout(&self.rules); self.players[1].query_boats_layout(&self.rules); } } impl Actor for Game { type Context = Context; } #[derive(Message)] #[rtype(result = "()")] pub struct AddPlayer(pub E); impl Handler>> for Game where E: Player + 'static, { type Result = (); /// Add a new player to the game fn handle(&mut self, msg: AddPlayer>, _ctx: &mut Self::Context) -> Self::Result { assert!(self.players.len() < 2); self.players.push(msg.0); if self.players.len() == 2 { self.query_boats_disposition(); } } }