diff --git a/crates/bevy_animation/src/animation_curves.rs b/crates/bevy_animation/src/animation_curves.rs index 0e535644cc..28069c1af4 100644 --- a/crates/bevy_animation/src/animation_curves.rs +++ b/crates/bevy_animation/src/animation_curves.rs @@ -41,7 +41,7 @@ //! # use bevy_math::curve::{Curve, Interval, FunctionCurve}; //! # use bevy_animation::{AnimationClip, AnimationTargetId, animated_field, animation_curves::*}; //! # use bevy_transform::components::Transform; -//! # use bevy_core::Name; +//! # use bevy_ecs::name::Name; //! # use bevy_math::vec3; //! # let wobble_curve = FunctionCurve::new( //! # Interval::UNIT, @@ -144,7 +144,7 @@ use downcast_rs::{impl_downcast, Downcast}; /// /// # use bevy_animation::{AnimationClip, AnimationTargetId, VariableCurve, AnimationEntityMut, AnimationEvaluationError, animation_curves::EvaluatorId}; /// # use bevy_animation::prelude::{AnimatableProperty, AnimatableKeyframeCurve, AnimatableCurve}; -/// # use bevy_core::Name; +/// # use bevy_ecs::name::Name; /// # use bevy_reflect::Reflect; /// # use bevy_render::camera::PerspectiveProjection; /// # use std::any::TypeId; diff --git a/crates/bevy_animation/src/lib.rs b/crates/bevy_animation/src/lib.rs index e03ad9a449..0403344791 100644 --- a/crates/bevy_animation/src/lib.rs +++ b/crates/bevy_animation/src/lib.rs @@ -33,7 +33,6 @@ use crate::{ use bevy_app::{Animation, App, Plugin, PostUpdate}; use bevy_asset::{Asset, AssetApp, Assets}; -use bevy_core::Name; use bevy_ecs::{ entity::{VisitEntities, VisitEntitiesMut}, prelude::*, diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index 748e261099..f5c37d1daa 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -9,13 +9,11 @@ extern crate alloc; -mod name; #[cfg(feature = "serialize")] mod serde; mod task_pool_options; use bevy_ecs::system::Resource; -pub use name::*; pub use task_pool_options::*; /// The core prelude. @@ -23,10 +21,7 @@ pub use task_pool_options::*; /// This includes the most common types in this crate, re-exported for your convenience. pub mod prelude { #[doc(hidden)] - pub use crate::{ - FrameCountPlugin, Name, NameOrEntity, TaskPoolOptions, TaskPoolPlugin, - TypeRegistrationPlugin, - }; + pub use crate::{FrameCountPlugin, TaskPoolOptions, TaskPoolPlugin, TypeRegistrationPlugin}; } use bevy_app::prelude::*; diff --git a/crates/bevy_core/src/serde.rs b/crates/bevy_core/src/serde.rs index d618ba1794..3e6a2ed4e8 100644 --- a/crates/bevy_core/src/serde.rs +++ b/crates/bevy_core/src/serde.rs @@ -8,37 +8,7 @@ use serde::{ Deserialize, Deserializer, Serialize, Serializer, }; -use super::{name::Name, FrameCount}; - -impl Serialize for Name { - fn serialize(&self, serializer: S) -> Result { - serializer.serialize_str(self.as_str()) - } -} - -impl<'de> Deserialize<'de> for Name { - fn deserialize>(deserializer: D) -> Result { - deserializer.deserialize_str(EntityVisitor) - } -} - -struct EntityVisitor; - -impl<'de> Visitor<'de> for EntityVisitor { - type Value = Name; - - fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { - formatter.write_str(any::type_name::()) - } - - fn visit_str(self, v: &str) -> Result { - Ok(Name::new(v.to_string())) - } - - fn visit_string(self, v: String) -> Result { - Ok(Name::new(v)) - } -} +use super::FrameCount; // Manually implementing serialize/deserialize allows us to use a more compact representation as simple integers impl Serialize for FrameCount { @@ -76,12 +46,6 @@ mod tests { use serde_test::{assert_tokens, Token}; - #[test] - fn test_serde_name() { - let name = Name::new("MyComponent"); - assert_tokens(&name, &[Token::String("MyComponent")]); - } - #[test] fn test_serde_frame_count() { let frame_count = FrameCount(100); diff --git a/crates/bevy_ecs/Cargo.toml b/crates/bevy_ecs/Cargo.toml index 3db26b9a2c..add6ff1861 100644 --- a/crates/bevy_ecs/Cargo.toml +++ b/crates/bevy_ecs/Cargo.toml @@ -139,6 +139,7 @@ bumpalo = "3" [dev-dependencies] rand = "0.8" static_assertions = "1.1.0" +serde_test = "1.0" [[example]] name = "events" diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 95144d9a75..419972fdff 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -33,6 +33,7 @@ pub mod event; pub mod identifier; pub mod intern; pub mod label; +pub mod name; pub mod observer; pub mod query; #[cfg(feature = "bevy_reflect")] @@ -59,6 +60,7 @@ pub mod prelude { component::{require, Component}, entity::{Entity, EntityMapper}, event::{Event, EventMutator, EventReader, EventWriter, Events}, + name::{Name, NameOrEntity}, observer::{CloneEntityWithObserversExt, Observer, Trigger}, query::{Added, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without}, removal_detection::RemovedComponents, diff --git a/crates/bevy_core/src/name.rs b/crates/bevy_ecs/src/name.rs similarity index 76% rename from crates/bevy_core/src/name.rs rename to crates/bevy_ecs/src/name.rs index 70e7a81cef..a6b8b961ea 100644 --- a/crates/bevy_core/src/name.rs +++ b/crates/bevy_ecs/src/name.rs @@ -1,18 +1,29 @@ -#[cfg(feature = "bevy_reflect")] -use bevy_ecs::reflect::ReflectComponent; -use bevy_ecs::{component::Component, entity::Entity, query::QueryData}; +//! Provides the [`Name`] [`Component`], used for identifying an [`Entity`]. -use alloc::borrow::Cow; -#[cfg(feature = "bevy_reflect")] -use bevy_reflect::std_traits::ReflectDefault; -#[cfg(feature = "bevy_reflect")] -use bevy_reflect::Reflect; +use crate::{self as bevy_ecs, component::Component, entity::Entity, query::QueryData}; + +use alloc::{ + borrow::{Cow, ToOwned}, + string::String, +}; use bevy_utils::FixedHasher; use core::{ hash::{BuildHasher, Hash, Hasher}, ops::Deref, }; +#[cfg(feature = "serialize")] +use serde::{ + de::{Error, Visitor}, + Deserialize, Deserializer, Serialize, Serializer, +}; + +#[cfg(feature = "bevy_reflect")] +use { + crate::reflect::ReflectComponent, + bevy_reflect::{std_traits::ReflectDefault, Reflect}, +}; + #[cfg(all(feature = "serialize", feature = "bevy_reflect"))] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; @@ -101,14 +112,13 @@ impl core::fmt::Debug for Name { /// Convenient query for giving a human friendly name to an entity. /// /// ``` -/// # use bevy_core::prelude::*; /// # use bevy_ecs::prelude::*; /// # #[derive(Component)] pub struct Score(f32); /// fn increment_score(mut scores: Query<(NameOrEntity, &mut Score)>) { /// for (name, mut score) in &mut scores { /// score.0 += 1.0; /// if score.0.is_nan() { -/// bevy_utils::tracing::error!("Score for {name} is invalid"); +/// log::error!("Score for {name} is invalid"); /// } /// } /// } @@ -213,10 +223,44 @@ impl Deref for Name { } } +#[cfg(feature = "serialize")] +impl Serialize for Name { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_str(self.as_str()) + } +} + +#[cfg(feature = "serialize")] +impl<'de> Deserialize<'de> for Name { + fn deserialize>(deserializer: D) -> Result { + deserializer.deserialize_str(NameVisitor) + } +} + +#[cfg(feature = "serialize")] +struct NameVisitor; + +#[cfg(feature = "serialize")] +impl<'de> Visitor<'de> for NameVisitor { + type Value = Name; + + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { + formatter.write_str(core::any::type_name::()) + } + + fn visit_str(self, v: &str) -> Result { + Ok(Name::new(v.to_string())) + } + + fn visit_string(self, v: String) -> Result { + Ok(Name::new(v)) + } +} + #[cfg(test)] mod tests { use super::*; - use bevy_ecs::world::World; + use crate::world::World; #[test] fn test_display_of_debug_name() { @@ -233,3 +277,16 @@ mod tests { assert_eq!(d2.to_string(), "MyName"); } } + +#[cfg(all(test, feature = "serialize"))] +mod serde_tests { + use super::Name; + + use serde_test::{assert_tokens, Token}; + + #[test] + fn test_serde_name() { + let name = Name::new("MyComponent"); + assert_tokens(&name, &[Token::String("MyComponent")]); + } +} diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 0e754a83b7..2b8c2b75bf 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -8,10 +8,10 @@ use bevy_asset::{ io::Reader, AssetLoadError, AssetLoader, Handle, LoadContext, ReadAssetBytesError, }; use bevy_color::{Color, LinearRgba}; -use bevy_core::Name; use bevy_core_pipeline::prelude::Camera3d; use bevy_ecs::{ entity::{Entity, EntityHashMap}, + name::Name, world::World, }; use bevy_hierarchy::{BuildChildren, ChildBuild, WorldChildBuilder}; diff --git a/crates/bevy_hierarchy/src/valid_parent_check_plugin.rs b/crates/bevy_hierarchy/src/valid_parent_check_plugin.rs index c24266205c..a05ec586cf 100644 --- a/crates/bevy_hierarchy/src/valid_parent_check_plugin.rs +++ b/crates/bevy_hierarchy/src/valid_parent_check_plugin.rs @@ -53,7 +53,7 @@ impl Default for ReportHierarchyIssue { /// (See B0004 explanation linked in warning message) pub fn check_hierarchy_component_has_valid_parent( parent_query: Query< - (Entity, &Parent, Option<&bevy_core::Name>), + (Entity, &Parent, Option<&Name>), (With, Or<(Changed, Added)>), >, component_query: Query<(), With>, diff --git a/crates/bevy_input/src/gamepad.rs b/crates/bevy_input/src/gamepad.rs index 7deac54249..5d057381fe 100644 --- a/crates/bevy_input/src/gamepad.rs +++ b/crates/bevy_input/src/gamepad.rs @@ -1,7 +1,6 @@ //! The gamepad input functionality. use crate::{Axis, ButtonInput, ButtonState}; -use bevy_core::Name; #[cfg(feature = "bevy_reflect")] use bevy_ecs::prelude::ReflectComponent; use bevy_ecs::{ @@ -9,6 +8,7 @@ use bevy_ecs::{ component::Component, entity::Entity, event::{Event, EventReader, EventWriter}, + name::Name, prelude::require, system::{Commands, Query}, }; @@ -316,7 +316,7 @@ pub enum ButtonSettingsError { /// ``` /// # use bevy_input::gamepad::{Gamepad, GamepadAxis, GamepadButton}; /// # use bevy_ecs::system::Query; -/// # use bevy_core::Name; +/// # use bevy_ecs::name::Name; /// # /// fn gamepad_usage_system(gamepads: Query<(&Name, &Gamepad)>) { /// for (name, gamepad) in &gamepads {