···2424bevy_time = { version = "0.18", default-features = false, features = [
2525 "bevy_reflect",
2626] }
2727-bevy_utils = { version = "0.18.1", default-features = false }
2727+bevy_utils = { version = "0.18", default-features = false }
28282929[dev-dependencies]
3030bevy = "0.18"
+21-5
src/bundle_inspector.rs
···8787 ///
8888 /// # Errors
8989 /// Will return an error if:
9090+ /// - The component is not registered in `dst_world`.
9091 /// - The component cannot be cloned ([`ComponentCloneBehavior::Ignore`]).
9192 /// - The stashed bundle doesn't contain the component.
9293 /// - The destination entity doesn't exist in `dst_world`.
9494+ /// - The resource AppTypeRegistry doesn't exist in `dst_world`.
9395 ///
9496 /// # Safety
9597 /// `src_component_id` must be for the same component as `type_id`.
···100102 type_id: TypeId,
101103 src_component_id: ComponentId,
102104 ) -> Result<&Self, MultiWorldCopyError> {
103103- //
104104- let dst_component_id = dst_world.components().get_id(type_id).unwrap();
105105+ let Some(dst_component_id) = dst_world.components().get_id(type_id) else {
106106+ return Err(MultiWorldCopyError::Unregistered(type_id));
107107+ };
105108 let component_info = dst_world.components().get_info(dst_component_id).unwrap();
106109107110 match component_info.clone_behavior() {
···124127 let dst = alloc(component_info.layout());
125128126129 // SAFETY: `dst` is allocated from the component's layout.
127127- // Both IDs provided by the caller must match, and `src` and `dst` obtained using the IDs.
130130+ // Both IDs provided by the caller must match, and `src` and `dst` are obtained using those IDs.
128131 // `src` and `dst` are from different worlds, so cannot overlap.
129132 copy_nonoverlapping(src.as_ptr(), dst, component_info.layout().size());
130133134134+ // SAFETY: Both IDs provided by the caller must match, and `dst` was created from `src`.
131135 let owning = OwningPtr::new(NonNull::new(dst).unwrap());
132136133137 // SAFETY: `existing_component_id` is extracted from `dst_world`.
134134- // Both IDs provided by the caller must match, `owning` was obtained using `src_component_id`.
138138+ // Both IDs provided by the caller must match, and `owning` was obtained using `src_component_id`.
135139 dst_world
136140 .get_entity_mut(dst_entity)
137141 .map_err(|_| MultiWorldCopyError::MissingDstEntity(dst_entity))?
138142 .insert_by_id(dst_component_id, owning);
139143 }
140144 } else {
141141- let registry = dst_world.resource::<AppTypeRegistry>().clone();
145145+ let Some(registry) = dst_world.get_resource::<AppTypeRegistry>().cloned() else {
146146+ return Err(MultiWorldCopyError::MissingTypeRegistry);
147147+ };
142148 let registry = registry.read();
143149144150 let reflect_component = registry
···160166161167#[derive(Debug, Eq, PartialEq, Clone)]
162168pub enum MultiWorldCopyError {
169169+ Unregistered(TypeId),
163170 Uncloneable(DebugName),
164171 MissingDstEntity(Entity),
165172 MissingSrcComponent(DebugName, Entity),
173173+ MissingTypeRegistry,
166174}
167175168176impl std::fmt::Display for MultiWorldCopyError {
169177 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
170178 match self {
179179+ MultiWorldCopyError::Unregistered(type_id) => write!(
180180+ f,
181181+ "Component with {type_id:?} is not registered in the destination world, and therefor cannot be inserted using merge mode.",
182182+ ),
171183 MultiWorldCopyError::Uncloneable(name) => write!(
172184 f,
173185 "Component {name} cannot be cloned, and therefor cannot be inserted using merge mode.",
···179191 MultiWorldCopyError::MissingSrcComponent(name, entity) => write!(
180192 f,
181193 "Component {name} does not exist on the scratch entity {entity}, and therefor cannot be cloned.",
194194+ ),
195195+ MultiWorldCopyError::MissingTypeRegistry => write!(
196196+ f,
197197+ "Resource AppTypeRegistry does not exist in the destination world, and therefor no components can be cloned.",
182198 ),
183199 }
184200 }