From 0867dc76a3c50c60f4b6d7e45daecede5c41ca8a Mon Sep 17 00:00:00 2001 From: Nathan Stocks Date: Sun, 31 Jan 2021 17:35:23 -0700 Subject: [PATCH] Use Cow<'static, str> in Name (#1308) * Implement Name { name } as Cow<'static, str> * Attempt impl Reflect for Cow<'static, str.> --- crates/bevy_core/src/name.rs | 17 +++---- crates/bevy_reflect/src/impls/std.rs | 67 +++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 9 deletions(-) diff --git a/crates/bevy_core/src/name.rs b/crates/bevy_core/src/name.rs index b0999773e8..fd2f4d9f78 100644 --- a/crates/bevy_core/src/name.rs +++ b/crates/bevy_core/src/name.rs @@ -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) -> Self { + pub fn new(name: impl Into>) -> 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>) { *self = Name::new(name); } #[inline(always)] pub fn mutate(&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 diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 0af5cead11..feae40b69a 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -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 Reflect for HashMap { + fn type_name(&self) -> &str { + std::any::type_name::() + } + + 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 = value.clone(); + } else { + panic!("Value is not a {}.", std::any::type_name::()); + } + } + + fn set(&mut self, value: Box) -> Result<(), Box> { + *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 { + Box::new(self.clone()) + } + + fn reflect_hash(&self) -> Option { + 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 { + let value = value.any(); + if let Some(value) = value.downcast_ref::() { + Some(std::cmp::PartialEq::eq(self, value)) + } else { + Some(false) + } + } + + fn serializable(&self) -> Option { + Some(Serializable::Borrowed(self)) + } +}