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_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;

View File

@ -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::*,

View File

@ -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::*;

View File

@ -8,37 +8,7 @@ use serde::{
Deserialize, Deserializer, Serialize, Serializer,
};
use super::{name::Name, 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))
}
}
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);

View File

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

View File

@ -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,

View File

@ -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<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)]
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")]);
}
}

View File

@ -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};

View File

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

View File

@ -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 {