Move Name out of bevy_core (#16894)

# Objective

- Contributes to #16892

## Solution

- Moved `Name` and `NameOrEntity` into `bevy_ecs::name`, and added them
to the prelude.

## Testing

- CI

## Migration Guide

If you were importing `Name` or `NameOrEntity` from `bevy_core`, instead
import from `bevy_ecs::name`.

---------

Co-authored-by: Christian Hughes <9044780+ItsDoot@users.noreply.github.com>
This commit is contained in:
Zachary Harrold 2024-12-19 13:45:16 +11:00 committed by GitHub
parent df7aa445e9
commit d4b07a5114
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 79 additions and 61 deletions

View File

@ -41,7 +41,7 @@
//! # use bevy_math::curve::{Curve, Interval, FunctionCurve}; //! # use bevy_math::curve::{Curve, Interval, FunctionCurve};
//! # use bevy_animation::{AnimationClip, AnimationTargetId, animated_field, animation_curves::*}; //! # use bevy_animation::{AnimationClip, AnimationTargetId, animated_field, animation_curves::*};
//! # use bevy_transform::components::Transform; //! # use bevy_transform::components::Transform;
//! # use bevy_core::Name; //! # use bevy_ecs::name::Name;
//! # use bevy_math::vec3; //! # use bevy_math::vec3;
//! # let wobble_curve = FunctionCurve::new( //! # let wobble_curve = FunctionCurve::new(
//! # Interval::UNIT, //! # 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::{AnimationClip, AnimationTargetId, VariableCurve, AnimationEntityMut, AnimationEvaluationError, animation_curves::EvaluatorId};
/// # use bevy_animation::prelude::{AnimatableProperty, AnimatableKeyframeCurve, AnimatableCurve}; /// # use bevy_animation::prelude::{AnimatableProperty, AnimatableKeyframeCurve, AnimatableCurve};
/// # use bevy_core::Name; /// # use bevy_ecs::name::Name;
/// # use bevy_reflect::Reflect; /// # use bevy_reflect::Reflect;
/// # use bevy_render::camera::PerspectiveProjection; /// # use bevy_render::camera::PerspectiveProjection;
/// # use std::any::TypeId; /// # use std::any::TypeId;

View File

@ -33,7 +33,6 @@ use crate::{
use bevy_app::{Animation, App, Plugin, PostUpdate}; use bevy_app::{Animation, App, Plugin, PostUpdate};
use bevy_asset::{Asset, AssetApp, Assets}; use bevy_asset::{Asset, AssetApp, Assets};
use bevy_core::Name;
use bevy_ecs::{ use bevy_ecs::{
entity::{VisitEntities, VisitEntitiesMut}, entity::{VisitEntities, VisitEntitiesMut},
prelude::*, prelude::*,

View File

@ -9,13 +9,11 @@
extern crate alloc; extern crate alloc;
mod name;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
mod serde; mod serde;
mod task_pool_options; mod task_pool_options;
use bevy_ecs::system::Resource; use bevy_ecs::system::Resource;
pub use name::*;
pub use task_pool_options::*; pub use task_pool_options::*;
/// The core prelude. /// 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. /// This includes the most common types in this crate, re-exported for your convenience.
pub mod prelude { pub mod prelude {
#[doc(hidden)] #[doc(hidden)]
pub use crate::{ pub use crate::{FrameCountPlugin, TaskPoolOptions, TaskPoolPlugin, TypeRegistrationPlugin};
FrameCountPlugin, Name, NameOrEntity, TaskPoolOptions, TaskPoolPlugin,
TypeRegistrationPlugin,
};
} }
use bevy_app::prelude::*; use bevy_app::prelude::*;

View File

@ -8,37 +8,7 @@ use serde::{
Deserialize, Deserializer, Serialize, Serializer, Deserialize, Deserializer, Serialize, Serializer,
}; };
use super::{name::Name, FrameCount}; use super::FrameCount;
impl Serialize for Name {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.as_str())
}
}
impl<'de> Deserialize<'de> for Name {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
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::<Name>())
}
fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
Ok(Name::new(v.to_string()))
}
fn visit_string<E: Error>(self, v: String) -> Result<Self::Value, E> {
Ok(Name::new(v))
}
}
// Manually implementing serialize/deserialize allows us to use a more compact representation as simple integers // Manually implementing serialize/deserialize allows us to use a more compact representation as simple integers
impl Serialize for FrameCount { impl Serialize for FrameCount {
@ -76,12 +46,6 @@ mod tests {
use serde_test::{assert_tokens, Token}; use serde_test::{assert_tokens, Token};
#[test]
fn test_serde_name() {
let name = Name::new("MyComponent");
assert_tokens(&name, &[Token::String("MyComponent")]);
}
#[test] #[test]
fn test_serde_frame_count() { fn test_serde_frame_count() {
let frame_count = FrameCount(100); let frame_count = FrameCount(100);

View File

@ -139,6 +139,7 @@ bumpalo = "3"
[dev-dependencies] [dev-dependencies]
rand = "0.8" rand = "0.8"
static_assertions = "1.1.0" static_assertions = "1.1.0"
serde_test = "1.0"
[[example]] [[example]]
name = "events" name = "events"

View File

@ -33,6 +33,7 @@ pub mod event;
pub mod identifier; pub mod identifier;
pub mod intern; pub mod intern;
pub mod label; pub mod label;
pub mod name;
pub mod observer; pub mod observer;
pub mod query; pub mod query;
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
@ -59,6 +60,7 @@ pub mod prelude {
component::{require, Component}, component::{require, Component},
entity::{Entity, EntityMapper}, entity::{Entity, EntityMapper},
event::{Event, EventMutator, EventReader, EventWriter, Events}, event::{Event, EventMutator, EventReader, EventWriter, Events},
name::{Name, NameOrEntity},
observer::{CloneEntityWithObserversExt, Observer, Trigger}, observer::{CloneEntityWithObserversExt, Observer, Trigger},
query::{Added, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without}, query::{Added, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without},
removal_detection::RemovedComponents, removal_detection::RemovedComponents,

View File

@ -1,18 +1,29 @@
#[cfg(feature = "bevy_reflect")] //! Provides the [`Name`] [`Component`], used for identifying an [`Entity`].
use bevy_ecs::reflect::ReflectComponent;
use bevy_ecs::{component::Component, entity::Entity, query::QueryData};
use alloc::borrow::Cow; use crate::{self as bevy_ecs, component::Component, entity::Entity, query::QueryData};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::std_traits::ReflectDefault; use alloc::{
#[cfg(feature = "bevy_reflect")] borrow::{Cow, ToOwned},
use bevy_reflect::Reflect; string::String,
};
use bevy_utils::FixedHasher; use bevy_utils::FixedHasher;
use core::{ use core::{
hash::{BuildHasher, Hash, Hasher}, hash::{BuildHasher, Hash, Hasher},
ops::Deref, 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"))] #[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; 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. /// Convenient query for giving a human friendly name to an entity.
/// ///
/// ``` /// ```
/// # use bevy_core::prelude::*;
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// # #[derive(Component)] pub struct Score(f32); /// # #[derive(Component)] pub struct Score(f32);
/// fn increment_score(mut scores: Query<(NameOrEntity, &mut Score)>) { /// fn increment_score(mut scores: Query<(NameOrEntity, &mut Score)>) {
/// for (name, mut score) in &mut scores { /// for (name, mut score) in &mut scores {
/// score.0 += 1.0; /// score.0 += 1.0;
/// if score.0.is_nan() { /// 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<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.as_str())
}
}
#[cfg(feature = "serialize")]
impl<'de> Deserialize<'de> for Name {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
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::<Name>())
}
fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
Ok(Name::new(v.to_string()))
}
fn visit_string<E: Error>(self, v: String) -> Result<Self::Value, E> {
Ok(Name::new(v))
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use bevy_ecs::world::World; use crate::world::World;
#[test] #[test]
fn test_display_of_debug_name() { fn test_display_of_debug_name() {
@ -233,3 +277,16 @@ mod tests {
assert_eq!(d2.to_string(), "MyName"); 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")]);
}
}

View File

@ -8,10 +8,10 @@ use bevy_asset::{
io::Reader, AssetLoadError, AssetLoader, Handle, LoadContext, ReadAssetBytesError, io::Reader, AssetLoadError, AssetLoader, Handle, LoadContext, ReadAssetBytesError,
}; };
use bevy_color::{Color, LinearRgba}; use bevy_color::{Color, LinearRgba};
use bevy_core::Name;
use bevy_core_pipeline::prelude::Camera3d; use bevy_core_pipeline::prelude::Camera3d;
use bevy_ecs::{ use bevy_ecs::{
entity::{Entity, EntityHashMap}, entity::{Entity, EntityHashMap},
name::Name,
world::World, world::World,
}; };
use bevy_hierarchy::{BuildChildren, ChildBuild, WorldChildBuilder}; use bevy_hierarchy::{BuildChildren, ChildBuild, WorldChildBuilder};

View File

@ -53,7 +53,7 @@ impl<T> Default for ReportHierarchyIssue<T> {
/// (See B0004 explanation linked in warning message) /// (See B0004 explanation linked in warning message)
pub fn check_hierarchy_component_has_valid_parent<T: Component>( pub fn check_hierarchy_component_has_valid_parent<T: Component>(
parent_query: Query< parent_query: Query<
(Entity, &Parent, Option<&bevy_core::Name>), (Entity, &Parent, Option<&Name>),
(With<T>, Or<(Changed<Parent>, Added<T>)>), (With<T>, Or<(Changed<Parent>, Added<T>)>),
>, >,
component_query: Query<(), With<T>>, component_query: Query<(), With<T>>,

View File

@ -1,7 +1,6 @@
//! The gamepad input functionality. //! The gamepad input functionality.
use crate::{Axis, ButtonInput, ButtonState}; use crate::{Axis, ButtonInput, ButtonState};
use bevy_core::Name;
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
use bevy_ecs::prelude::ReflectComponent; use bevy_ecs::prelude::ReflectComponent;
use bevy_ecs::{ use bevy_ecs::{
@ -9,6 +8,7 @@ use bevy_ecs::{
component::Component, component::Component,
entity::Entity, entity::Entity,
event::{Event, EventReader, EventWriter}, event::{Event, EventReader, EventWriter},
name::Name,
prelude::require, prelude::require,
system::{Commands, Query}, system::{Commands, Query},
}; };
@ -316,7 +316,7 @@ pub enum ButtonSettingsError {
/// ``` /// ```
/// # use bevy_input::gamepad::{Gamepad, GamepadAxis, GamepadButton}; /// # use bevy_input::gamepad::{Gamepad, GamepadAxis, GamepadButton};
/// # use bevy_ecs::system::Query; /// # use bevy_ecs::system::Query;
/// # use bevy_core::Name; /// # use bevy_ecs::name::Name;
/// # /// #
/// fn gamepad_usage_system(gamepads: Query<(&Name, &Gamepad)>) { /// fn gamepad_usage_system(gamepads: Query<(&Name, &Gamepad)>) {
/// for (name, gamepad) in &gamepads { /// for (name, gamepad) in &gamepads {