gled-core 2.30.0

The engine of gled without a user interface: inputs, timing, rendering, Art-Net/DMX output and storage
Documentation
//! The project's output settings, applied to the running output when they
//! change: channel overwrites and the Art-Net input's settings.

use gled_model::asset::project::{
    Project,
    io::{ArtnetConfig, ArtnetControlConfig, ChannelOverwrites},
};

use crate::{input::artnet::ARTNET_CONFIG, pipeline::output_sender::set_channel_overwrites};

/// The project's output settings the running output was last given. The
/// project holds them; the output threads read them from their own globals,
/// which are updated only when the project's values change.
#[derive(Debug, Default)]
pub(super) struct AppliedOutput {
    channel_overwrites: Option<ChannelOverwrites>,
    artnet: Option<(ArtnetConfig, ArtnetControlConfig)>,
}

impl AppliedOutput {
    pub(super) fn apply(&mut self, project: &Project) {
        if self.channel_overwrites.as_ref() != Some(&project.channel_overwrites) {
            set_channel_overwrites(project.channel_overwrites.clone());
            self.channel_overwrites = Some(project.channel_overwrites.clone());
        }
        let artnet = (project.artnet_config.clone(), project.artnet_control_config);
        if self.artnet.as_ref() != Some(&artnet) {
            // The running config also counts the data arriving per universe;
            // only the settings come from the project.
            let mut live = ARTNET_CONFIG.lock();
            live.universe = artnet.0.universe;
            live.artnet_control_config = artnet.1;
            for (universe, bridge) in &artnet.0.bridge {
                let running = live.bridge.entry(*universe).or_default();
                running.output_routing = bridge.output_routing.clone();
                running.htp = bridge.htp;
            }
            drop(live);
            self.artnet = Some(artnet);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::pipeline::output_sender::current_channel_overwrites;
    use gled_model::asset::project::io::{Bridge, ChannelIdentifier};

    #[test]
    fn project_output_settings_reach_the_running_output_and_keep_the_counters() {
        // Art-Net arrived on universe 3 before the project said anything.
        ARTNET_CONFIG.lock().bridge.insert(
            3,
            Bridge {
                updates: 42,
                ..Bridge::default()
            },
        );

        let mut project = Project::default();
        project.artnet_config.universe = 7;
        project.artnet_config.bridge.insert(
            3,
            Bridge {
                htp: true,
                ..Bridge::default()
            },
        );
        project.channel_overwrites.0.insert(
            ChannelIdentifier {
                device: Default::default(),
                universe: Some(1),
                channel: 5,
            },
            255,
        );

        let mut applied = AppliedOutput::default();
        applied.apply(&project);

        let live = ARTNET_CONFIG.lock().clone();
        assert_eq!(live.universe, 7);
        let bridge = live.bridge.get(&3).expect("bridged universe");
        assert!(bridge.htp);
        assert_eq!(bridge.updates, 42);
        assert_eq!(current_channel_overwrites(), project.channel_overwrites);
    }
}