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:
Nathan Stocks 2021-01-31 17:35:23 -07:00 committed by GitHub
parent 7d065eeb71
commit 0867dc76a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 9 deletions

View file

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

View file

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