gled-model 2.32.1

The data model of gled: projects, scenes, effects, animations, curves and assets
Documentation
//! Input and output settings stored with a project: Art-Net input and
//! bridging, the Art-Net control universe, OSC, and fixed channel values.

use std::collections::BTreeMap;

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

use crate::{
    asset::output_device::{OutputDevice, routing::OutputRouting},
    asset_id::AssetId,
};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct ArtnetConfig {
    pub universe: u16,
    #[serde(deserialize_with = "crate::serde_helpers::deserialize_u16_index_btreemap")]
    pub bridge: BTreeMap<u16, Bridge>,
    pub artnet_control_config: ArtnetControlConfig,
}

#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct Bridge {
    pub last_data_at: DateTime<Utc>,
    pub updates: usize,
    pub output_routing: OutputRouting,
    pub htp: bool,
}

impl Default for ArtnetConfig {
    fn default() -> Self {
        Self {
            universe: 18,
            bridge: Default::default(),
            artnet_control_config: ArtnetControlConfig::default(),
        }
    }
}

#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq)]
pub struct ArtnetControlConfig {
    pub active: bool,
    pub universe: u16,
}

impl Default for ArtnetControlConfig {
    fn default() -> Self {
        Self {
            active: false,
            universe: 1337,
        }
    }
}

#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq)]
#[serde(default)]
pub struct OscConfig {
    pub active: bool,
    pub port: u16,
}

impl Default for OscConfig {
    fn default() -> Self {
        Self {
            active: false,
            port: 8000,
        }
    }
}

#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
pub struct ChannelOverwrites(
    #[serde(with = "serde_channel_overwrites_map")] pub BTreeMap<ChannelIdentifier, u8>,
);

impl ChannelOverwrites {
    /// Overwrite data for given device/universe tuple.
    /// Removes the entry from the channel overwrites so we know which universes we need to send extra
    pub fn overwrite_data(
        &mut self,
        device: AssetId<OutputDevice>,
        universe: Option<u16>,
        data: &mut [u8],
    ) {
        self.0.retain(|channel_identifier, value| {
            if channel_identifier.device == device && channel_identifier.universe == universe {
                data[channel_identifier.channel as usize - 1] = *value;
                false
            } else {
                true
            }
        });
    }

    pub fn overwritten_universes(self) -> Vec<(OutputRouting, [u8; 512])> {
        let mut overwritten_universes = BTreeMap::new();
        for (channel_identifier, value) in self.0.into_iter() {
            overwritten_universes
                .entry(OutputRouting {
                    device: Some(channel_identifier.device),
                    universe: channel_identifier.universe,
                })
                .or_insert([0; 512])[channel_identifier.channel as usize - 1] = value;
        }
        overwritten_universes.into_iter().collect()
    }
}

#[derive(
    Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, serde::Deserialize, serde::Serialize,
)]
pub struct ChannelIdentifier {
    pub device: AssetId<OutputDevice>,
    pub universe: Option<u16>,
    pub channel: u16,
}

mod serde_channel_overwrites_map {
    use super::ChannelIdentifier;
    use serde::{Deserialize, Deserializer, Serialize, Serializer};
    use std::collections::BTreeMap;

    pub(crate) fn serialize<S>(
        map: &BTreeMap<ChannelIdentifier, u8>,
        serializer: S,
    ) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let vec: Vec<(&ChannelIdentifier, &u8)> = map.iter().collect();
        vec.serialize(serializer)
    }

    pub(crate) fn deserialize<'de, D>(
        deserializer: D,
    ) -> Result<BTreeMap<ChannelIdentifier, u8>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let vec: Vec<(ChannelIdentifier, u8)> = Vec::deserialize(deserializer)?;
        Ok(vec.into_iter().collect())
    }
}