1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use crate::*;

struct Stream {
    reader: Box<dyn BufRead + Send>,
    writer: Box<dyn Write + Send>,
}

pub struct StreamPlayer<G: Game> {
    stream: Option<Stream>,
    phantom_data: PhantomData<G>,
}

impl<G: Game> StreamPlayer<G> {
    pub fn new(reader: Box<dyn BufRead + Send>, writer: Box<dyn Write + Send>) -> Self {
        Self {
            stream: Some(Stream { reader, writer }),
            phantom_data: PhantomData,
        }
    }
}

impl<G: Game> Drop for StreamPlayer<G> {
    fn drop(&mut self) {
        if let Some(stream) = &mut self.stream {
            let mut try_write_finish = || {
                ServerMessage::<G> { player_view: None }.write_to(&mut stream.writer)?;
                stream.writer.flush()
            };
            if let Err(e) = try_write_finish() {
                warn!("{}", e);
            }
        }
    }
}

impl<G: Game> Player<G> for StreamPlayer<G> {
    fn get_action(
        &mut self,
        player_view: &G::PlayerView,
        custom_data_handler: Option<&dyn Fn(G::CustomData)>,
    ) -> Result<G::Action, PlayerError> {
        let stream = self.stream.as_mut().expect("Called get_action after error");
        let mut get_action = move || {
            ServerMessage::<G> {
                player_view: Some(player_view.clone()), // TODO: dont clone
            }
            .write_to(&mut stream.writer)?;
            stream.writer.flush()?;
            loop {
                match PlayerMessage::<G>::read_from(&mut stream.reader)? {
                    PlayerMessage::ActionMessage { action } => return Ok(action),
                    PlayerMessage::CustomDataMessage { data } => {
                        if let Some(handler) = custom_data_handler {
                            handler(data);
                        }
                    }
                }
            }
        };
        let result = get_action();
        if result.is_err() {
            self.stream = None;
        }
        result
    }
}