Skip to main content

gled_protocol/
replica.rs

1//! What a remote interface knows of the engine, rebuilt from the server's
2//! messages.
3
4use gled_model::collection::Collections;
5
6use crate::{assets::collections_from, message::ServerMessage, state::EngineState};
7
8#[derive(Debug, Clone, Default)]
9pub struct StateReplica {
10    pub state: EngineState,
11    /// The number of the newest action of this interface the engine applied.
12    pub applied_sequence: u64,
13    /// Whether a full state has arrived; updates before it are ignored.
14    pub complete: bool,
15    /// The engine's assets.
16    pub assets: Collections,
17    /// Whether all assets have arrived; changes before them are ignored.
18    pub(crate) assets_complete: bool,
19}
20
21impl StateReplica {
22    /// Takes a message. Returns whether the state changed.
23    pub fn apply(&mut self, message: &ServerMessage) -> bool {
24        match message {
25            ServerMessage::State {
26                state,
27                applied_sequence,
28            } => {
29                self.state = EngineState::clone(state);
30                self.applied_sequence = *applied_sequence;
31                self.complete = true;
32                true
33            }
34            ServerMessage::Update {
35                state,
36                project,
37                applied_sequence,
38            } if self.complete => {
39                let mut replica_project = self.state.project.take();
40                project.clone().apply_to(&mut replica_project);
41                self.state = EngineState {
42                    project: replica_project,
43                    ..EngineState::clone(state)
44                };
45                self.applied_sequence = *applied_sequence;
46                true
47            }
48            ServerMessage::Assets(assets) => {
49                self.assets = collections_from(assets.clone());
50                self.assets_complete = true;
51                true
52            }
53            ServerMessage::AssetsChanged(changes) if self.assets_complete => {
54                changes.clone().apply_to(&mut self.assets);
55                true
56            }
57            ServerMessage::Timing { beat, render } if self.complete => {
58                self.state.beat = *beat;
59                self.state.render = *render;
60                true
61            }
62            _ => false,
63        }
64    }
65}