Skip to main content

euv_core/vdom/node/
struct.rs

1use crate::*;
2
3/// Inner storage for a dynamic node render closure.
4///
5/// Boxes a `dyn FnMut() -> VirtualNode` so it can be stored behind a raw pointer.
6/// Allocated via `Box::leak` and lives for the remainder of the program.
7#[derive(CustomDebug, Data)]
8pub(crate) struct RenderFnInner {
9    /// The boxed render closure.
10    #[debug(skip)]
11    #[get(pub(crate))]
12    #[set(pub(crate))]
13    pub(crate) render_fn: Box<dyn FnMut() -> VirtualNode>,
14}
15
16/// Represents a text node in the virtual DOM.
17///
18/// Text nodes may optionally be bound to a reactive signal for automatic updates.
19#[derive(Clone, CustomDebug, Data, New)]
20pub struct TextNode {
21    /// The text content.
22    #[get(pub(crate))]
23    #[set(pub(crate))]
24    pub(crate) content: String,
25    /// An optional signal that drives reactive text updates.
26    #[debug(skip)]
27    #[get(pub(crate))]
28    #[set(pub(crate))]
29    pub(crate) signal: Option<Signal<String>>,
30}
31
32/// A closure-based dynamic node that re-renders when its dependency signals change.
33///
34/// Holds a raw pointer to a heap-allocated render closure that produces a fresh
35/// `VirtualNode` on each evaluation. The renderer subscribes to the closure's
36/// signals and patches the DOM automatically.
37/// Contains a `HookContext` that persists hook state (like `use_signal`) across
38/// re-renders, ensuring that signal values are not reset when the render function
39/// is called again.
40///
41/// Implements `Copy` for ergonomic use; all copies share the same underlying state.
42///
43/// SAFETY: The inner pointer is allocated via `Box::leak` and lives for the
44/// entire program. This is safe in single-threaded WASM contexts where no
45/// concurrent access can occur.
46#[derive(CustomDebug, Data, Eq, PartialEq)]
47pub struct DynamicNode {
48    /// Raw pointer to the heap-allocated render closure inner state.
49    ///
50    /// SAFETY: Allocated via `Box::leak`, valid for the program lifetime.
51    #[debug(skip)]
52    #[get(pub(crate))]
53    #[set(pub(crate))]
54    pub(crate) render_fn: *mut RenderFnInner,
55    /// Persistent hook context for this dynamic node, storing signal
56    /// state and other hook values across render cycles.
57    ///
58    /// Implements `Copy`; all copies share the same underlying state.
59    /// When the `arm_changed` flag inside is toggled (by `match` arm switching),
60    /// the hooks array is cleared to prevent signal leakage between arms.
61    #[set(pub(crate))]
62    pub(crate) hook_context: HookContext,
63}