Skip to content

Commit

Permalink
Update to bevy 0.12
Browse files Browse the repository at this point in the history
  • Loading branch information
nicopap committed Nov 4, 2023
1 parent 94b47d0 commit 16bc91f
Show file tree
Hide file tree
Showing 47 changed files with 154 additions and 165 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 0.11

- **BREAKING**: Update to bevy 0.12
- Removed the examples that depended on `bevy_mod_picking`
- **Now asset loading from chirp files is supported for any asset type**
- **Asset loading from chirp files work on WASM**

# 0.10.1

- Reworked the AST so that it is a fully contiguous memory block.
Expand Down
29 changes: 13 additions & 16 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
resolver = "2"
exclude = ["assets/", "the_book/"]
members = [
"examples/*",
"examples/chirp_menu",
"examples/dsl_and_chirp",
"examples/hello_world",
"examples/simple_menu",
"examples/sprite_debug",
"examples/templates",
"dsl",
"chirp",
"chirp_macros",
Expand All @@ -19,7 +24,7 @@ repository = "https://github.com/nicopap/cuicui_layout"

[workspace.dependencies]
anyhow = "1.0.72"
bevy_mod_sysfail = "3"
bevy_mod_sysfail = "5"
# TODO make this optional as well
css-color = "0.2.5"
# TODO make this optional, only used in debug module of cuicui_layout
Expand All @@ -46,22 +51,14 @@ cuicui_layout_bevy_ui = { version = "0.10.2", path = "./ui" }
cuicui = { version = "0.8.0", path = "./cuicui" }

# For examples only
bevy_framepace = "0.13.3"
bevy-inspector-egui = "0.19"
bevy_mod_picking = { version = "0.15.0", default-features = false, features = [
"backend_bevy_ui",
] }
bevy-ui-navigation = "0.32.0"
# bevy_framepace = "0.13.3"
# bevy-inspector-egui = "0.19"
# bevy_mod_picking = { version = "0.15.0", default-features = false, features = [
# "backend_bevy_ui",
# ] }
# bevy-ui-navigation = "0.32.0"
rust-hsluv = "0.1.4"

# bevy_ui hot reloading only works with a patched version of bevy:
# https://github.com/bevyengine/bevy/pull/9621
# bevy_sprite should just work. The following line is to quickly generate the lines
# necessary to patch dependencies with a local version of bevy.
# [patch.crates-io]
# bevy = { git = "https://github.com/nicopap/bevy.git", branch = "v0.11.2-no-ui-panic" }
#app|asset|core|ecs|hierarchy|log|math|reflect|utils|window|mikktspace|transform|render|time|core_pipeline|pbr|

[workspace.metadata.release]
dependent-version = "upgrade"

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ See the [./CHANGELOG.md](./CHANGELOG.md) file.

| bevy | latest supporting version |
|------|-------|
| 0.12 | 0.10.2 |
| 0.11 | 0.10.2 |
| 0.10 | 0.3.0 |

Expand Down
2 changes: 1 addition & 1 deletion chirp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ thiserror.workspace = true
winnow.workspace = true
cuicui_chirp_macros = { version = "0.10.2", path = "../chirp_macros", optional = true }
cuicui_dsl.workspace = true
bevy = { version = "0.11", default-features = false, features = ["bevy_asset", "bevy_scene"] }
bevy = { version = "0.12", default-features = false, features = ["bevy_asset", "bevy_scene"] }

[package.metadata.release]
pre-release-replacements = [
Expand Down
2 changes: 1 addition & 1 deletion chirp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,5 +426,5 @@ different niches.
[`parse_dsl_impl::type_parsers`]: https://docs.rs/cuicui_chirp/0.10.2/cuicui_chirp/parse_dsl_impl/fn.type_parsers.html
[`ParseDsl`]: https://docs.rs/cuicui_chirp/0.10.2/cuicui_chirp/parse_dsl/trait.ParseDsl.html
[`ReflectDsl`]: https://docs.rs/cuicui_chirp/0.10.2/cuicui_chirp/reflect/struct.ReflectDsl.html
[`Reflect`]: https://docs.rs/bevy/0.11/bevy/reflect/trait.Reflect.html
[`Reflect`]: https://docs.rs/bevy/0.12/bevy/reflect/trait.Reflect.html
[`WorldHandles`]: https://docs.rs/cuicui_chirp/0.10.2/cuicui_chirp/loader/struct.WorldHandles.html
2 changes: 1 addition & 1 deletion chirp/src/interpret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use bevy::asset::LoadContext;
use bevy::ecs::prelude::{Commands, Entity};
use bevy::hierarchy::BuildChildren;
use bevy::log::{error, trace};
use bevy::reflect::TypeRegistryInternal as TypeRegistry;
use bevy::reflect::TypeRegistry;
use bevy::utils::HashMap;
use cuicui_dsl::EntityCommands;
use miette::{Diagnostic, NamedSource, SourceSpan};
Expand Down
2 changes: 1 addition & 1 deletion chirp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ macro_rules! log_miette_error {

use bevy::asset::LoadContext;
use bevy::ecs::{prelude::*, system::SystemState};
use bevy::reflect::TypeRegistryInternal as TypeRegistry;
use bevy::reflect::TypeRegistry;

use crate::interpret::Interpreter;

Expand Down
5 changes: 4 additions & 1 deletion chirp/src/load_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ pub trait LoadAsset: Sized {
#[cfg(feature = "load_image")]
impl LoadAsset for Image {
fn load(path: &Path, bytes: &[u8], _: &LoadContext) -> Result<Self> {
use bevy::render::texture::ImageSampler::Default;
// use the file extension for the image type
let ext = path.extension().unwrap().to_str().unwrap();

let image_type = ImageType::Extension(ext);
let formats = CompressedImageFormats::empty();

Ok(Image::from_buffer(bytes, image_type, formats, true)?)
Ok(Image::from_buffer(
bytes, image_type, formats, true, Default,
)?)
}
}
#[cfg(feature = "load_font")]
Expand Down
19 changes: 8 additions & 11 deletions chirp/src/loader/internal.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::marker::PhantomData;

use bevy::asset::{LoadContext, LoadedAsset};
use bevy::asset::LoadContext;
use bevy::ecs::prelude::*;
use bevy::reflect::TypeRegistryInternal as TypeRegistry;
use bevy::reflect::TypeRegistry;
use bevy::scene::Scene;

use super::spawn::Chirp;
use super::spawn::Chirp_;
use crate::{interpret, ChirpReader, Handles, ParseDsl};

pub(super) struct Loader<'a, 'r, 'w, 'h, D> {
Expand All @@ -20,19 +20,16 @@ impl<'a, 'r, 'w, 'h, D: ParseDsl + 'static> Loader<'a, 'r, 'w, 'h, D> {
Self { ctx, registry: reg, handles: h, _dsl: PhantomData }
}

pub(super) fn load(&mut self, file: &[u8]) {
let load = LoadedAsset::new;

let chirp = match self.load_scene(file) {
pub(super) fn load(&mut self, file: &[u8]) -> Chirp_ {
match self.load_scene(file) {
Ok((root, scene)) => {
Chirp::Loaded(root, self.ctx.set_labeled_asset("Scene", load(scene)))
Chirp_::Loaded(root, self.ctx.add_labeled_asset("Scene".to_owned(), scene))
}
Err(errors) => {
log_miette_error!(&errors);
Chirp::Error(errors)
Chirp_::Error(errors)
}
};
self.ctx.set_default_asset(LoadedAsset::new(chirp));
}
}
fn load_scene(&mut self, file: &[u8]) -> Result<(Entity, Scene), interpret::Errors> {
let mut world = World::new();
Expand Down
27 changes: 18 additions & 9 deletions chirp/src/loader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ use std::{any::type_name, marker::PhantomData, sync::Arc, sync::RwLock, sync::Tr

use anyhow::Result;
use bevy::app::{App, Plugin as BevyPlugin, PostUpdate};
use bevy::asset::{prelude::*, AssetLoader, LoadContext};
use bevy::asset::{prelude::*, AssetLoader, AsyncReadExt, LoadContext};
use bevy::ecs::{prelude::*, schedule::ScheduleLabel, system::EntityCommands};
use bevy::log::{error, info};
use bevy::reflect::{TypeRegistryArc, TypeRegistryInternal as TypeRegistry};
use bevy::reflect::{TypeRegistry, TypeRegistryArc};
use bevy::scene::scene_spawner_system;
use bevy::transform::TransformSystem;
use bevy::utils::get_short_name;
Expand Down Expand Up @@ -74,6 +74,7 @@ pub struct ChirpBundle {
impl ChirpBundle {
/// Load a new chirp scene.
#[must_use]
#[allow(clippy::missing_const_for_fn)]
pub fn new(scene: Handle<Chirp>) -> Self {
ChirpBundle { state: ChirpState::Loading, scene }
}
Expand Down Expand Up @@ -135,22 +136,30 @@ impl<D: 'static> FromWorld for ChirpLoader<D> {
}

impl<D: ParseDsl + 'static> AssetLoader for ChirpLoader<D> {
type Asset = Chirp;
type Settings = ();
type Error = std::io::Error;

fn load<'a>(
&'a self,
bytes: &'a [u8],
reader: &'a mut bevy::asset::io::Reader,
_: &'a Self::Settings,
load_context: &'a mut LoadContext,
) -> bevy::utils::BoxedFuture<'a, Result<()>> {
) -> bevy::utils::BoxedFuture<'a, Result<Self::Asset, std::io::Error>> {
Box::pin(async move {
let registry = self.registry.internal.read();
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
let registry = self.registry.internal.read().unwrap();
let Ok(handles) = self.handles.as_ref().read() else {
let name = get_short_name(type_name::<D>());
return Err(anyhow::anyhow!("Can't read handles in ChirpLoader<{name}>"));
error!("Can't read handles in ChirpLoader<{name}>");
return Ok(Chirp(spawn::Chirp_::LoadError));
};
internal::Loader::<D>::new(load_context, &registry, &handles).load(bytes);
let chirp = internal::Loader::<D>::new(load_context, &registry, &handles).load(&bytes);
drop(registry);
let path = load_context.path().to_string_lossy();
info!("Complete loading of chirp: {path}");
Ok(())
Ok(Chirp(chirp))
})
}

Expand Down Expand Up @@ -198,7 +207,7 @@ impl<D: ParseDsl + 'static> BevyPlugin for Plugin<D> {
.before(bevy::ui::UiSystem::Focus)
.before(bevy::ui::UiSystem::Stack);
app.add_systems(PostUpdate, chirp_asset_systems);
app.add_asset::<Chirp>()
app.init_asset::<Chirp>()
.register_type::<ChirpState>()
.init_asset_loader::<ChirpLoader<D>>();
}
Expand Down
15 changes: 8 additions & 7 deletions chirp/src/loader/scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
use std::any;

use bevy::ecs::prelude::*;
use bevy::ecs::{entity::EntityMap, query::QuerySingleError, reflect::ReflectMapEntities};
use bevy::ecs::{query::QuerySingleError, reflect::ReflectMapEntities};
use bevy::log::{info, trace, warn};
use bevy::reflect::TypeRegistryInternal as TypeRegistry;
use bevy::reflect::TypeRegistry;
use bevy::scene::Scene;
use bevy::utils::HashMap;

#[derive(Debug, thiserror::Error)]
pub enum Error {
Expand All @@ -26,12 +27,12 @@ pub enum Error {
#[derive(Debug, Component, Default)]
#[component(storage = "SparseSet")]
pub(super) struct ChirpInstance {
pub(super) map: EntityMap,
pub(super) map: HashMap<Entity, Entity>,
}
impl ChirpInstance {
pub(super) fn despawn_scene(&self, root: Entity, cmds: &mut Commands<'_, '_>) {
for e in self.map.values().filter(|e| *e != root) {
cmds.entity(e).despawn();
for e in self.map.values().filter(|e| **e != root) {
cmds.entity(*e).despawn();
}
}
}
Expand Down Expand Up @@ -65,7 +66,7 @@ pub(super) fn insert_on<D>(
let source = &source_scene.world;
let get_info = |id| source.components().get_info(id);
let dsl = any::type_name::<D>();
let mut entity_map = EntityMap::default();
let mut entity_map = HashMap::default();
entity_map.insert(source_root, target_root);

trace!("Applying scene to target world");
Expand All @@ -85,7 +86,7 @@ pub(super) fn insert_on<D>(
let unregistered = || Error::UnregisteredType(info.name().into(), dsl);
let entry = info
.type_id()
.map_or_else(|| reg.get_with_name(info.name()), |id| reg.get(id))
.map_or_else(|| reg.get_with_type_path(info.name()), |id| reg.get(id))
.ok_or_else(unregistered)?;

let reflect_component =
Expand Down
29 changes: 17 additions & 12 deletions chirp/src/loader/spawn.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use bevy::asset::{AssetEvent, Assets, Handle};
use bevy::ecs::{prelude::*, reflect::ReflectComponent, system::SystemState};
use bevy::log::{error, trace};
use bevy::prelude::Children;
use bevy::reflect::{Reflect, TypePath, TypeUuid};
use bevy::prelude::{Asset, Children};
use bevy::reflect::{Reflect, TypePath};
use bevy::scene::Scene;
use thiserror::Error;

Expand Down Expand Up @@ -46,31 +46,36 @@ pub enum ChirpState {
///
/// Modify this component to control the scene state. It can be used to reload
/// the scene or despawn the scene.
#[derive(Debug, TypeUuid, TypePath)]
#[uuid = "b954f251-c38a-4ede-a7dd-cbf9856c84c1"]
pub enum Chirp {
#[derive(Debug, TypePath, Asset)]
pub struct Chirp(pub(crate) Chirp_);

#[derive(Debug, TypePath)]
pub enum Chirp_ {
/// The chirp file loaded successfully and holds the given [`Scene`].
Loaded(Entity, Handle<Scene>),
/// The chirp file failed to load with the given [`anyhow::Error`].
///
/// Note: this exists because this enables us to use hot reloading even
/// when loading the file failed.
Error(interpret::Errors),
LoadError,
}

#[allow(clippy::needless_pass_by_value)] // false positive, bevy systems
pub(super) fn update_asset_changed(
mut asset_events: EventReader<AssetEvent<Chirp>>,
mut chirp_instances: Query<(&mut ChirpState, &Handle<Chirp>), With<ChirpInstance>>,
) {
use AssetEvent::{Created, Modified, Removed};
use AssetEvent::{Added, LoadedWithDependencies, Modified, Removed};
#[allow(clippy::explicit_iter_loop)]
for event in asset_events.iter() {
for event in asset_events.read() {
for (mut state, instance_handle) in &mut chirp_instances {
let instance_id = instance_handle.id();
match event {
Modified { handle } if handle == instance_handle => *state = ChirpState::MustReload,
Removed { handle } if handle == instance_handle => *state = ChirpState::MustDelete,
Created { .. } | Modified { .. } | Removed { .. } => {}
Modified { id } if id == &instance_id => *state = ChirpState::MustReload,
Removed { id } if id == &instance_id => *state = ChirpState::MustDelete,
Added { .. } | Modified { .. } | Removed { .. } | LoadedWithDependencies { .. } => {
}
}
}
}
Expand All @@ -97,7 +102,7 @@ pub(super) fn spawn_chirps<D>(
continue;
};
world.entity_mut(target).insert(instance);
change_scenes(world, |s| s.set(scene_handle, scene));
change_scenes(world, |s| s.insert(scene_handle, scene));
}
}
fn change_scenes<T>(world: &mut World, f: impl FnOnce(&mut Assets<Scene>) -> T) -> T {
Expand Down Expand Up @@ -134,7 +139,7 @@ fn mark_loaded(
) -> Vec<SpawnRequest> {
let iter = to_spawn.iter_mut();
let iter = iter.filter_map(|(target, mut state, handle)| {
let Some(&Chirp::Loaded(source, ref scene)) = chirps.get(handle) else {
let Some(&Chirp(Chirp_::Loaded(source, ref scene))) = chirps.get(handle) else {
return None;
};
matches!(*state, ChirpState::Loading).then(|| {
Expand Down
17 changes: 5 additions & 12 deletions chirp/src/parse_dsl/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
// use inline(always) on functions that are very small, it won't add significative
// compile overhead in anycase, but may help the optimizer elide some code.

use std::{any, borrow::Cow, convert::Infallible, fs, io, marker::PhantomData, str, str::FromStr};
use std::{any, borrow::Cow, convert::Infallible, io, marker::PhantomData, str, str::FromStr};

use bevy::asset::{Asset, FileAssetIo, Handle, LoadContext, LoadedAsset};
use bevy::asset::{Asset, Handle, LoadContext};
use bevy::reflect::erased_serde::__private::serde::de::DeserializeSeed;
use bevy::reflect::serde::TypedReflectDeserializer;
use bevy::reflect::{FromReflect, Reflect, TypeRegistryInternal as TypeRegistry};
use bevy::reflect::{FromReflect, Reflect, TypeRegistry};
use thiserror::Error;

use super::escape_literal;
Expand Down Expand Up @@ -164,18 +164,11 @@ pub fn to_handle<T: Asset + LoadAsset>(
load_context: Option<&mut LoadContext>,
input: &str,
) -> Result<Handle<T>, HandleDslDeserError<T>> {
use HandleDslDeserError::{BadLoad, UnsupportedIo};

let Some(ctx) = load_context else {
return Err(HandleDslDeserError::<T>::NoLoadContext);
};
let file_io: &FileAssetIo = ctx.asset_io().downcast_ref().ok_or(UnsupportedIo)?;
let input = interpret_str(input);
let mut file_path = file_io.root_path().clone();
file_path.push(input.as_ref());
let bytes = fs::read(&file_path)?;
let asset = T::load(&file_path, &bytes, ctx).map_err(BadLoad)?;
Ok(ctx.set_labeled_asset(input.as_ref(), LoadedAsset::new(asset)))
let input = input.to_owned();
Ok(ctx.load(input))
}

/// Returns the input as a `&str`, removing quotes applying backslash escapes.
Expand Down
2 changes: 1 addition & 1 deletion chirp/src/parse_dsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

use anyhow::Result;
use bevy::asset::LoadContext;
use bevy::reflect::TypeRegistryInternal as TypeRegistry;
use bevy::reflect::TypeRegistry;
use cuicui_dsl::{BaseDsl, DslBundle};
use thiserror::Error;

Expand Down
Loading

0 comments on commit 16bc91f

Please sign in to comment.