Skip to main content

molgfx_render/engine/chunk_placement/
relations.rs

1use super::{ChunkPlacementError, ChunkPlacementId};
2use molgfx_core::{ChunkVisualDescriptor, RelationStyle, ResidencyTicket, VisualCompatibility};
3use std::sync::Arc;
4
5/// Declarative rendering of one globally anchored resident relation chunk.
6#[derive(Clone, Debug, PartialEq)]
7pub struct RelationChunkPlacement {
8    id: ChunkPlacementId,
9    ticket: ResidencyTicket,
10    style: RelationStyle,
11    visual: Option<Arc<ChunkVisualDescriptor>>,
12}
13
14impl RelationChunkPlacement {
15    /// Creates one relation occurrence with a purely visual fallback style.
16    ///
17    /// # Errors
18    ///
19    /// Rejects non-positive widths and opacity outside the closed unit range.
20    pub fn new(
21        id: ChunkPlacementId,
22        ticket: ResidencyTicket,
23        style: RelationStyle,
24    ) -> Result<Self, ChunkPlacementError> {
25        if !style.width_pixels.is_finite()
26            || style.width_pixels <= 0.0
27            || !style.opacity.is_finite()
28            || !(0.0..=1.0).contains(&style.opacity)
29            || style
30                .endpoint_insets_pixels
31                .iter()
32                .any(|value| !value.is_finite() || *value < 0.0)
33        {
34            return Err(ChunkPlacementError::InvalidRelationStyle);
35        }
36        Ok(Self {
37            id,
38            ticket,
39            style,
40            visual: None,
41        })
42    }
43
44    /// Attaches a typed scene-independent visual program and exact columns.
45    ///
46    /// # Errors
47    ///
48    /// Rejects outputs unsupported by analytic relation glyphs.
49    pub fn with_visual(
50        mut self,
51        visual: Arc<ChunkVisualDescriptor>,
52    ) -> Result<Self, ChunkPlacementError> {
53        visual
54            .style()
55            .program()
56            .validate_compatibility(VisualCompatibility::RELATIONS)
57            .map_err(|_| ChunkPlacementError::InvalidRelationVisual)?;
58        self.visual = Some(visual);
59        Ok(self)
60    }
61
62    /// Stable caller-owned relation occurrence.
63    #[must_use]
64    pub const fn id(&self) -> ChunkPlacementId {
65        self.id
66    }
67
68    /// Exact relation payload generation.
69    #[must_use]
70    pub const fn ticket(&self) -> ResidencyTicket {
71        self.ticket
72    }
73
74    /// Batch-wide visual fallback used without a paged descriptor.
75    #[must_use]
76    pub const fn style(&self) -> RelationStyle {
77        self.style
78    }
79
80    /// Optional typed visual descriptor sharing immutable program storage.
81    #[must_use]
82    pub const fn visual(&self) -> Option<&Arc<ChunkVisualDescriptor>> {
83        self.visual.as_ref()
84    }
85}