lumen_engine/node/compositing/
switch.rs1use crate::node::{NodeId, NodeProperty, PortRef};
2
3use crate::gpu::{
4 BoundFrame, CompiledOutput, FrameBindContext, FrameBinding, GpuCompileNode, GpuFrameBindNode,
5};
6
7#[derive(Debug, Clone, lumen_macros::Node)]
9#[node(kind = "switch", name = "Switch", category = "compositing")]
10pub struct Switch {
11 pub id: NodeId,
12 #[property(kind = "int", name = "Selected layer", min = 0, step = 1)]
14 pub selected_layer: NodeProperty,
15 #[input(optional, variadic)]
16 pub layers: Vec<PortRef>,
17}
18
19impl Default for Switch {
20 fn default() -> Self {
21 Self {
22 id: NodeId::new(0),
23 selected_layer: NodeProperty::Int(0),
24 layers: Vec::new(),
25 }
26 }
27}
28
29pub fn selected_layer_for_frame(
30 node: &Switch,
31 ctx: &crate::expr::ExpressionContext<'_>,
32) -> crate::Result<Option<usize>> {
33 let selected = node
34 .selected_layer
35 .resolve_int(node.id, "selected_layer", ctx)?;
36 Ok((selected >= 0).then_some(selected as usize))
37}
38
39impl GpuCompileNode for Switch {
40 fn compile_gpu(
41 &self,
42 ctx: &mut crate::gpu::CompileContext<'_>,
43 port: &PortRef,
44 ) -> crate::Result<CompiledOutput> {
45 if port.port != "output" {
46 return Err(ctx.missing_output(self.id, &port.port));
47 }
48
49 let selected_layer =
50 selected_layer_for_frame(self, &ctx.expr_context(self.id, "selected_layer"))?;
51 ctx.push_frame_binding(FrameBinding::Switch {
52 node_id: self.id,
53 selected_layer,
54 });
55
56 let Some(index) = selected_layer else {
57 return Ok(ctx.compile_transparent(self.id));
58 };
59 let Some(layer) = self.layers.get(index) else {
60 return Ok(ctx.compile_transparent(self.id));
61 };
62 if layer.is_empty() {
63 return Ok(ctx.compile_transparent(self.id));
64 }
65 ctx.compile_port(layer)
66 }
67}
68
69impl GpuFrameBindNode for Switch {
70 fn bind_gpu_frame(
71 &self,
72 _ctx: &FrameBindContext<'_>,
73 binding: &FrameBinding,
74 _bound: &mut BoundFrame,
75 ) -> crate::Result<()> {
76 let FrameBinding::Switch { .. } = binding else {
77 return Ok(());
78 };
79 Ok(())
80 }
81}