From 632ef4e2d7647f6cb704a1b5eaeb2fbba9562314 Mon Sep 17 00:00:00 2001 From: Zicklag Date: Wed, 1 Mar 2023 01:53:02 +0000 Subject: [PATCH] fix: makes bones asset path representation more consistent. (#106) Previously the normalize method on a bones path would remove the leading `/` to make it support Bevy paths, which can't start with a `/`, but this was not consistent with the way that the handle was serialized. Now, the bones path representations always maintain the leading `/` to indicate a root path, and the leading `/` is removed when converting to a Bevy handle. This fixes issues run into when trying to read serialized bones handles during map saving in Jumpy. --- crates/bones_asset/src/lib.rs | 38 ++++++++++++++++++------------ crates/bones_bevy_asset/src/lib.rs | 5 +--- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/crates/bones_asset/src/lib.rs b/crates/bones_asset/src/lib.rs index f9a4f71be3..f9393820d0 100644 --- a/crates/bones_asset/src/lib.rs +++ b/crates/bones_asset/src/lib.rs @@ -227,6 +227,23 @@ pub struct AssetPath { pub label: Option>, } +#[cfg(feature = "bevy")] +impl AssetPath { + /// Get the equivalent [`bevy_asset::AssetPath`] from this Bones [`AssetPath`]. + pub fn get_bevy_asset_path(&self) -> bevy_asset::AssetPath<'static> { + bevy_asset::AssetPath::new( + // Bones convention is that `/` is relative to root, but Bevy doesn't like the + // leading /. + if let Ok(path) = self.path.strip_prefix("/") { + path.to_path_buf() + } else { + self.path.to_path_buf() + }, + self.label.as_ref().map(|x| x.to_string()), + ) + } +} + impl AssetPath { /// Create a new asset path. pub fn new>(path: P, label: Option) -> Self { @@ -274,7 +291,7 @@ impl AssetPath { let base = base_path.parent().unwrap_or_else(|| Path::new("")); base.join(&self.path) } else { - self.path.strip_prefix("/").unwrap().to_owned() + self.path.to_path_buf() }; self.path = Arc::from(normalize_path(&path)); @@ -400,7 +417,7 @@ impl serde::Serialize for UntypedHandle { S: serde::Serializer, { serializer.serialize_str(&format!( - "/{}{}", + "{}{}", self.path.path.to_str().expect("Non-unicode path"), self.path .label @@ -417,7 +434,7 @@ impl serde::Serialize for Handle { S: serde::Serializer, { serializer.serialize_str(&format!( - "/{}{}", + "{}{}", self.path.path.to_str().expect("Non-unicode path"), self.path .label @@ -469,10 +486,7 @@ mod bevy { impl super::Handle { /// Get a Bevy weak [`Handle`] from from this bones asset handle. pub fn get_bevy_handle(&self) -> Handle { - let asset_path = AssetPath::new( - self.path.path.to_path_buf(), - self.path.label.as_ref().map(|x| x.to_string()), - ); + let asset_path = self.path.get_bevy_asset_path(); Handle::weak(asset_path.into()) } } @@ -480,20 +494,14 @@ mod bevy { impl super::Handle { /// Get a Bevy weak [`HandleUntyped`] from this bones asset handle. pub fn get_bevy_handle_untyped(&self) -> HandleUntyped { - let asset_path = AssetPath::new( - self.path.path.to_path_buf(), - self.path.label.as_ref().map(|x| x.to_string()), - ); + let asset_path = self.path.get_bevy_asset_path(); HandleUntyped::weak(asset_path.into()) } } impl super::UntypedHandle { /// Get a Bevy weak [`HandleUntyped`] from this bones asset handle. pub fn get_bevy_handle(&self) -> HandleUntyped { - let asset_path = AssetPath::new( - self.path.path.to_path_buf(), - self.path.label.as_ref().map(|x| x.to_string()), - ); + let asset_path = self.path.get_bevy_asset_path(); HandleUntyped::weak(asset_path.into()) } } diff --git a/crates/bones_bevy_asset/src/lib.rs b/crates/bones_bevy_asset/src/lib.rs index ea229a9bec..4773d1bbf6 100644 --- a/crates/bones_bevy_asset/src/lib.rs +++ b/crates/bones_bevy_asset/src/lib.rs @@ -78,10 +78,7 @@ impl BonesBevyAssetLoad for bones::Handle { self.path.normalize_relative_to(load_context.path()); // Create a bevy asset path from this bones handle - let asset_path = bevy_asset::AssetPath::new( - self.path.path.to_path_buf(), - self.path.clone().label.map(|x| x.to_string()), - ); + let asset_path = self.path.get_bevy_asset_path(); let path_id = asset_path.get_id(); dependencies.push(asset_path);