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 {
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())
}
}