gled-ui 2.32.1

gled's egui interface, shared by the desktop app and the browser
Documentation
//! Everything an interface knows of the engine, rebuilt from the messages it
//! receives. The desktop app and the browser fill it the same way; only the
//! transport differs.

use std::sync::Arc;

use gled_model::input::event::InputEvent;
use gled_protocol::{
    message::ServerMessage,
    midi::MidiMonitorEvent,
    replica::StateReplica,
    state::{EngineEvent, SoundSnapshot},
};

#[derive(Debug, Default)]
pub(crate) struct ClientModel {
    /// The engine's state and assets.
    pub(crate) replica: StateReplica,
    pub(crate) sound: Arc<SoundSnapshot>,
    /// The newest preview frame not yet shown.
    pub(crate) preview: Option<Arc<Vec<u8>>>,
    /// Engine events not yet handled.
    pub(crate) events: Vec<EngineEvent>,
    /// Input events that arrived since they were last taken, for assigning
    /// inputs.
    pub(crate) input_events: Vec<InputEvent>,
    /// MIDI traffic not yet shown in the monitor.
    pub(crate) midi_monitor: Vec<MidiMonitorEvent>,
    /// Messages captured for MIDI learn, not yet looked at.
    pub(crate) midi_learn: Vec<[u8; 3]>,
    /// The server's version, once it welcomed this interface.
    pub(crate) server_version: Option<String>,
    /// Set when the state changed since the flag was last cleared.
    pub(crate) state_changed: bool,
    /// Set when the server welcomed this interface, which starts a new
    /// session: action numbers start over.
    pub(crate) welcomed: bool,
}

impl ClientModel {
    pub(crate) fn apply(&mut self, message: ServerMessage) {
        match message {
            ServerMessage::Welcome { app_version, .. } => {
                self.server_version = Some(app_version);
                self.welcomed = true;
            }
            ServerMessage::Preview(output) => self.preview = Some(output.0),
            ServerMessage::Sound(sound) => self.sound = sound,
            ServerMessage::Event(event) => self.events.push(event),
            ServerMessage::InputEvents(events) => self.input_events.extend(events),
            ServerMessage::MidiMonitor(events) => self.midi_monitor.extend(events),
            ServerMessage::MidiLearn(messages) => self.midi_learn.extend(messages),
            message => {
                if self.replica.apply(&message) {
                    self.state_changed = true;
                }
            }
        }
    }
}