nimble_steps/
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 flood_rs::prelude::*;
6use std::collections::VecDeque;
7use std::io;
8use tick_id::TickId;
9
10pub mod pending_steps;
11
12#[derive(Debug)]
13pub struct GenericOctetStep {
14    pub payload: Vec<u8>,
15}
16
17impl Serialize for GenericOctetStep {
18    fn serialize(&self, stream: &mut impl WriteOctetStream) -> io::Result<()>
19    where
20        Self: Sized,
21    {
22        stream.write_u8(self.payload.len() as u8)?;
23        stream.write(self.payload.as_slice())
24    }
25}
26
27impl Deserialize for GenericOctetStep {
28    fn deserialize(stream: &mut impl ReadOctetStream) -> io::Result<Self>
29    where
30        Self: Sized,
31    {
32        let len = stream.read_u8()? as usize;
33        let mut payload = vec![0u8; len];
34        stream.read(&mut payload)?;
35        Ok(Self { payload })
36    }
37}
38
39#[derive(Debug, Clone, Eq, PartialEq)]
40pub struct JoinedData {
41    pub tick_id: TickId,
42}
43
44impl Serialize for JoinedData {
45    fn serialize(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
46        stream.write_u32(self.tick_id.0)
47    }
48}
49
50impl Deserialize for JoinedData {
51    fn deserialize(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
52        Ok(Self {
53            tick_id: TickId(stream.read_u32()?),
54        })
55    }
56}
57
58#[derive(Debug, Clone, Eq, PartialEq)] // Clone is needed since it can be in collections (like pending steps queue), Eq and PartialEq is to be able to use in tests, Debug for debug output.
59pub enum Step<T> {
60    Forced,
61    WaitingForReconnect,
62    Joined(JoinedData),
63    Left,
64    Custom(T),
65}
66
67impl<T> Step<T> {
68    #[must_use]
69    pub fn to_octet(&self) -> u8 {
70        match self {
71            Step::Forced => 0x01,
72            Step::WaitingForReconnect => 0x02,
73            Step::Joined(_) => 0x03,
74            Step::Left => 0x04,
75            Step::Custom(_) => 0x05,
76        }
77    }
78}
79
80impl<T: Serialize> Serialize for Step<T> {
81    fn serialize(&self, stream: &mut impl WriteOctetStream) -> io::Result<()> {
82        stream.write_u8(self.to_octet())?;
83        match self {
84            Step::Joined(join) => join.serialize(stream),
85            Step::Custom(custom) => custom.serialize(stream),
86            _ => Ok(()),
87        }
88    }
89}
90
91impl<T: Deserialize> Deserialize for Step<T> {
92    fn deserialize(stream: &mut impl ReadOctetStream) -> io::Result<Self> {
93        let step_type = stream.read_u8()?;
94        let t = match step_type {
95            0x01 => Step::Forced,
96            0x02 => Step::WaitingForReconnect,
97            0x03 => Step::Joined(JoinedData::deserialize(stream)?),
98            0x04 => Step::Left,
99            0x05 => Step::Custom(T::deserialize(stream)?),
100            _ => Err(io::Error::new(
101                io::ErrorKind::InvalidInput,
102                "invalid input, unknown step type",
103            ))?,
104        };
105        Ok(t)
106    }
107}
108
109#[derive(Debug, PartialEq, Clone)]
110pub struct StepInfo<T> {
111    pub step: T,
112    pub tick_id: TickId,
113}
114
115#[derive(Default, Debug)]
116pub struct Steps<T> {
117    steps: VecDeque<StepInfo<T>>,
118    expected_read_id: TickId,
119    expected_write_id: TickId,
120}
121
122impl<T> Steps<T> {
123    pub fn iter(&self) -> impl Iterator<Item = &StepInfo<T>> {
124        self.steps.iter()
125    }
126}
127
128pub struct FromIndexIterator<'a, T> {
129    deque: &'a VecDeque<StepInfo<T>>,
130    #[allow(unused)]
131    start_index: usize,
132    current_index: usize,
133}
134
135impl<'a, T> FromIndexIterator<'a, T> {
136    pub fn new(deque: &'a VecDeque<StepInfo<T>>, start_index: usize) -> Self {
137        Self {
138            deque,
139            start_index,
140            current_index: start_index,
141        }
142    }
143}
144
145impl<StepType: Clone> Iterator for FromIndexIterator<'_, StepType> {
146    type Item = StepInfo<StepType>;
147
148    fn next(&mut self) -> Option<Self::Item> {
149        let item = self.deque.get(self.current_index)?;
150        self.current_index += 1;
151        Some(item.clone())
152    }
153}
154
155pub const TICK_ID_MAX: u32 = u32::MAX;
156
157impl<StepType> Steps<StepType> {
158    pub fn new() -> Self {
159        Self {
160            steps: VecDeque::new(),
161            expected_read_id: TickId::new(0),
162            expected_write_id: TickId::new(0),
163        }
164    }
165
166    pub fn clear(&mut self) {
167        self.steps.clear();
168        self.expected_read_id = TickId(0);
169        self.expected_write_id = TickId(0);
170    }
171
172    pub fn new_with_initial_tick(initial_tick_id: TickId) -> Self {
173        Self {
174            steps: VecDeque::new(),
175            expected_read_id: initial_tick_id,
176            expected_write_id: initial_tick_id,
177        }
178    }
179
180    pub fn push(&mut self, step: StepType) {
181        let info = StepInfo {
182            step,
183            tick_id: self.expected_write_id,
184        };
185        self.steps.push_back(info);
186        self.expected_write_id += 1;
187    }
188
189    pub fn debug_get(&self, index: usize) -> Option<&StepInfo<StepType>> {
190        self.steps.get(index)
191    }
192
193    pub fn pop(&mut self) -> Option<StepInfo<StepType>> {
194        let info = self.steps.pop_front();
195        if let Some(ref step_info) = info {
196            assert_eq!(step_info.tick_id, self.expected_read_id);
197            self.expected_read_id += 1;
198        }
199        info
200    }
201
202    pub fn pop_up_to(&mut self, tick_id: TickId) {
203        while let Some(info) = self.steps.front() {
204            if info.tick_id >= tick_id {
205                break;
206            }
207
208            self.steps.pop_front();
209        }
210    }
211
212    pub fn pop_count(&mut self, count: usize) {
213        if count >= self.steps.len() {
214            self.steps.clear();
215        } else {
216            self.steps.drain(..count);
217        }
218    }
219
220    pub fn front_tick_id(&self) -> Option<TickId> {
221        self.steps.front().map(|step_info| step_info.tick_id)
222    }
223
224    pub fn back_tick_id(&self) -> Option<TickId> {
225        self.steps.back().map(|step_info| step_info.tick_id)
226    }
227
228    pub fn len(&self) -> usize {
229        self.steps.len()
230    }
231
232    pub fn is_empty(&self) -> bool {
233        self.steps.is_empty()
234    }
235
236    pub fn iter_index(&self, start_index: usize) -> FromIndexIterator<StepType> {
237        FromIndexIterator::new(&self.steps, start_index)
238    }
239}