use std::{collections::BTreeSet, sync::Arc};
use gled_gpu::{layout::LampLayout, render_to_output::positions::Positions};
use gled_model::asset::{group::Group, svg::Svg};
use gled_svg::{ParsedSvg, measurement_point::MeasurementPoints};
#[derive(Debug, Default)]
pub(crate) struct ClientLayout {
svg: Option<Arc<str>>,
points: Arc<MeasurementPoints>,
generation: u64,
groups: Arc<Vec<Group>>,
universes: Arc<BTreeSet<u16>>,
}
impl ClientLayout {
pub(crate) fn update(&mut self, svg: Option<&Svg>) -> bool {
let contents = svg.map(|svg| svg.contents().clone());
let unchanged = match (&self.svg, &contents) {
(Some(old), Some(new)) => Arc::ptr_eq(old, new) || old == new,
(None, None) => true,
_ => false,
};
if unchanged {
return false;
}
self.svg = contents;
self.generation += 1;
self.points = Arc::default();
self.groups = Arc::default();
self.universes = Arc::default();
if let Some(svg) = self
.svg
.as_deref()
.and_then(|contents| ParsedSvg::parse(contents).ok())
{
let points = MeasurementPoints::from(&svg);
self.groups = Arc::new(points.groups());
self.universes = Arc::new(points.universes());
self.points = Arc::new(points);
}
true
}
pub(crate) fn generation(&self) -> u64 {
self.generation
}
pub(crate) fn groups(&self) -> &Arc<Vec<Group>> {
&self.groups
}
pub(crate) fn universes(&self) -> &Arc<BTreeSet<u16>> {
&self.universes
}
}
impl LampLayout for ClientLayout {
fn positions(&self, group: &Group) -> Positions {
self.points.positions(group)
}
fn preview_positions(&self) -> Positions {
self.points.preview_positions()
}
}