use super::mark::{Drawing, MarkKind, Style, mark, style_methods};
use crate::expr::compile::{Compiler, Store};
use crate::gpu::shaders as wgsl;
use crate::{Error, Name, Result};
mark!(
Faces {
corners: Option<[Name; 3]> as "[a: string, b: string, c: string]",
});
impl Faces {
pub fn of(data: impl Into<Name>, table: impl Into<Name>) -> Faces {
Faces { style: Style::new(data.into(), table.into()), corners: None }
}
#[must_use]
pub fn corners(mut self, a: impl Into<Name>, b: impl Into<Name>, c: impl Into<Name>) -> Faces {
self.corners = Some([a.into(), b.into(), c.into()]);
self
}
pub(crate) fn compile(&self, c: &mut Compiler<'_>) -> Result<Drawing> {
let Some(corners) = &self.corners else {
return Err(Error::invalid("name the reference fields of each row's three corners").at("corners"));
};
for (corner, word) in corners.iter().zip([wgsl::FACE_A, wgsl::FACE_B, wgsl::FACE_C]) {
c.end(corner, word).map_err(|e| e.at("corners"))?;
}
let mut flags = 0;
match &self.style.color {
Some(expr) => {
c.channel("color", expr, Store::Color { word: wgsl::FACE_COLOR, fallback: wgsl::THEME_VERTEX })?;
}
None => flags |= wgsl::ENDS_COLOR,
}
c.channel("visible", &self.style.visible, Store::Flag { word: wgsl::FACE_FLAGS, bit: wgsl::VISIBLE })?;
let mut drawing = Drawing::new(MarkKind::Faces, wgsl::FACE_WORDS);
drawing.flags = flags;
Ok(drawing)
}
}
style_methods!(Faces);