base2020/src/net/agent.rs

74 lines
2.1 KiB
Rust

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<Item = Result<ClientMessage, Error>>
+ Sink<ServerMessage, Error = Error>
+ 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
}
}