Allow returning an error from labeled_asset_scope
. (#19449)
# Objective - `LoadContext::labeled_asset_scope` cannot return errors back to the asset loader. This means users that need errors need to fall back to using the raw `begin_labeled_asset` and `add_loaded_labeled_asset`, which is more error-prone. ## Solution - Allow returning a (generic) error from `labeled_asset_scope`. - This has the unfortunate side effect that closures which don't return any errors need to A) return Ok at the end, B) need to specify an error type (e.g., `()`). --- ## Showcase ```rust // impl AssetLoader for MyLoader let handle = load_context.labeled_asset_scope("MySubasset", |mut load_context| { if !some_precondition { return Err(ThingsDontMakeSenseError); } let handle = load_context.add_labeled_asset("MySubasset/Other", SomeOtherThing(456)); Ok(Something{ id: 123, handle }) })?; ```
This commit is contained in:
parent
5561b40bdf
commit
723b52abd3
@ -388,15 +388,15 @@ impl<'a> LoadContext<'a> {
|
|||||||
/// result with [`LoadContext::add_labeled_asset`].
|
/// result with [`LoadContext::add_labeled_asset`].
|
||||||
///
|
///
|
||||||
/// See [`AssetPath`] for more on labeled assets.
|
/// See [`AssetPath`] for more on labeled assets.
|
||||||
pub fn labeled_asset_scope<A: Asset>(
|
pub fn labeled_asset_scope<A: Asset, E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
label: String,
|
label: String,
|
||||||
load: impl FnOnce(&mut LoadContext) -> A,
|
load: impl FnOnce(&mut LoadContext) -> Result<A, E>,
|
||||||
) -> Handle<A> {
|
) -> Result<Handle<A>, E> {
|
||||||
let mut context = self.begin_labeled_asset();
|
let mut context = self.begin_labeled_asset();
|
||||||
let asset = load(&mut context);
|
let asset = load(&mut context)?;
|
||||||
let loaded_asset = context.finish(asset);
|
let loaded_asset = context.finish(asset);
|
||||||
self.add_loaded_labeled_asset(label, loaded_asset)
|
Ok(self.add_loaded_labeled_asset(label, loaded_asset))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This will add the given `asset` as a "labeled [`Asset`]" with the `label` label.
|
/// This will add the given `asset` as a "labeled [`Asset`]" with the `label` label.
|
||||||
@ -410,7 +410,8 @@ impl<'a> LoadContext<'a> {
|
|||||||
///
|
///
|
||||||
/// See [`AssetPath`] for more on labeled assets.
|
/// See [`AssetPath`] for more on labeled assets.
|
||||||
pub fn add_labeled_asset<A: Asset>(&mut self, label: String, asset: A) -> Handle<A> {
|
pub fn add_labeled_asset<A: Asset>(&mut self, label: String, asset: A) -> Handle<A> {
|
||||||
self.labeled_asset_scope(label, |_| asset)
|
self.labeled_asset_scope(label, |_| Ok::<_, ()>(asset))
|
||||||
|
.expect("the closure returns Ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a [`LoadedAsset`] that is a "labeled sub asset" of the root path of this load context.
|
/// Add a [`LoadedAsset`] that is a "labeled sub asset" of the root path of this load context.
|
||||||
|
@ -1043,71 +1043,75 @@ fn load_material(
|
|||||||
is_scale_inverted: bool,
|
is_scale_inverted: bool,
|
||||||
) -> Handle<StandardMaterial> {
|
) -> Handle<StandardMaterial> {
|
||||||
let material_label = material_label(material, is_scale_inverted);
|
let material_label = material_label(material, is_scale_inverted);
|
||||||
load_context.labeled_asset_scope(material_label.to_string(), |load_context| {
|
load_context
|
||||||
let pbr = material.pbr_metallic_roughness();
|
.labeled_asset_scope::<_, ()>(material_label.to_string(), |load_context| {
|
||||||
|
let pbr = material.pbr_metallic_roughness();
|
||||||
|
|
||||||
// TODO: handle missing label handle errors here?
|
// TODO: handle missing label handle errors here?
|
||||||
let color = pbr.base_color_factor();
|
let color = pbr.base_color_factor();
|
||||||
let base_color_channel = pbr
|
let base_color_channel = pbr
|
||||||
.base_color_texture()
|
.base_color_texture()
|
||||||
.map(|info| uv_channel(material, "base color", info.tex_coord()))
|
.map(|info| uv_channel(material, "base color", info.tex_coord()))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let base_color_texture = pbr
|
let base_color_texture = pbr
|
||||||
.base_color_texture()
|
.base_color_texture()
|
||||||
.map(|info| texture_handle(&info.texture(), load_context));
|
.map(|info| texture_handle(&info.texture(), load_context));
|
||||||
|
|
||||||
let uv_transform = pbr
|
let uv_transform = pbr
|
||||||
.base_color_texture()
|
.base_color_texture()
|
||||||
.and_then(|info| info.texture_transform().map(texture_transform_to_affine2))
|
.and_then(|info| info.texture_transform().map(texture_transform_to_affine2))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let normal_map_channel = material
|
let normal_map_channel = material
|
||||||
.normal_texture()
|
.normal_texture()
|
||||||
.map(|info| uv_channel(material, "normal map", info.tex_coord()))
|
.map(|info| uv_channel(material, "normal map", info.tex_coord()))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let normal_map_texture: Option<Handle<Image>> =
|
let normal_map_texture: Option<Handle<Image>> =
|
||||||
material.normal_texture().map(|normal_texture| {
|
material.normal_texture().map(|normal_texture| {
|
||||||
// TODO: handle normal_texture.scale
|
// TODO: handle normal_texture.scale
|
||||||
texture_handle(&normal_texture.texture(), load_context)
|
texture_handle(&normal_texture.texture(), load_context)
|
||||||
|
});
|
||||||
|
|
||||||
|
let metallic_roughness_channel = pbr
|
||||||
|
.metallic_roughness_texture()
|
||||||
|
.map(|info| uv_channel(material, "metallic/roughness", info.tex_coord()))
|
||||||
|
.unwrap_or_default();
|
||||||
|
let metallic_roughness_texture = pbr.metallic_roughness_texture().map(|info| {
|
||||||
|
warn_on_differing_texture_transforms(
|
||||||
|
material,
|
||||||
|
&info,
|
||||||
|
uv_transform,
|
||||||
|
"metallic/roughness",
|
||||||
|
);
|
||||||
|
texture_handle(&info.texture(), load_context)
|
||||||
});
|
});
|
||||||
|
|
||||||
let metallic_roughness_channel = pbr
|
let occlusion_channel = material
|
||||||
.metallic_roughness_texture()
|
.occlusion_texture()
|
||||||
.map(|info| uv_channel(material, "metallic/roughness", info.tex_coord()))
|
.map(|info| uv_channel(material, "occlusion", info.tex_coord()))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let metallic_roughness_texture = pbr.metallic_roughness_texture().map(|info| {
|
let occlusion_texture = material.occlusion_texture().map(|occlusion_texture| {
|
||||||
warn_on_differing_texture_transforms(
|
// TODO: handle occlusion_texture.strength() (a scalar multiplier for occlusion strength)
|
||||||
material,
|
texture_handle(&occlusion_texture.texture(), load_context)
|
||||||
&info,
|
});
|
||||||
uv_transform,
|
|
||||||
"metallic/roughness",
|
|
||||||
);
|
|
||||||
texture_handle(&info.texture(), load_context)
|
|
||||||
});
|
|
||||||
|
|
||||||
let occlusion_channel = material
|
let emissive = material.emissive_factor();
|
||||||
.occlusion_texture()
|
let emissive_channel = material
|
||||||
.map(|info| uv_channel(material, "occlusion", info.tex_coord()))
|
.emissive_texture()
|
||||||
.unwrap_or_default();
|
.map(|info| uv_channel(material, "emissive", info.tex_coord()))
|
||||||
let occlusion_texture = material.occlusion_texture().map(|occlusion_texture| {
|
.unwrap_or_default();
|
||||||
// TODO: handle occlusion_texture.strength() (a scalar multiplier for occlusion strength)
|
let emissive_texture = material.emissive_texture().map(|info| {
|
||||||
texture_handle(&occlusion_texture.texture(), load_context)
|
// TODO: handle occlusion_texture.strength() (a scalar multiplier for occlusion strength)
|
||||||
});
|
warn_on_differing_texture_transforms(material, &info, uv_transform, "emissive");
|
||||||
|
texture_handle(&info.texture(), load_context)
|
||||||
|
});
|
||||||
|
|
||||||
let emissive = material.emissive_factor();
|
#[cfg(feature = "pbr_transmission_textures")]
|
||||||
let emissive_channel = material
|
let (
|
||||||
.emissive_texture()
|
specular_transmission,
|
||||||
.map(|info| uv_channel(material, "emissive", info.tex_coord()))
|
specular_transmission_channel,
|
||||||
.unwrap_or_default();
|
specular_transmission_texture,
|
||||||
let emissive_texture = material.emissive_texture().map(|info| {
|
) = material
|
||||||
// TODO: handle occlusion_texture.strength() (a scalar multiplier for occlusion strength)
|
|
||||||
warn_on_differing_texture_transforms(material, &info, uv_transform, "emissive");
|
|
||||||
texture_handle(&info.texture(), load_context)
|
|
||||||
});
|
|
||||||
|
|
||||||
#[cfg(feature = "pbr_transmission_textures")]
|
|
||||||
let (specular_transmission, specular_transmission_channel, specular_transmission_texture) =
|
|
||||||
material
|
|
||||||
.transmission()
|
.transmission()
|
||||||
.map_or((0.0, UvChannel::Uv0, None), |transmission| {
|
.map_or((0.0, UvChannel::Uv0, None), |transmission| {
|
||||||
let specular_transmission_channel = transmission
|
let specular_transmission_channel = transmission
|
||||||
@ -1127,152 +1131,156 @@ fn load_material(
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(not(feature = "pbr_transmission_textures"))]
|
#[cfg(not(feature = "pbr_transmission_textures"))]
|
||||||
let specular_transmission = material
|
let specular_transmission = material
|
||||||
.transmission()
|
.transmission()
|
||||||
.map_or(0.0, |transmission| transmission.transmission_factor());
|
.map_or(0.0, |transmission| transmission.transmission_factor());
|
||||||
|
|
||||||
#[cfg(feature = "pbr_transmission_textures")]
|
#[cfg(feature = "pbr_transmission_textures")]
|
||||||
let (
|
let (
|
||||||
thickness,
|
thickness,
|
||||||
thickness_channel,
|
thickness_channel,
|
||||||
thickness_texture,
|
thickness_texture,
|
||||||
attenuation_distance,
|
attenuation_distance,
|
||||||
attenuation_color,
|
attenuation_color,
|
||||||
) = material.volume().map_or(
|
) = material.volume().map_or(
|
||||||
(0.0, UvChannel::Uv0, None, f32::INFINITY, [1.0, 1.0, 1.0]),
|
(0.0, UvChannel::Uv0, None, f32::INFINITY, [1.0, 1.0, 1.0]),
|
||||||
|volume| {
|
|volume| {
|
||||||
let thickness_channel = volume
|
let thickness_channel = volume
|
||||||
.thickness_texture()
|
.thickness_texture()
|
||||||
.map(|info| uv_channel(material, "thickness", info.tex_coord()))
|
.map(|info| uv_channel(material, "thickness", info.tex_coord()))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let thickness_texture: Option<Handle<Image>> =
|
let thickness_texture: Option<Handle<Image>> =
|
||||||
volume.thickness_texture().map(|thickness_texture| {
|
volume.thickness_texture().map(|thickness_texture| {
|
||||||
texture_handle(&thickness_texture.texture(), load_context)
|
texture_handle(&thickness_texture.texture(), load_context)
|
||||||
});
|
});
|
||||||
|
|
||||||
(
|
|
||||||
volume.thickness_factor(),
|
|
||||||
thickness_channel,
|
|
||||||
thickness_texture,
|
|
||||||
volume.attenuation_distance(),
|
|
||||||
volume.attenuation_color(),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(not(feature = "pbr_transmission_textures"))]
|
|
||||||
let (thickness, attenuation_distance, attenuation_color) =
|
|
||||||
material
|
|
||||||
.volume()
|
|
||||||
.map_or((0.0, f32::INFINITY, [1.0, 1.0, 1.0]), |volume| {
|
|
||||||
(
|
(
|
||||||
volume.thickness_factor(),
|
volume.thickness_factor(),
|
||||||
|
thickness_channel,
|
||||||
|
thickness_texture,
|
||||||
volume.attenuation_distance(),
|
volume.attenuation_distance(),
|
||||||
volume.attenuation_color(),
|
volume.attenuation_color(),
|
||||||
)
|
)
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let ior = material.ior().unwrap_or(1.5);
|
#[cfg(not(feature = "pbr_transmission_textures"))]
|
||||||
|
let (thickness, attenuation_distance, attenuation_color) =
|
||||||
|
material
|
||||||
|
.volume()
|
||||||
|
.map_or((0.0, f32::INFINITY, [1.0, 1.0, 1.0]), |volume| {
|
||||||
|
(
|
||||||
|
volume.thickness_factor(),
|
||||||
|
volume.attenuation_distance(),
|
||||||
|
volume.attenuation_color(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
// Parse the `KHR_materials_clearcoat` extension data if necessary.
|
let ior = material.ior().unwrap_or(1.5);
|
||||||
let clearcoat =
|
|
||||||
ClearcoatExtension::parse(load_context, document, material).unwrap_or_default();
|
|
||||||
|
|
||||||
// Parse the `KHR_materials_anisotropy` extension data if necessary.
|
// Parse the `KHR_materials_clearcoat` extension data if necessary.
|
||||||
let anisotropy =
|
let clearcoat =
|
||||||
AnisotropyExtension::parse(load_context, document, material).unwrap_or_default();
|
ClearcoatExtension::parse(load_context, document, material).unwrap_or_default();
|
||||||
|
|
||||||
// Parse the `KHR_materials_specular` extension data if necessary.
|
// Parse the `KHR_materials_anisotropy` extension data if necessary.
|
||||||
let specular =
|
let anisotropy =
|
||||||
SpecularExtension::parse(load_context, document, material).unwrap_or_default();
|
AnisotropyExtension::parse(load_context, document, material).unwrap_or_default();
|
||||||
|
|
||||||
// We need to operate in the Linear color space and be willing to exceed 1.0 in our channels
|
// Parse the `KHR_materials_specular` extension data if necessary.
|
||||||
let base_emissive = LinearRgba::rgb(emissive[0], emissive[1], emissive[2]);
|
let specular =
|
||||||
let emissive = base_emissive * material.emissive_strength().unwrap_or(1.0);
|
SpecularExtension::parse(load_context, document, material).unwrap_or_default();
|
||||||
|
|
||||||
StandardMaterial {
|
// We need to operate in the Linear color space and be willing to exceed 1.0 in our channels
|
||||||
base_color: Color::linear_rgba(color[0], color[1], color[2], color[3]),
|
let base_emissive = LinearRgba::rgb(emissive[0], emissive[1], emissive[2]);
|
||||||
base_color_channel,
|
let emissive = base_emissive * material.emissive_strength().unwrap_or(1.0);
|
||||||
base_color_texture,
|
|
||||||
perceptual_roughness: pbr.roughness_factor(),
|
Ok(StandardMaterial {
|
||||||
metallic: pbr.metallic_factor(),
|
base_color: Color::linear_rgba(color[0], color[1], color[2], color[3]),
|
||||||
metallic_roughness_channel,
|
base_color_channel,
|
||||||
metallic_roughness_texture,
|
base_color_texture,
|
||||||
normal_map_channel,
|
perceptual_roughness: pbr.roughness_factor(),
|
||||||
normal_map_texture,
|
metallic: pbr.metallic_factor(),
|
||||||
double_sided: material.double_sided(),
|
metallic_roughness_channel,
|
||||||
cull_mode: if material.double_sided() {
|
metallic_roughness_texture,
|
||||||
None
|
normal_map_channel,
|
||||||
} else if is_scale_inverted {
|
normal_map_texture,
|
||||||
Some(Face::Front)
|
double_sided: material.double_sided(),
|
||||||
} else {
|
cull_mode: if material.double_sided() {
|
||||||
Some(Face::Back)
|
None
|
||||||
},
|
} else if is_scale_inverted {
|
||||||
occlusion_channel,
|
Some(Face::Front)
|
||||||
occlusion_texture,
|
} else {
|
||||||
emissive,
|
Some(Face::Back)
|
||||||
emissive_channel,
|
},
|
||||||
emissive_texture,
|
occlusion_channel,
|
||||||
specular_transmission,
|
occlusion_texture,
|
||||||
#[cfg(feature = "pbr_transmission_textures")]
|
emissive,
|
||||||
specular_transmission_channel,
|
emissive_channel,
|
||||||
#[cfg(feature = "pbr_transmission_textures")]
|
emissive_texture,
|
||||||
specular_transmission_texture,
|
specular_transmission,
|
||||||
thickness,
|
#[cfg(feature = "pbr_transmission_textures")]
|
||||||
#[cfg(feature = "pbr_transmission_textures")]
|
specular_transmission_channel,
|
||||||
thickness_channel,
|
#[cfg(feature = "pbr_transmission_textures")]
|
||||||
#[cfg(feature = "pbr_transmission_textures")]
|
specular_transmission_texture,
|
||||||
thickness_texture,
|
thickness,
|
||||||
ior,
|
#[cfg(feature = "pbr_transmission_textures")]
|
||||||
attenuation_distance,
|
thickness_channel,
|
||||||
attenuation_color: Color::linear_rgb(
|
#[cfg(feature = "pbr_transmission_textures")]
|
||||||
attenuation_color[0],
|
thickness_texture,
|
||||||
attenuation_color[1],
|
ior,
|
||||||
attenuation_color[2],
|
attenuation_distance,
|
||||||
),
|
attenuation_color: Color::linear_rgb(
|
||||||
unlit: material.unlit(),
|
attenuation_color[0],
|
||||||
alpha_mode: alpha_mode(material),
|
attenuation_color[1],
|
||||||
uv_transform,
|
attenuation_color[2],
|
||||||
clearcoat: clearcoat.clearcoat_factor.unwrap_or_default() as f32,
|
),
|
||||||
clearcoat_perceptual_roughness: clearcoat.clearcoat_roughness_factor.unwrap_or_default()
|
unlit: material.unlit(),
|
||||||
as f32,
|
alpha_mode: alpha_mode(material),
|
||||||
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
uv_transform,
|
||||||
clearcoat_channel: clearcoat.clearcoat_channel,
|
clearcoat: clearcoat.clearcoat_factor.unwrap_or_default() as f32,
|
||||||
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
clearcoat_perceptual_roughness: clearcoat
|
||||||
clearcoat_texture: clearcoat.clearcoat_texture,
|
.clearcoat_roughness_factor
|
||||||
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
.unwrap_or_default() as f32,
|
||||||
clearcoat_roughness_channel: clearcoat.clearcoat_roughness_channel,
|
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
||||||
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
clearcoat_channel: clearcoat.clearcoat_channel,
|
||||||
clearcoat_roughness_texture: clearcoat.clearcoat_roughness_texture,
|
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
||||||
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
clearcoat_texture: clearcoat.clearcoat_texture,
|
||||||
clearcoat_normal_channel: clearcoat.clearcoat_normal_channel,
|
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
||||||
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
clearcoat_roughness_channel: clearcoat.clearcoat_roughness_channel,
|
||||||
clearcoat_normal_texture: clearcoat.clearcoat_normal_texture,
|
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
||||||
anisotropy_strength: anisotropy.anisotropy_strength.unwrap_or_default() as f32,
|
clearcoat_roughness_texture: clearcoat.clearcoat_roughness_texture,
|
||||||
anisotropy_rotation: anisotropy.anisotropy_rotation.unwrap_or_default() as f32,
|
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
||||||
#[cfg(feature = "pbr_anisotropy_texture")]
|
clearcoat_normal_channel: clearcoat.clearcoat_normal_channel,
|
||||||
anisotropy_channel: anisotropy.anisotropy_channel,
|
#[cfg(feature = "pbr_multi_layer_material_textures")]
|
||||||
#[cfg(feature = "pbr_anisotropy_texture")]
|
clearcoat_normal_texture: clearcoat.clearcoat_normal_texture,
|
||||||
anisotropy_texture: anisotropy.anisotropy_texture,
|
anisotropy_strength: anisotropy.anisotropy_strength.unwrap_or_default() as f32,
|
||||||
// From the `KHR_materials_specular` spec:
|
anisotropy_rotation: anisotropy.anisotropy_rotation.unwrap_or_default() as f32,
|
||||||
// <https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_specular#materials-with-reflectance-parameter>
|
#[cfg(feature = "pbr_anisotropy_texture")]
|
||||||
reflectance: specular.specular_factor.unwrap_or(1.0) as f32 * 0.5,
|
anisotropy_channel: anisotropy.anisotropy_channel,
|
||||||
#[cfg(feature = "pbr_specular_textures")]
|
#[cfg(feature = "pbr_anisotropy_texture")]
|
||||||
specular_channel: specular.specular_channel,
|
anisotropy_texture: anisotropy.anisotropy_texture,
|
||||||
#[cfg(feature = "pbr_specular_textures")]
|
// From the `KHR_materials_specular` spec:
|
||||||
specular_texture: specular.specular_texture,
|
// <https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_specular#materials-with-reflectance-parameter>
|
||||||
specular_tint: match specular.specular_color_factor {
|
reflectance: specular.specular_factor.unwrap_or(1.0) as f32 * 0.5,
|
||||||
Some(color) => Color::linear_rgb(color[0] as f32, color[1] as f32, color[2] as f32),
|
#[cfg(feature = "pbr_specular_textures")]
|
||||||
None => Color::WHITE,
|
specular_channel: specular.specular_channel,
|
||||||
},
|
#[cfg(feature = "pbr_specular_textures")]
|
||||||
#[cfg(feature = "pbr_specular_textures")]
|
specular_texture: specular.specular_texture,
|
||||||
specular_tint_channel: specular.specular_color_channel,
|
specular_tint: match specular.specular_color_factor {
|
||||||
#[cfg(feature = "pbr_specular_textures")]
|
Some(color) => {
|
||||||
specular_tint_texture: specular.specular_color_texture,
|
Color::linear_rgb(color[0] as f32, color[1] as f32, color[2] as f32)
|
||||||
..Default::default()
|
}
|
||||||
}
|
None => Color::WHITE,
|
||||||
})
|
},
|
||||||
|
#[cfg(feature = "pbr_specular_textures")]
|
||||||
|
specular_tint_channel: specular.specular_color_channel,
|
||||||
|
#[cfg(feature = "pbr_specular_textures")]
|
||||||
|
specular_tint_texture: specular.specular_color_texture,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads a glTF node.
|
/// Loads a glTF node.
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
title: `labeled_asset_scope` can now return errors.
|
||||||
|
pull_requests: [19449]
|
||||||
|
---
|
||||||
|
|
||||||
|
`labeled_asset_scope` now returns a user-specified error type based on their closure. Previously,
|
||||||
|
users would need to fall back to `begin_labeled_asset` and `add_loaded_labeled_asset` to handle
|
||||||
|
errors, which is more error-prone. Consider migrating to use `labeled_asset_scope` if this was you!
|
||||||
|
|
||||||
|
However, `labeled_asset_scope` closures that don't return errors now needs to A) return Ok, and B)
|
||||||
|
specify an error type.
|
||||||
|
|
||||||
|
If your code previously looked like this:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
labeled_asset_scope(label, |mut load_context| {
|
||||||
|
let my_asset = ...;
|
||||||
|
|
||||||
|
my_asset
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
You can migrate it to:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
labeled_asset_scope::<_, ()>(label, |mut load_context| {
|
||||||
|
let my_asset = ...;
|
||||||
|
|
||||||
|
Ok(my_asset)
|
||||||
|
}).unwrap();
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user