Skip to content

Commit

Permalink
Improve DynamicStruct::insert (bevyengine#11068)
Browse files Browse the repository at this point in the history
# Objective

I wanted to pass in a `String` to `DynamicStruct::insert_boxed` but it
took in a &str. That's fine but I also saw that it immediately converted
the `&str` to a `String`. Which is wasteful.

## Solution

I made `DynamicStruct::insert_boxed` take in a `impl Into<Cow<str>>`.
Same for `DynamicStruct::insert`.

---

## Changelog

- `DynamicStruct::insert_boxed` and `DynamicStruct::insert` now support
taking in anything that implements `impl Into<Cow<str>>`.
  • Loading branch information
doonv authored and tjamaan committed Feb 6, 2024
1 parent 47d88ae commit 0157425
Showing 1 changed file with 12 additions and 18 deletions.
30 changes: 12 additions & 18 deletions crates/bevy_reflect/src/struct_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
TypePath, TypePathTable,
};
use bevy_reflect_derive::impl_type_path;
use bevy_utils::{Entry, HashMap};
use bevy_utils::HashMap;
use std::fmt::{Debug, Formatter};
use std::{
any::{Any, TypeId},
Expand Down Expand Up @@ -300,29 +300,23 @@ impl DynamicStruct {
/// Inserts a field named `name` with value `value` into the struct.
///
/// If the field already exists, it is overwritten.
pub fn insert_boxed(&mut self, name: &str, value: Box<dyn Reflect>) {
let name = Cow::Owned(name.to_string());
match self.field_indices.entry(name) {
Entry::Occupied(entry) => {
self.fields[*entry.get()] = value;
}
Entry::Vacant(entry) => {
self.fields.push(value);
self.field_names.push(entry.key().clone());
entry.insert(self.fields.len() - 1);
}
pub fn insert_boxed<'a>(&mut self, name: impl Into<Cow<'a, str>>, value: Box<dyn Reflect>) {
let name: Cow<str> = name.into();
if let Some(index) = self.field_indices.get(&name) {
self.fields[*index] = value;
} else {
self.fields.push(value);
self.field_indices
.insert(Cow::Owned(name.clone().into_owned()), self.fields.len() - 1);
self.field_names.push(Cow::Owned(name.into_owned()));
}
}

/// Inserts a field named `name` with the typed value `value` into the struct.
///
/// If the field already exists, it is overwritten.
pub fn insert<T: Reflect>(&mut self, name: &str, value: T) {
if let Some(index) = self.field_indices.get(name) {
self.fields[*index] = Box::new(value);
} else {
self.insert_boxed(name, Box::new(value));
}
pub fn insert<'a, T: Reflect>(&mut self, name: impl Into<Cow<'a, str>>, value: T) {
self.insert_boxed(name, Box::new(value));
}

/// Gets the index of the field with the given name.
Expand Down

0 comments on commit 0157425

Please sign in to comment.