use crate::bfc::BfcFrame; use crate::cache::CacheKey; use crate::geom::{Point3, Transform}; use crate::model::ColourData; use crate::scanner::LineType; use crate::texmap::{TexmapAssociation, TexmapState, TextureDescriptor}; use crate::types::{Diagnostic, Span}; use smol_str::SmolStr; #[derive(Clone, Debug, PartialEq)] pub struct ColourScopeSnapshot { pub effective: crate::ColourCode, } /// A semantic parser callback. Implementations receive events while traversal /// is walking occurrences, before retained compatibility records are assembled. pub trait SemanticSink { fn on_event(&mut self, event: &SemanticEvent, context: &TraversalContext); } /// Scope and source information active at one semantic event. #[derive(Clone, Debug, PartialEq)] pub struct TraversalContext { pub composed_transform: Transform, pub colour_scope: ColourScopeSnapshot, pub bfc_frame: BfcFrame, pub texmap_state: TexmapState, pub texmap_descriptor: Option>, pub source_file_id: u32, pub source_span: Option, } impl TraversalContext { pub(crate) fn for_model( transform: Transform, colour: crate::ColourCode, bfc_frame: BfcFrame, texmap_state: TexmapState, texmap_descriptor: Option<&TextureDescriptor<'_>>, source_file_id: u32, source_span: Option, ) -> Self { Self { composed_transform: transform, colour_scope: ColourScopeSnapshot { effective: colour }, bfc_frame, texmap_state, texmap_descriptor: texmap_descriptor.map(|descriptor| TextureDescriptor { mode: descriptor.mode, parameters: descriptor .parameters .iter() .map(|value| std::borrow::Cow::Owned(value.to_string())) .collect(), pngfile: std::borrow::Cow::Owned(descriptor.pngfile.to_string()), glossmap: descriptor .glossmap .as_ref() .map(|value| std::borrow::Cow::Owned(value.to_string())), }), source_file_id, source_span, } } } /// Typed semantic callbacks emitted by parsing and occurrence traversal. #[derive(Clone, Debug, PartialEq)] pub enum SemanticEvent<'a> { ModelBoundary { name: SmolStr, root: CacheKey, }, GeometryEmitted { primitive_id: u32, source: CacheKey, span: Span, line_type: LineType, colour: crate::ColourCode, vertices: &'a [Point3], bfc: BfcFrame, texmap: Option<&'a TexmapAssociation>, inverted: bool, }, IncludeInstantiated { target: SmolStr, transform: Transform, colour: crate::ColourCode, bfc: BfcFrame, texmap: Option, }, StepBoundary, ColourDefined { code: crate::ColourCode, data: ColourData, }, TexmapTransition { kind: crate::TexmapKind, descriptor: Option>, }, DataPayload { filename: SmolStr, bytes: Vec, }, Diagnostic(Diagnostic), } #[derive(Default)] pub struct NoopSemanticSink; impl SemanticSink for NoopSemanticSink { fn on_event(&mut self, _event: &SemanticEvent<'_>, _context: &TraversalContext) {} }