Skip to content

Commit 3e33498

Browse files
committed
better error handling and safety comment
1 parent 73eaa2a commit 3e33498

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

crates/bevy_mod_scripting_bindings/src/reference.rs

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,9 @@ impl ReflectReference {
283283
.ok_or_else(|| {
284284
InteropError::missing_type_data(
285285
handle_type_id,
286-
"ReflectHandle".to_string(),
286+
stringify!(ReflectHandle).into(),
287287
)
288-
.with_context("Handle type is not registered for asset operations - ensure the asset type is properly registered with ReflectHandle type data")
288+
.with_context("Handle type is not registered for asset operations - ensure that you registered it with bevy::App::register_asset_reflect::<T>()")
289289
})?;
290290

291291
let untyped_handle = self.with_reflect(world.clone(), |reflect| {
@@ -300,14 +300,42 @@ impl ReflectReference {
300300
reflect_handle
301301
.downcast_handle_untyped(reflect_any.as_any())
302302
.ok_or_else(|| {
303-
InteropError::invariant("Failed to get UntypedHandle")
304-
.with_context("Handle downcast failed - handle may be of wrong type or corrupted")
303+
InteropError::could_not_downcast(self.clone(), handle_type_id)
304+
.with_context("UntypedHandle downcast failed - handle may be of wrong type or corrupted")
305305
})
306306
})??;
307-
308307
Ok(untyped_handle)
309308
}
310309

310+
/// Get asset from world and return a mutable reference to it
311+
unsafe fn load_asset_mut<'w>(
312+
&self,
313+
handle: &UntypedHandle,
314+
world: WorldGuard<'w>,
315+
) -> Result<&'w mut dyn Reflect, InteropError> {
316+
let type_registry = world.type_registry();
317+
let type_registry = type_registry.read();
318+
319+
let reflect_asset: &ReflectAsset = type_registry
320+
.get_type_data(self.base.type_id)
321+
.ok_or_else(|| InteropError::unregistered_base(self.base.clone()))?;
322+
323+
let world_cell = world.as_unsafe_world_cell()?;
324+
// Safety: The caller guarantees exclusive access to the asset through the WorldGuard,
325+
// and we've validated that the type_id matches the ReflectAsset type data.
326+
// The UnsafeWorldCell is valid for the lifetime 'w of the WorldGuard.
327+
let asset = unsafe { reflect_asset.get_unchecked_mut(world_cell, handle.clone()) }
328+
.ok_or_else(|| {
329+
InteropError::unsupported_operation(
330+
Some(self.base.type_id),
331+
None,
332+
"Asset not loaded or handle is invalid",
333+
)
334+
})?;
335+
336+
Ok(asset)
337+
}
338+
311339
/// Indexes into the reflect path inside this reference.
312340
/// You can use [`Self::reflect`] and [`Self::reflect_mut`] to get the actual value.
313341
pub fn index_path<T: Into<ParsedPath>>(&mut self, index: T) {
@@ -552,32 +580,6 @@ impl ReflectReference {
552580
self.walk_path_mut(base.as_partial_reflect_mut())
553581
}
554582

555-
/// Get asset from world and return a mutable reference to it
556-
unsafe fn load_asset_mut<'w>(
557-
&self,
558-
handle: &UntypedHandle,
559-
world: WorldGuard<'w>,
560-
) -> Result<&'w mut dyn Reflect, InteropError> {
561-
let type_registry = world.type_registry();
562-
let type_registry = type_registry.read();
563-
564-
let reflect_asset: &ReflectAsset = type_registry
565-
.get_type_data(self.base.type_id)
566-
.ok_or_else(|| InteropError::unregistered_base(self.base.clone()))?;
567-
568-
let world_cell = world.as_unsafe_world_cell()?;
569-
let asset = unsafe { reflect_asset.get_unchecked_mut(world_cell, handle.clone()) }
570-
.ok_or_else(|| {
571-
InteropError::unsupported_operation(
572-
Some(self.base.type_id),
573-
None,
574-
"Asset not loaded or handle is invalid",
575-
)
576-
})?;
577-
578-
Ok(asset)
579-
}
580-
581583
fn walk_path<'a>(
582584
&self,
583585
root: &'a dyn PartialReflect,

0 commit comments

Comments
 (0)