use anyhow::{Error, Result}; use futures::{channel::mpsc::*, prelude::*, Stream}; use super::server::Handle; use super::*; pub struct ClientAgent { server: Handle, player_id: PlayerId, } impl ClientAgent { pub fn new(server: Handle) -> ClientAgent { ClientAgent { server, player_id: 0, } } async fn process_message(&self, msg: ClientMessage) { trace!("Client#{} message: {:?}", self.player_id, &msg); match msg { ClientMessage::Input { local_input } => self.server.lock().await.input(self.player_id, local_input), // for now, anybody can set the state ClientMessage::SetState { new_state } => self.server.lock().await.set_state(new_state), ClientMessage::GetState { .. } => {} } } pub async fn run( &mut self, socket: &mut (impl Stream> + Sink + Send + Unpin), ) -> Result<()> { let (sender, mut receiver) = channel(CHANNEL_BUFFER); // register player self.player_id = self .server .lock() .await .add_player(sender, &self.server) .await?; // main message loop let result: Result<()> = async { loop { tokio::select! { client_message = socket.next() => { match client_message { Some(msg) => self.process_message(msg?).await, None => break Ok(()), } }, Some(server_message) = receiver.next() => { socket.send(server_message).await? }, else => break Ok(()), } } } .await; // deregister player, whether normally or due to error self.server.lock().await.remove_player(self.player_id); result } }