Name component with fast comparisons (#1109)
Name component with fast comparisons
This commit is contained in:
parent
6531fcdfd2
commit
30fd302c7e
@ -20,4 +20,4 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.4.0" }
|
||||
bevy_math = { path = "../bevy_math", version = "0.4.0" }
|
||||
bevy_reflect = { path = "../bevy_reflect", version = "0.4.0", features = ["bevy"] }
|
||||
bevy_tasks = { path = "../bevy_tasks", version = "0.4.0" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }
|
@ -1,6 +1,7 @@
|
||||
mod bytes;
|
||||
mod float_ord;
|
||||
mod label;
|
||||
mod name;
|
||||
mod task_pool_options;
|
||||
mod time;
|
||||
|
||||
@ -11,6 +12,7 @@ use bevy_reflect::RegisterTypeBuilder;
|
||||
pub use bytes::*;
|
||||
pub use float_ord::*;
|
||||
pub use label::*;
|
||||
pub use name::*;
|
||||
pub use task_pool_options::DefaultTaskPoolOptions;
|
||||
pub use time::*;
|
||||
|
||||
@ -36,6 +38,7 @@ impl Plugin for CorePlugin {
|
||||
.init_resource::<EntityLabels>()
|
||||
.init_resource::<FixedTimesteps>()
|
||||
.register_type::<Option<String>>()
|
||||
.register_type::<Name>()
|
||||
.register_type::<Labels>()
|
||||
.register_type::<Range<f32>>()
|
||||
.register_type::<Timer>()
|
||||
|
96
crates/bevy_core/src/name.rs
Normal file
96
crates/bevy_core/src/name.rs
Normal file
@ -0,0 +1,96 @@
|
||||
use bevy_reflect::{Reflect, ReflectComponent};
|
||||
use bevy_utils::AHasher;
|
||||
use std::{
|
||||
hash::{Hash, Hasher},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
/// Component used to identify a entity. Stores a hash for faster comparisons
|
||||
#[derive(Debug, Clone, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct Name {
|
||||
hash: u64, // TODO: Shouldn't be serialized
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl Default for Name {
|
||||
fn default() -> Self {
|
||||
Name::new("".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Name {
|
||||
pub fn new(name: String) -> Self {
|
||||
let mut name = Name { name, hash: 0 };
|
||||
name.update_hash();
|
||||
name
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set(&mut self, name: String) {
|
||||
*self = Name::new(name);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn mutate<F: FnOnce(&mut String)>(&mut self, f: F) {
|
||||
f(&mut self.name);
|
||||
self.update_hash();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
fn update_hash(&mut self) {
|
||||
let mut hasher = AHasher::default();
|
||||
self.name.hash(&mut hasher);
|
||||
self.hash = hasher.finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Name {
|
||||
#[inline(always)]
|
||||
fn from(name: &str) -> Self {
|
||||
Name::new(name.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for Name {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.name.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Name {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if self.hash != other.hash {
|
||||
// Makes the common case of two strings not been equal very fast
|
||||
return false;
|
||||
}
|
||||
|
||||
self.name.eq(&other.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Name {}
|
||||
|
||||
impl PartialOrd for Name {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
self.name.partial_cmp(&other.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Name {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.name.cmp(&other.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Name {
|
||||
type Target = String;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.name
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user