lumen_engine/node/processing/
memo.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 = "memo", name = "Memo", category = "processing")]
10pub struct Memo {
11 pub id: NodeId,
12 #[property(kind = "string", name = "Cache key", role = "cache_id")]
14 pub cache_id: NodeProperty,
15 #[property(kind = "bool")]
17 pub allow_expressions: NodeProperty,
18 #[input()]
19 pub source: PortRef,
20}
21
22impl Default for Memo {
23 fn default() -> Self {
24 Self {
25 id: NodeId::new(0),
26 cache_id: NodeProperty::String(String::new()),
27 allow_expressions: NodeProperty::Bool(false),
28 source: PortRef::empty(),
29 }
30 }
31}
32
33impl GpuCompileNode for Memo {
34 fn compile_gpu(
35 &self,
36 ctx: &mut crate::gpu::CompileContext<'_>,
37 port: &PortRef,
38 ) -> crate::Result<CompiledOutput> {
39 if port.port != "output" {
40 return Err(ctx.missing_output(self.id, &port.port));
41 }
42 let source = ctx.compile_port(&self.source)?;
43 ctx.push_frame_binding(FrameBinding::Memo {
44 node_id: self.id,
45 cache_id: self.cache_id.clone(),
46 allow_expressions: self.allow_expressions.clone(),
47 });
48 Ok(source)
49 }
50}
51
52impl GpuFrameBindNode for Memo {
53 fn bind_gpu_frame(
54 &self,
55 ctx: &FrameBindContext<'_>,
56 binding: &FrameBinding,
57 _bound: &mut BoundFrame,
58 ) -> crate::Result<()> {
59 let FrameBinding::Memo {
60 node_id,
61 cache_id,
62 allow_expressions,
63 } = binding
64 else {
65 return Ok(());
66 };
67 let _ = cache_id.resolve_string(
68 *node_id,
69 "cache_id",
70 &ctx.expr_context(*node_id, "cache_id"),
71 )?;
72 let _ = allow_expressions.resolve_bool(
73 *node_id,
74 "allow_expressions",
75 &ctx.expr_context(*node_id, "allow_expressions"),
76 )?;
77 Ok(())
78 }
79}