nimble_sample_game/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/nimble-rust/nimble
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use app_version::{Version, VersionProvider};
6use flood_rs::prelude::{InOctetStream, OutOctetStream};
7use flood_rs::{BufferDeserializer, Deserialize, ReadOctetStream, Serialize, WriteOctetStream};
8use log::info;
9use nimble_assent::AssentCallback;
10use nimble_rectify::RectifyCallback;
11pub use nimble_sample_step::SampleStep;
12use nimble_seer::SeerCallback;
13use nimble_step::Step;
14use nimble_step_map::StepMap;
15use std::io;
16
17#[derive(Default, Clone, Debug, Eq, PartialEq)]
18pub struct SampleGameState {
19    pub x: i32,
20    pub y: i32,
21}
22
23impl SampleGameState {
24    pub fn update(&mut self, step: &StepMap<Step<SampleStep>>) {
25        for (participant_id, step) in step {
26            match &step {
27                Step::Custom(custom) => match custom {
28                    SampleStep::MoveLeft(amount) => self.x -= *amount as i32,
29                    SampleStep::MoveRight(amount) => self.x += *amount as i32,
30                    SampleStep::Jump => self.y += 1,
31                    SampleStep::Nothing => {}
32                },
33                Step::Forced => self.y += 1,
34                Step::WaitingForReconnect => info!("waiting for reconnect"),
35                Step::Joined(data) => info!(
36                    "participant {} joined at time {}",
37                    participant_id, data.tick_id
38                ),
39                Step::Left => info!("participant {} left", participant_id),
40            }
41        }
42    }
43
44    pub fn to_octets(&self) -> io::Result<Vec<u8>> {
45        let mut out = OutOctetStream::new();
46        out.write_i32(self.x)?;
47        out.write_i32(self.y)?;
48        Ok(out.octets())
49    }
50
51    #[allow(unused)]
52    pub fn from_octets(payload: &[u8]) -> io::Result<(Self, usize)> {
53        let mut in_stream = InOctetStream::new(payload);
54        Ok((
55            Self {
56                x: in_stream.read_i32()?,
57                y: in_stream.read_i32()?,
58            },
59            in_stream.cursor.position() as usize,
60        ))
61    }
62}
63
64impl BufferDeserializer for SampleGameState {
65    fn deserialize(buf: &[u8]) -> io::Result<(Self, usize)> {
66        let mut in_stream = InOctetStream::new(buf);
67        let s = <Self as Deserialize>::deserialize(&mut in_stream)?;
68        Ok((s, in_stream.cursor.position() as usize))
69    }
70}
71
72impl Serialize for SampleGameState {
73    fn serialize(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
74        stream.write_i32(self.x)?;
75        stream.write_i32(self.y)
76    }
77}
78
79impl Deserialize for SampleGameState {
80    fn deserialize(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
81        Ok(Self {
82            x: stream.read_i32()?,
83            y: stream.read_i32()?,
84        })
85    }
86}
87
88#[derive(Default, Clone, Debug, Eq, PartialEq)]
89pub struct SampleGame {
90    pub predicted: SampleGameState,
91    pub authoritative: SampleGameState,
92}
93
94impl SampleGame {
95    pub fn authoritative_octets(&self) -> io::Result<Vec<u8>> {
96        self.authoritative.to_octets()
97    }
98}
99
100impl BufferDeserializer for SampleGame {
101    fn deserialize(octets: &[u8]) -> io::Result<(Self, usize)> {
102        let (sample_state, size) = SampleGameState::from_octets(octets)?;
103        Ok((
104            Self {
105                predicted: sample_state.clone(),
106                authoritative: sample_state,
107            },
108            size,
109        ))
110    }
111}
112
113impl VersionProvider for SampleGame {
114    fn version() -> Version {
115        Version::new(0, 0, 5)
116    }
117}
118
119impl Serialize for SampleGame {
120    fn serialize(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
121        self.authoritative.serialize(stream)
122    }
123}
124
125impl Deserialize for SampleGame {
126    fn deserialize(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
127        let state = <SampleGameState as Deserialize>::deserialize(stream)?;
128        Ok(Self {
129            authoritative: state.clone(),
130            predicted: state,
131        })
132    }
133}
134
135impl SeerCallback<StepMap<Step<SampleStep>>> for SampleGame {
136    fn on_pre_ticks(&mut self) {}
137    fn on_tick(&mut self, step: &StepMap<Step<SampleStep>>) {
138        self.predicted.update(step);
139    }
140    fn on_post_ticks(&mut self) {}
141}
142
143impl AssentCallback<StepMap<Step<SampleStep>>> for SampleGame {
144    fn on_pre_ticks(&mut self) {}
145    fn on_tick(&mut self, step: &StepMap<Step<SampleStep>>) {
146        self.authoritative.update(step);
147    }
148    fn on_post_ticks(&mut self) {}
149}
150
151impl RectifyCallback for SampleGame {
152    fn on_copy_from_authoritative(&mut self) {
153        self.predicted = self.authoritative.clone();
154    }
155}