Skip to main content

sim_lib_view/
embed.rs

1//! Scene embedding: one lens hosting another lens's Scene.
2//!
3//! Composition is a `scene/embed` node wrapping a nested Scene produced by
4//! another lens. A host lens can therefore render a value through a different
5//! lens and place the result inside its own Scene without flattening or
6//! duplicating it.
7
8use sim_kernel::{Cx, Expr, Result, Symbol};
9use sim_lib_scene::node;
10
11use crate::dispatch::LensRegistry;
12
13/// Wrap an already-rendered `inner` Scene in a `scene/embed` node, recording the
14/// lens that produced it.
15pub fn embed_scene(lens_id: &Symbol, inner: Expr) -> Expr {
16    node(
17        "embed",
18        vec![("lens", Expr::Symbol(lens_id.clone())), ("scene", inner)],
19    )
20}
21
22impl LensRegistry {
23    /// Render `value` through the named view lens and return it wrapped in a
24    /// `scene/embed` node, ready to nest inside a host lens's Scene.
25    pub fn render_embedded(&self, cx: &mut Cx, lens_id: &Symbol, value: &Expr) -> Result<Expr> {
26        let inner = self.render(cx, lens_id, value)?;
27        Ok(embed_scene(lens_id, inner))
28    }
29}