Skip to main content

gled_protocol/
message.rs

1//! The messages of a connection between a remote user interface and the
2//! engine, over a WebSocket. The interface opens with `Hello`; the server
3//! answers `Welcome` or `Rejected`, then sends the state whenever it changes.
4
5use std::sync::Arc;
6
7use gled_model::input::event::InputEvent;
8use gled_model::timing::BeatState;
9use serde::{Deserialize, Serialize};
10
11use crate::assets::{AnyAsset, AssetChanges};
12use crate::bytes::SharedBytes;
13use crate::midi::MidiMonitorEvent;
14use crate::project_update::ProjectUpdate;
15use crate::state::{ClientInput, EngineEvent, EngineState, RenderStats, SoundSnapshot};
16
17/// Changes whenever a message changes incompatibly. Both ends must agree.
18///
19/// 2: the patch replaced the SVG and the groups (`ProjectUpdate::Changed`,
20/// `UiAction::SetProjectPatch`, `SetSceneEffectLayout`).
21/// 3: pictures travel through the engine (`ClientInput::SavePicture`,
22/// `RequestPicture`, `EngineEvent::Picture`).
23/// 4: controllers select rows and columns (`UiAction::SelectSceneRowRelative`,
24/// `SelectSceneColumnRelative`, `EngineState::controller_line`) and switch
25/// modes (`UiAction::SetMidiMode`, `EngineState::midi_modes`,
26/// `last_mode_switch`) and show touched faders (`UiAction::SetTouchedControl`,
27/// `EngineState::touched_controls`, `midi_inputs`); controller mappings have
28/// modes, touch notes and default devices.
29/// 5: controller mappings name their controls (`MidiControllerMapping::controls`)
30/// and beat lights can pulse on every beat (`BeatFlankPulse::every_beat`).
31pub const PROTOCOL_VERSION: u32 = 5;
32
33/// The optional streams an interface can ask for. All are off until it
34/// subscribes, so a hidden page costs nothing.
35#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
36#[serde(default)]
37pub struct Subscriptions {
38    pub preview: bool,
39    pub sound: bool,
40    /// New input events (keys, gamepad, Art-Net), for assigning inputs.
41    pub input_events: bool,
42    /// The MIDI monitor and the messages MIDI learn captured.
43    pub midi: bool,
44}
45
46/// From a user interface to the server.
47#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
48pub enum ClientMessage {
49    Hello {
50        protocol_version: u32,
51        /// The interface's gled version, for the logs.
52        app_version: String,
53    },
54    Input(ClientInput),
55    /// Which of the optional streams this interface wants.
56    Subscribe(Subscriptions),
57    /// Asks for a `Pong` with the same number, to measure the round trip.
58    Ping(u64),
59}
60
61/// From the server to a user interface.
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
63pub enum ServerMessage {
64    Welcome {
65        client_id: u64,
66        /// The server's gled version.
67        app_version: String,
68    },
69    /// The connection is closed after this.
70    Rejected {
71        reason: String,
72    },
73    State {
74        state: Arc<EngineState>,
75        /// The number of the newest action of this interface applied.
76        applied_sequence: u64,
77    },
78    /// What changed since the last `State` or `Update`: the state without
79    /// its project, which comes as a patch.
80    Update {
81        /// The state with `project: None`.
82        state: Arc<EngineState>,
83        project: ProjectUpdate,
84        applied_sequence: u64,
85    },
86    /// The timing, when nothing else changed since the last `State`.
87    Timing {
88        beat: BeatState,
89        render: RenderStats,
90    },
91    /// Every asset, sent once after `Welcome`.
92    Assets(Vec<AnyAsset>),
93    /// Assets that changed since `Assets` or the last `AssetsChanged`.
94    AssetsChanged(AssetChanges),
95    /// The LED output as rendered, for the preview: three bytes per lamp,
96    /// 512 bytes per universe in the order of `OutputConfig::universes`.
97    /// Only sent to interfaces that subscribed to it.
98    Preview(SharedBytes),
99    /// Sound levels, at most 30 times a second, to interfaces that subscribed.
100    Sound(Arc<SoundSnapshot>),
101    /// Input events that happened since the last of these, to interfaces
102    /// that subscribed.
103    InputEvents(Vec<InputEvent>),
104    /// MIDI traffic since the last of these, to interfaces that subscribed.
105    MidiMonitor(Vec<MidiMonitorEvent>),
106    /// Messages MIDI learn captured since the last of these.
107    MidiLearn(Vec<[u8; 3]>),
108    Event(EngineEvent),
109    Pong(u64),
110}