mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Use Cow<'static, str> in Name (#1308)
* Implement Name { name } as Cow<'static, str> * Attempt impl Reflect for Cow<'static, str.>
This commit is contained in:
parent
7d065eeb71
commit
0867dc76a3
2 changed files with 75 additions and 9 deletions
|
@ -1,26 +1,27 @@
|
|||
use bevy_reflect::{Reflect, ReflectComponent};
|
||||
use bevy_utils::AHasher;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
hash::{Hash, Hasher},
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
/// Component used to identify a entity. Stores a hash for faster comparisons
|
||||
/// Component used to identify an 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,
|
||||
name: Cow<'static, str>,
|
||||
}
|
||||
|
||||
impl Default for Name {
|
||||
fn default() -> Self {
|
||||
Name::new("".to_string())
|
||||
Name::new("")
|
||||
}
|
||||
}
|
||||
|
||||
impl Name {
|
||||
pub fn new(name: impl Into<String>) -> Self {
|
||||
pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
|
||||
let name = name.into();
|
||||
let mut name = Name { name, hash: 0 };
|
||||
name.update_hash();
|
||||
|
@ -28,19 +29,19 @@ impl Name {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set(&mut self, name: String) {
|
||||
pub fn set(&mut self, name: impl Into<Cow<'static, str>>) {
|
||||
*self = Name::new(name);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn mutate<F: FnOnce(&mut String)>(&mut self, f: F) {
|
||||
f(&mut self.name);
|
||||
f(self.name.to_mut());
|
||||
self.update_hash();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.name.as_str()
|
||||
&self.name
|
||||
}
|
||||
|
||||
fn update_hash(&mut self) {
|
||||
|
@ -89,7 +90,7 @@ impl Ord for Name {
|
|||
}
|
||||
|
||||
impl Deref for Name {
|
||||
type Target = String;
|
||||
type Target = Cow<'static, str>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.name
|
||||
|
|
|
@ -6,7 +6,12 @@ use crate::{
|
|||
use bevy_reflect_derive::impl_reflect_value;
|
||||
use bevy_utils::{HashMap, HashSet};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{any::Any, hash::Hash, ops::Range};
|
||||
use std::{
|
||||
any::Any,
|
||||
borrow::Cow,
|
||||
hash::{Hash, Hasher},
|
||||
ops::Range,
|
||||
};
|
||||
|
||||
impl_reflect_value!(bool(Hash, PartialEq, Serialize, Deserialize));
|
||||
impl_reflect_value!(u8(Hash, PartialEq, Serialize, Deserialize));
|
||||
|
@ -199,3 +204,63 @@ impl<K: Reflect + Clone + Eq + Hash, V: Reflect + Clone> Reflect for HashMap<K,
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for Cow<'static, str> {
|
||||
fn type_name(&self) -> &str {
|
||||
std::any::type_name::<Self>()
|
||||
}
|
||||
|
||||
fn any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn any_mut(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn apply(&mut self, value: &dyn Reflect) {
|
||||
let value = value.any();
|
||||
if let Some(value) = value.downcast_ref::<Self>() {
|
||||
*self = value.clone();
|
||||
} else {
|
||||
panic!("Value is not a {}.", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
|
||||
*self = value.take()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reflect_ref(&self) -> ReflectRef {
|
||||
ReflectRef::Value(self)
|
||||
}
|
||||
|
||||
fn reflect_mut(&mut self) -> ReflectMut {
|
||||
ReflectMut::Value(self)
|
||||
}
|
||||
|
||||
fn clone_value(&self) -> Box<dyn Reflect> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
fn reflect_hash(&self) -> Option<u64> {
|
||||
let mut hasher = crate::ReflectHasher::default();
|
||||
Hash::hash(&std::any::Any::type_id(self), &mut hasher);
|
||||
Hash::hash(self, &mut hasher);
|
||||
Some(hasher.finish())
|
||||
}
|
||||
|
||||
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
|
||||
let value = value.any();
|
||||
if let Some(value) = value.downcast_ref::<Self>() {
|
||||
Some(std::cmp::PartialEq::eq(self, value))
|
||||
} else {
|
||||
Some(false)
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Option<Serializable> {
|
||||
Some(Serializable::Borrowed(self))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue