firecore_battle/
endpoint.rs1use crate::message::{ClientMessage, ServerMessage};
2
3pub trait BattleEndpoint<ID, T> {
5 fn send(&mut self, message: ServerMessage<ID, T>);
6
7 fn receive(&mut self) -> Result<ClientMessage<ID>, Option<ReceiveError>>;
8}
9
10#[derive(Debug)]
11pub enum ReceiveError {
12 Disconnected,
13}
14
15#[cfg(feature = "mpsc_endpoint")]
16pub use mpsc::*;
17
18#[cfg(feature = "mpsc_endpoint")]
19mod mpsc {
20
21 use crossbeam_channel::{unbounded, Receiver, Sender, TryRecvError};
22
23 use crate::message::{ClientMessage, ServerMessage};
24
25 use super::{BattleEndpoint, ReceiveError};
26
27 pub fn create<ID, T>() -> (MpscClient<ID, T>, MpscEndpoint<ID, T>) {
28 let (serv_sender, receiver) = unbounded();
29 let (sender, serv_receiver) = unbounded();
30
31 (
32 MpscClient { sender, receiver },
33 MpscEndpoint {
34 receiver: serv_receiver,
35 sender: serv_sender,
36 },
37 )
38 }
39
40 #[derive(Clone)]
41 pub struct MpscClient<ID, T> {
42 pub sender: Sender<ClientMessage<ID>>,
43 pub receiver: Receiver<ServerMessage<ID, T>>,
44 }
45
46 #[derive(Clone)]
47 pub struct MpscEndpoint<ID, T> {
48 pub receiver: Receiver<ClientMessage<ID>>,
49 pub sender: Sender<ServerMessage<ID, T>>,
50 }
51
52 impl<ID, T> MpscClient<ID, T> {
53 pub fn send(&self, message: ClientMessage<ID>) {
54 if let Err(err) = self.sender.try_send(message) {
55 log::error!("AI cannot send client message with error {}", err);
56 }
57 }
58 }
59
60 impl<ID, T> BattleEndpoint<ID, T> for MpscEndpoint<ID, T> {
61 fn send(&mut self, message: ServerMessage<ID, T>) {
62 if let Err(err) = self.sender.try_send(message) {
63 log::error!("Cannot send server message to AI with error {}", err);
64 }
65 }
66
67 fn receive(&mut self) -> Result<ClientMessage<ID>, Option<ReceiveError>> {
68 match self.receiver.try_recv() {
69 Ok(m) => Ok(m),
70 Err(err) => Err(match err {
71 TryRecvError::Empty => None,
72 TryRecvError::Disconnected => Some(ReceiveError::Disconnected),
73 }),
74 }
75 }
76 }
77}