pub fn spawn_tree(
ce: &MaterializedCE,
parent: Option<ComponentId>,
world: &mut World,
emit: &mut dyn SignalEmitter,
) -> Result<ComponentId, String>Expand description
Recursively spawn the component tree described by ce, attach it to parent (if any),
and initialise it. Returns the root ComponentId.
Examples found in repository?
examples/diy-panel.rs (lines 136-141)
92fn spawn_container_item_debug_clones(
93 universe: &mut engine::Universe,
94 container: engine::ecs::ComponentId,
95) {
96 use engine::ecs::IntentValue;
97 use engine::ecs::system::TransformSystem;
98 use mittens_engine::scripting::component_registry::{
99 ce_ast_to_materialized, spawn_tree, subtree_to_ce_ast,
100 };
101
102 let items = collect_container_items(&universe.world, container);
103 for (index, item) in items.into_iter().enumerate() {
104 let Some(matrix_world) = TransformSystem::world_model(&universe.world, item) else {
105 println!("[diy-panel-debug] skip {:?}: no world matrix", item);
106 continue;
107 };
108
109 let item_label = universe
110 .world
111 .component_label(item)
112 .unwrap_or("")
113 .to_string();
114 println!(
115 "[diy-panel-debug] item={} label={:?} matrix_world={:?}",
116 index, item_label, matrix_world,
117 );
118
119 // Subtree → MMS AST → MaterializedCE → fresh spawn.
120 // Same path attach_clone uses; gives the clone fresh GUIDs and
121 // routes everything through the standard component registry.
122 let Ok(ce_ast) = subtree_to_ce_ast(&universe.world, item) else {
123 println!(
124 "[diy-panel-debug] skip {:?}: failed to encode subtree",
125 item
126 );
127 continue;
128 };
129 let Ok(materialized) = ce_ast_to_materialized(&ce_ast) else {
130 println!(
131 "[diy-panel-debug] skip {:?}: failed to materialize CE",
132 item
133 );
134 continue;
135 };
136 let Ok(clone_root) = spawn_tree(
137 &materialized,
138 None,
139 &mut universe.world,
140 &mut universe.command_queue,
141 ) else {
142 println!("[diy-panel-debug] skip {:?}: failed to spawn clone", item);
143 continue;
144 };
145
146 universe.add(clone_root);
147
148 let (mut clone_translation, clone_rotation, clone_scale) =
149 decompose_world_trs(matrix_world);
150 clone_translation[0] += DEBUG_CLONE_WORLD_OFFSET[0];
151 clone_translation[1] += DEBUG_CLONE_WORLD_OFFSET[1];
152 clone_translation[2] += DEBUG_CLONE_WORLD_OFFSET[2];
153
154 universe.command_queue.push_intent_now(
155 clone_root,
156 IntentValue::UpdateTransform {
157 component_ids: vec![clone_root],
158 translation: clone_translation,
159 rotation_quat_xyzw: clone_rotation,
160 scale: clone_scale,
161 },
162 );
163
164 let label = if item_label.is_empty() {
165 format!("item_{index}")
166 } else {
167 format!("{}_{}", item_label, index)
168 };
169 println!(
170 "[diy-panel-debug] cloned item={} label={:?} clone_root={:?} offset_translation={:?}",
171 index, label, clone_root, clone_translation,
172 );
173 }
174}