Improve DynamicStruct::insert (#11068)

# 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>>`.
This commit is contained in:
Doonv 2024-02-05 15:57:25 +02:00 committed by GitHub
parent 2fd5d4695e
commit 56076b7b0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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},
@ -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.