bevy/crates/bevy_scene/src/scene_loader.rs
Mike d58ed67fa4
add position to scene errors (#8065)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/6760
- adds line and position on line info to scene errors

```text
Before:
2023-03-12T22:38:59.103220Z  WARN bevy_asset::asset_server: encountered an error while loading an asset: Expected closing `)`
After:
2023-03-12T22:38:59.103220Z  WARN bevy_asset::asset_server: encountered an error while loading an asset: Expected closing `)` at scenes/test/scene.scn.ron:10:4
```

## Solution

- use span_error to get position info. This is what the ron crate does
internally to get the position info.
562963f887/src/options.rs (L158)

## Changelog

- added line numbers to scene errors

---------

Co-authored-by: Paul Hansen <mail@paul.rs>
2023-03-20 19:29:54 +00:00

58 lines
1.7 KiB
Rust

use crate::serde::SceneDeserializer;
use anyhow::{anyhow, Result};
use bevy_app::AppTypeRegistry;
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
use bevy_ecs::world::{FromWorld, World};
use bevy_reflect::TypeRegistryArc;
use bevy_utils::BoxedFuture;
#[cfg(feature = "serialize")]
use serde::de::DeserializeSeed;
#[derive(Debug)]
pub struct SceneLoader {
type_registry: TypeRegistryArc,
}
impl FromWorld for SceneLoader {
fn from_world(world: &mut World) -> Self {
let type_registry = world.resource::<AppTypeRegistry>();
SceneLoader {
type_registry: type_registry.0.clone(),
}
}
}
#[cfg(feature = "serialize")]
impl AssetLoader for SceneLoader {
fn load<'a>(
&'a self,
bytes: &'a [u8],
load_context: &'a mut LoadContext,
) -> BoxedFuture<'a, Result<()>> {
Box::pin(async move {
let mut deserializer = ron::de::Deserializer::from_bytes(bytes)?;
let scene_deserializer = SceneDeserializer {
type_registry: &self.type_registry.read(),
};
let scene = scene_deserializer
.deserialize(&mut deserializer)
.map_err(|e| {
let span_error = deserializer.span_error(e);
anyhow!(
"{} at {}:{}",
span_error.code,
load_context.path().to_string_lossy(),
span_error.position,
)
})?;
load_context.set_default_asset(LoadedAsset::new(scene));
Ok(())
})
}
fn extensions(&self) -> &[&str] {
&["scn", "scn.ron"]
}
}