bevy/crates/bevy_scene/src/scene_loader.rs
Nicola Papale 0294bb191d
Move AppTypeRegistry to bevy_ecs (#8901)
# Objective

- Use `AppTypeRegistry` on API defined in `bevy_ecs`
(https://github.com/bevyengine/bevy/pull/8895#discussion_r1234748418)

A lot of the API on `Reflect` depends on a registry. When it comes to
the ECS. We should use `AppTypeRegistry` in the general case.

This is however impossible in `bevy_ecs`, since `AppTypeRegistry` is
defined in `bevy_app`.

## Solution

- Move `AppTypeRegistry` resource definition from `bevy_app` to
`bevy_ecs`
- Still add the resource in the `App` plugin, since bevy_ecs itself
doesn't know of plugins

Note that `bevy_ecs` is a dependency of `bevy_app`, so nothing
revolutionary happens.

## Alternative

- Define the API as a trait in `bevy_app` over `bevy_ecs`. (though this
prevents us from using bevy_ecs internals)
- Do not rely on `AppTypeRegistry` for the API in question, requring
users to extract themselves the resource and pass it to the API methods.

---

## Changelog

- Moved `AppTypeRegistry` resource definition from `bevy_app` to
`bevy_ecs`

## Migration Guide

- If you were **not** using a `prelude::*` to import `AppTypeRegistry`,
you should update your imports:

```diff
- use bevy::app::AppTypeRegistry;
+ use bevy::ecs::reflect::AppTypeRegistry
```
2023-06-21 17:25:01 +00:00

59 lines
1.7 KiB
Rust

#[cfg(feature = "serialize")]
use crate::serde::SceneDeserializer;
use anyhow::{anyhow, Result};
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
use bevy_ecs::reflect::AppTypeRegistry;
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"]
}
}