I cracked reflection?
This commit is contained in:
parent
72681ee9f0
commit
0ad9f13f1d
|
@ -1,5 +1,5 @@
|
||||||
pub(crate) struct Entity {
|
pub(crate) struct Entity {
|
||||||
name: Option<String>,
|
pub name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const _: () = {
|
const _: () = {
|
||||||
|
|
|
@ -8,6 +8,8 @@ pub mod process_gltfs;
|
||||||
pub use process_gltfs::*;
|
pub use process_gltfs::*;
|
||||||
|
|
||||||
mod fake_entity;
|
mod fake_entity;
|
||||||
|
mod patch_entity;
|
||||||
|
mod reflect_ext;
|
||||||
|
|
||||||
pub mod blender_settings;
|
pub mod blender_settings;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
use bevy::{
|
||||||
|
log::{info, warn},
|
||||||
|
prelude::Entity,
|
||||||
|
reflect::Reflect,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{fake_entity, reflect_ext};
|
||||||
|
|
||||||
|
pub fn patch_reflect_entity(reflect: &mut dyn Reflect) -> Option<Entity> {
|
||||||
|
// We can put here either `fake_entity::Entity` or `bevy::ecs::entity::Entity`, but the latter would result in a false downcast.
|
||||||
|
let maybe_fake = reflect
|
||||||
|
.downcast_mut::<fake_entity::Entity>() // TODO: doesn't work yet, seems like it doesnt work when it's a dynamic type
|
||||||
|
.map(|fake| fake.name.clone());
|
||||||
|
|
||||||
|
info!("{}", reflect.reflect_type_ident().unwrap());
|
||||||
|
|
||||||
|
if let Some(reference) = maybe_fake {
|
||||||
|
let entity = if let Some(name) = reference {
|
||||||
|
info!("Found name {name}");
|
||||||
|
bevy::ecs::entity::Entity::PLACEHOLDER
|
||||||
|
} else {
|
||||||
|
warn!("No object was specified for Entity relation, using `Entity::PLACEHOLDER`.");
|
||||||
|
bevy::ecs::entity::Entity::PLACEHOLDER
|
||||||
|
};
|
||||||
|
Some(entity)
|
||||||
|
} else {
|
||||||
|
let reflect_mut = reflect.reflect_mut();
|
||||||
|
let iter = reflect_ext::DynamicFieldIterMut::from_reflect_mut(reflect_mut);
|
||||||
|
// TODO: recursively update
|
||||||
|
for f in iter {
|
||||||
|
patch_reflect_entity(f);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
use bevy::reflect::{Array, Reflect};
|
||||||
|
|
||||||
|
pub struct ArrayIterMut<'a> {
|
||||||
|
array: &'a mut dyn Array,
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ArrayIterMut<'a> {
|
||||||
|
/// Creates a new [`ArrayIterMut`].
|
||||||
|
#[inline]
|
||||||
|
pub fn new(array: &'a mut dyn Array) -> ArrayIterMut {
|
||||||
|
ArrayIterMut { array, index: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for ArrayIterMut<'a> {
|
||||||
|
type Item = &'a mut dyn Reflect;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let value = self.array.get_mut(self.index);
|
||||||
|
self.index += value.is_some() as usize;
|
||||||
|
value.map(|v| unsafe {
|
||||||
|
// SAFETY: index can only correspond to one field
|
||||||
|
&mut *(v as *mut _)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let size = self.array.len();
|
||||||
|
(size, Some(size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for ArrayIterMut<'a> {}
|
|
@ -0,0 +1,36 @@
|
||||||
|
use bevy::reflect::{Enum, Reflect};
|
||||||
|
|
||||||
|
pub struct VariantFieldIterMut<'a> {
|
||||||
|
container: &'a mut dyn Enum,
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> VariantFieldIterMut<'a> {
|
||||||
|
pub fn new(container: &'a mut dyn Enum) -> Self {
|
||||||
|
Self {
|
||||||
|
container,
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for VariantFieldIterMut<'a> {
|
||||||
|
// TODO: make this work with `VariantFieldMut` again
|
||||||
|
type Item = &'a mut dyn Reflect;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let value = self.container.field_at_mut(self.index);
|
||||||
|
self.index += value.is_some() as usize;
|
||||||
|
value.map(|v| unsafe {
|
||||||
|
// SAFETY: index can only correspond to one field
|
||||||
|
&mut *(v as *mut _)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let size = self.container.field_len();
|
||||||
|
(size, Some(size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for VariantFieldIterMut<'a> {}
|
|
@ -0,0 +1,36 @@
|
||||||
|
use bevy::reflect::{List, Reflect};
|
||||||
|
|
||||||
|
pub struct ListIterMut<'a> {
|
||||||
|
list: &'a mut dyn List,
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ListIterMut<'a> {
|
||||||
|
/// Creates a new [`ListIterMut`].
|
||||||
|
#[inline]
|
||||||
|
pub fn new(list: &'a mut dyn List) -> ListIterMut {
|
||||||
|
ListIterMut { list, index: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for ListIterMut<'a> {
|
||||||
|
type Item = &'a mut dyn Reflect;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let value = self.list.get_mut(self.index);
|
||||||
|
self.index += value.is_some() as usize;
|
||||||
|
value.map(|v| unsafe {
|
||||||
|
// SAFETY: index can only correspond to one field
|
||||||
|
&mut *(v as *mut _)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let size = self.list.len();
|
||||||
|
(size, Some(size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for ListIterMut<'a> {}
|
|
@ -0,0 +1,34 @@
|
||||||
|
use bevy::reflect::{Map, Reflect};
|
||||||
|
|
||||||
|
pub struct MapIterMut<'a> {
|
||||||
|
map: &'a mut dyn Map,
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> MapIterMut<'a> {
|
||||||
|
/// Creates a new [`MapIterMut`].
|
||||||
|
#[inline]
|
||||||
|
pub fn new(map: &'a mut dyn Map) -> MapIterMut {
|
||||||
|
MapIterMut { map, index: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for MapIterMut<'a> {
|
||||||
|
type Item = (&'a dyn Reflect, &'a mut dyn Reflect);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let value = self.map.get_at_mut(self.index);
|
||||||
|
self.index += value.is_some() as usize;
|
||||||
|
value.map(|(k, v)| unsafe {
|
||||||
|
// SAFETY: index can only correspond to one field
|
||||||
|
(&*(k as *const _), &mut *(v as *mut _))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let size = self.map.len();
|
||||||
|
(size, Some(size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for MapIterMut<'a> {}
|
|
@ -0,0 +1,56 @@
|
||||||
|
use bevy::reflect::{Reflect, ReflectMut};
|
||||||
|
|
||||||
|
pub mod array_ext;
|
||||||
|
pub mod enum_ext;
|
||||||
|
pub mod list_ext;
|
||||||
|
pub mod map_ext;
|
||||||
|
pub mod struct_ext;
|
||||||
|
pub mod tuple_ext;
|
||||||
|
pub mod tuple_struct_ext;
|
||||||
|
|
||||||
|
pub enum DynamicFieldIterMut<'a> {
|
||||||
|
Struct(struct_ext::FieldIterMut<'a>),
|
||||||
|
TupleStruct(tuple_struct_ext::TupleStructFieldIterMut<'a>),
|
||||||
|
Tuple(tuple_ext::TupleFieldIterMut<'a>),
|
||||||
|
List(list_ext::ListIterMut<'a>),
|
||||||
|
Array(array_ext::ArrayIterMut<'a>),
|
||||||
|
Map(map_ext::MapIterMut<'a>),
|
||||||
|
Enum(enum_ext::VariantFieldIterMut<'a>),
|
||||||
|
Value,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DynamicFieldIterMut<'a> {
|
||||||
|
pub fn from_reflect_mut(ref_mut: ReflectMut<'a>) -> Self {
|
||||||
|
match ref_mut {
|
||||||
|
ReflectMut::Struct(s) => DynamicFieldIterMut::Struct(struct_ext::FieldIterMut::new(s)),
|
||||||
|
ReflectMut::TupleStruct(s) => {
|
||||||
|
DynamicFieldIterMut::TupleStruct(tuple_struct_ext::TupleStructFieldIterMut::new(s))
|
||||||
|
}
|
||||||
|
ReflectMut::Tuple(t) => {
|
||||||
|
DynamicFieldIterMut::Tuple(tuple_ext::TupleFieldIterMut::new(t))
|
||||||
|
}
|
||||||
|
ReflectMut::List(l) => DynamicFieldIterMut::List(list_ext::ListIterMut::new(l)),
|
||||||
|
ReflectMut::Array(a) => DynamicFieldIterMut::Array(array_ext::ArrayIterMut::new(a)),
|
||||||
|
ReflectMut::Map(m) => DynamicFieldIterMut::Map(map_ext::MapIterMut::new(m)),
|
||||||
|
ReflectMut::Enum(e) => DynamicFieldIterMut::Enum(enum_ext::VariantFieldIterMut::new(e)),
|
||||||
|
ReflectMut::Value(_) => DynamicFieldIterMut::Value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for DynamicFieldIterMut<'a> {
|
||||||
|
type Item = &'a mut dyn Reflect;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
match self {
|
||||||
|
DynamicFieldIterMut::Struct(s) => s.next(),
|
||||||
|
DynamicFieldIterMut::TupleStruct(s) => s.next(),
|
||||||
|
DynamicFieldIterMut::Tuple(t) => t.next(),
|
||||||
|
DynamicFieldIterMut::List(l) => l.next(),
|
||||||
|
DynamicFieldIterMut::Array(a) => a.next(),
|
||||||
|
DynamicFieldIterMut::Map(m) => m.next().map(|(_, v)| v),
|
||||||
|
DynamicFieldIterMut::Enum(e) => e.next(),
|
||||||
|
DynamicFieldIterMut::Value => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
use bevy::reflect::{Reflect, Struct};
|
||||||
|
|
||||||
|
/// An iterator over the field values of a struct.
|
||||||
|
pub struct FieldIterMut<'a> {
|
||||||
|
pub(crate) struct_val: &'a mut dyn Struct,
|
||||||
|
pub(crate) index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FieldIterMut<'a> {
|
||||||
|
pub fn new(value: &'a mut dyn Struct) -> Self {
|
||||||
|
FieldIterMut {
|
||||||
|
struct_val: value,
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for FieldIterMut<'a> {
|
||||||
|
type Item = &'a mut dyn Reflect;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let value = self.struct_val.field_at_mut(self.index);
|
||||||
|
self.index += value.is_some() as usize;
|
||||||
|
value.map(|v| unsafe {
|
||||||
|
// SAFETY: index can only correspond to one field
|
||||||
|
&mut *(v as *mut _)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let size = self.struct_val.field_len();
|
||||||
|
(size, Some(size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for FieldIterMut<'a> {}
|
|
@ -0,0 +1,35 @@
|
||||||
|
use bevy::reflect::{Reflect, Tuple};
|
||||||
|
|
||||||
|
pub struct TupleFieldIterMut<'a> {
|
||||||
|
pub(crate) tuple: &'a mut dyn Tuple,
|
||||||
|
pub(crate) index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TupleFieldIterMut<'a> {
|
||||||
|
pub fn new(value: &'a mut dyn Tuple) -> Self {
|
||||||
|
TupleFieldIterMut {
|
||||||
|
tuple: value,
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for TupleFieldIterMut<'a> {
|
||||||
|
type Item = &'a mut dyn Reflect;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let value = self.tuple.field_mut(self.index);
|
||||||
|
self.index += value.is_some() as usize;
|
||||||
|
value.map(|v| unsafe {
|
||||||
|
// SAFETY: index can only correspond to one field
|
||||||
|
&mut *(v as *mut _)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let size = self.tuple.field_len();
|
||||||
|
(size, Some(size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for TupleFieldIterMut<'a> {}
|
|
@ -0,0 +1,35 @@
|
||||||
|
use bevy::reflect::{Reflect, TupleStruct};
|
||||||
|
|
||||||
|
pub struct TupleStructFieldIterMut<'a> {
|
||||||
|
pub(crate) tuple_struct: &'a mut dyn TupleStruct,
|
||||||
|
pub(crate) index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TupleStructFieldIterMut<'a> {
|
||||||
|
pub fn new(value: &'a mut dyn TupleStruct) -> Self {
|
||||||
|
TupleStructFieldIterMut {
|
||||||
|
tuple_struct: value,
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for TupleStructFieldIterMut<'a> {
|
||||||
|
type Item = &'a mut dyn Reflect;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let value = self.tuple_struct.field_mut(self.index);
|
||||||
|
self.index += value.is_some() as usize;
|
||||||
|
value.map(|v| unsafe {
|
||||||
|
// SAFETY: index can only correspond to one field
|
||||||
|
&mut *(v as *mut _)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let size = self.tuple_struct.field_len();
|
||||||
|
(size, Some(size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for TupleStructFieldIterMut<'a> {}
|
|
@ -7,7 +7,7 @@ use bevy::utils::HashMap;
|
||||||
use ron::Value;
|
use ron::Value;
|
||||||
use serde::de::DeserializeSeed;
|
use serde::de::DeserializeSeed;
|
||||||
|
|
||||||
use super::{capitalize_first_letter, fake_entity};
|
use super::{capitalize_first_letter, fake_entity, patch_entity::patch_reflect_entity};
|
||||||
|
|
||||||
pub fn ronstring_to_reflect_component(
|
pub fn ronstring_to_reflect_component(
|
||||||
ron_string: &str,
|
ron_string: &str,
|
||||||
|
@ -127,7 +127,7 @@ fn bevy_components_string_to_components(
|
||||||
let mut deserializer = ron::Deserializer::from_str(ron_string.as_str())
|
let mut deserializer = ron::Deserializer::from_str(ron_string.as_str())
|
||||||
.expect("deserialzer should have been generated from string");
|
.expect("deserialzer should have been generated from string");
|
||||||
let reflect_deserializer = ReflectDeserializer::new(type_registry);
|
let reflect_deserializer = ReflectDeserializer::new(type_registry);
|
||||||
let component = reflect_deserializer
|
let mut component = reflect_deserializer
|
||||||
.deserialize(&mut deserializer)
|
.deserialize(&mut deserializer)
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -136,6 +136,8 @@ fn bevy_components_string_to_components(
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
patch_reflect_entity(component.as_mut());
|
||||||
|
|
||||||
debug!("component {:?}", component);
|
debug!("component {:?}", component);
|
||||||
debug!("real type {:?}", component.get_represented_type_info());
|
debug!("real type {:?}", component.get_represented_type_info());
|
||||||
components.push((component, type_registration.clone()));
|
components.push((component, type_registration.clone()));
|
||||||
|
|
Loading…
Reference in New Issue