1use std::rc::{Rc, Weak};
2use_RefCell!();
3
4use pax_runtime_api::{use_RefCell, ImplToFromPaxAny, Numeric, Property};
5
6use crate::api::Layer;
7use crate::{
8 BaseInstance, ExpandedNode, InstanceFlags, InstanceNode, InstantiationArgs, RuntimeContext,
9};
10
11pub struct SlotInstance {
22 base: BaseInstance,
23}
24
25impl ImplToFromPaxAny for Slot {}
26
27#[derive(Default)]
29pub struct Slot {
30 pub index: Property<Numeric>,
32 pub last_node_id: Property<usize>,
33 pub showing_node: Property<Weak<ExpandedNode>>,
35}
36
37impl InstanceNode for SlotInstance {
38 fn instantiate(args: InstantiationArgs) -> Rc<Self>
39 where
40 Self: Sized,
41 {
42 Rc::new(Self {
43 base: BaseInstance::new(
44 args,
45 InstanceFlags {
46 invisible_to_slot: false,
47 invisible_to_raycasting: true,
48 layer: Layer::DontCare,
49 is_component: false,
50 is_slot: true,
51 },
52 ),
53 })
54 }
55
56 fn handle_mount(
57 self: Rc<Self>,
58 expanded_node: &Rc<ExpandedNode>,
59 context: &Rc<RuntimeContext>,
60 ) {
61 let weak_ref_self = Rc::downgrade(expanded_node);
62 let cloned_context = Rc::clone(context);
63
64 let containing = expanded_node.containing_component.upgrade();
65 let containing = &containing
66 .as_ref()
67 .expect("slot to have a containing component");
68
69 let nodes = containing.expanded_and_flattened_slot_children.clone();
70 let listener = containing.slot_child_attached_listener.clone();
71
72 let index = expanded_node
73 .with_properties_unwrapped(|properties: &mut Slot| properties.index.clone());
74 let deps = vec![index.untyped(), nodes.untyped()];
75
76 expanded_node
77 .children
78 .replace_with(Property::computed_with_name(
79 move || {
80 let Some(cloned_expanded_node) = weak_ref_self.upgrade() else {
81 panic!("ran evaluator after expanded node dropped (repeat elem)")
82 };
83 let node_rc =
84 nodes.read(|nodes| nodes.get(index.get().to_int() as usize).cloned());
85 let node = match &node_rc {
86 Some(rc) => Rc::downgrade(rc),
87 None => Weak::new(),
88 };
89 let ret = cloned_expanded_node.attach_children(
90 node.upgrade().as_slice().to_vec(),
91 &cloned_context,
92 &cloned_expanded_node.parent_frame,
93 );
94 listener.set(());
95 ret
96 },
97 &deps,
98 &format!("slot_children (node id: {})", expanded_node.id.0),
99 ));
100 }
101
102 fn resolve_debug(
103 &self,
104 f: &mut std::fmt::Formatter,
105 _expanded_node: Option<&ExpandedNode>,
106 ) -> std::fmt::Result {
107 f.debug_struct("Slot").finish()
108 }
109
110 fn base(&self) -> &BaseInstance {
111 &self.base
112 }
113}