The deserialzation hack..
This commit is contained in:
parent
1b6dec8f5a
commit
cc71436187
|
@ -1,7 +1,62 @@
|
||||||
|
use std::{alloc::Layout, num::NonZeroU32};
|
||||||
|
|
||||||
|
use bevy::{
|
||||||
|
log::{info, warn},
|
||||||
|
reflect::ReflectDeserialize,
|
||||||
|
};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
let real = Layout::new::<bevy::ecs::entity::Entity>();
|
||||||
|
let fake = Layout::new::<Entity>();
|
||||||
|
assert!(real.size() == fake.size());
|
||||||
|
assert!(real.align() == fake.align());
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
#[repr(C, align(8))]
|
||||||
pub(crate) struct Entity {
|
pub(crate) struct Entity {
|
||||||
pub name: Option<String>,
|
// Do not reorder the fields here. The ordering is equivalent to bevy's `Entity`
|
||||||
|
#[cfg(target_endian = "little")]
|
||||||
|
index: u32,
|
||||||
|
generation: NonZeroU32,
|
||||||
|
#[cfg(target_endian = "big")]
|
||||||
|
index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Entity {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename = "Entity")]
|
||||||
|
struct EntityData {
|
||||||
|
name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let entity_data = EntityData::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
let entity = if let Some(name) = entity_data.name {
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(unsafe {
|
||||||
|
// SAFETY: both have the same layout
|
||||||
|
core::mem::transmute(entity)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is expanded and modified from
|
||||||
|
// ```
|
||||||
|
// #[derive(Clone, Reflect)]
|
||||||
|
// #[reflect_value(Deserialize)]
|
||||||
|
// ```
|
||||||
const _: () = {
|
const _: () = {
|
||||||
use bevy::reflect as bevy_reflect;
|
use bevy::reflect as bevy_reflect;
|
||||||
|
|
||||||
|
@ -9,9 +64,6 @@ const _: () = {
|
||||||
impl bevy_reflect::GetTypeRegistration for Entity
|
impl bevy_reflect::GetTypeRegistration for Entity
|
||||||
where
|
where
|
||||||
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
||||||
Option<String>: bevy_reflect::FromReflect
|
|
||||||
+ bevy_reflect::TypePath
|
|
||||||
+ bevy_reflect::__macro_exports::RegisterForReflection,
|
|
||||||
{
|
{
|
||||||
fn get_type_registration() -> bevy_reflect::TypeRegistration {
|
fn get_type_registration() -> bevy_reflect::TypeRegistration {
|
||||||
let mut registration = bevy_reflect::TypeRegistration::of::<Self>();
|
let mut registration = bevy_reflect::TypeRegistration::of::<Self>();
|
||||||
|
@ -22,45 +74,16 @@ const _: () = {
|
||||||
registration.insert::<bevy_reflect::ReflectFromReflect>(
|
registration.insert::<bevy_reflect::ReflectFromReflect>(
|
||||||
bevy_reflect::FromType::<Self>::from_type(),
|
bevy_reflect::FromType::<Self>::from_type(),
|
||||||
);
|
);
|
||||||
|
registration.insert::<ReflectDeserialize>(bevy_reflect::FromType::<Self>::from_type());
|
||||||
registration
|
registration
|
||||||
}
|
}
|
||||||
#[inline(never)]
|
|
||||||
fn register_type_dependencies(registry: &mut bevy_reflect::TypeRegistry) {
|
|
||||||
<Option<String> as bevy_reflect::__macro_exports::RegisterForReflection>::__register(
|
|
||||||
registry,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl bevy_reflect::Typed for Entity
|
|
||||||
where
|
|
||||||
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
|
||||||
Option<String>: bevy_reflect::FromReflect
|
|
||||||
+ bevy_reflect::TypePath
|
|
||||||
+ bevy_reflect::__macro_exports::RegisterForReflection,
|
|
||||||
{
|
|
||||||
fn type_info() -> &'static bevy_reflect::TypeInfo {
|
|
||||||
static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
|
|
||||||
bevy_reflect::utility::NonGenericTypeInfoCell::new();
|
|
||||||
CELL.get_or_set(|| {
|
|
||||||
bevy_reflect::TypeInfo::Struct(
|
|
||||||
bevy_reflect::StructInfo::new::<bevy::ecs::entity::Entity>(&[
|
|
||||||
// TODO: changed here
|
|
||||||
bevy_reflect::NamedField::new::<Option<String>>("name")
|
|
||||||
.with_custom_attributes(
|
|
||||||
bevy_reflect::attributes::CustomAttributes::default(),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
.with_custom_attributes(bevy_reflect::attributes::CustomAttributes::default()),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl bevy_reflect::TypePath for Entity
|
impl bevy_reflect::TypePath for Entity
|
||||||
where
|
where
|
||||||
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
||||||
{
|
{
|
||||||
fn type_path() -> &'static str {
|
fn type_path() -> &'static str {
|
||||||
"bevy_ecs::entity::Entity"
|
"bevy_ecs::entity::Entity" // this is changed
|
||||||
}
|
}
|
||||||
fn short_type_path() -> &'static str {
|
fn short_type_path() -> &'static str {
|
||||||
"Entity"
|
"Entity"
|
||||||
|
@ -69,74 +92,29 @@ const _: () = {
|
||||||
::core::option::Option::Some("Entity")
|
::core::option::Option::Some("Entity")
|
||||||
}
|
}
|
||||||
fn crate_name() -> Option<&'static str> {
|
fn crate_name() -> Option<&'static str> {
|
||||||
|
// this is changed
|
||||||
::core::option::Option::Some("bevy_ecs::entity".split(':').next().unwrap())
|
::core::option::Option::Some("bevy_ecs::entity".split(':').next().unwrap())
|
||||||
}
|
}
|
||||||
fn module_path() -> Option<&'static str> {
|
fn module_path() -> Option<&'static str> {
|
||||||
::core::option::Option::Some("bevy_ecs::entity")
|
::core::option::Option::Some("bevy_ecs::entity") // this is changed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl bevy_reflect::Struct for Entity
|
impl bevy_reflect::Typed for Entity
|
||||||
where
|
where
|
||||||
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
||||||
Option<String>: bevy_reflect::FromReflect
|
|
||||||
+ bevy_reflect::TypePath
|
|
||||||
+ bevy_reflect::__macro_exports::RegisterForReflection,
|
|
||||||
{
|
{
|
||||||
fn field(&self, name: &str) -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
|
fn type_info() -> &'static bevy_reflect::TypeInfo {
|
||||||
match name {
|
static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
|
||||||
"name" => ::core::option::Option::Some(&self.name),
|
bevy_reflect::utility::NonGenericTypeInfoCell::new();
|
||||||
_ => ::core::option::Option::None,
|
CELL.get_or_set(|| {
|
||||||
}
|
let info = bevy_reflect::ValueInfo::new::<bevy::ecs::entity::Entity>(); // this is changed
|
||||||
}
|
bevy_reflect::TypeInfo::Value(info)
|
||||||
fn field_mut(
|
})
|
||||||
&mut self,
|
|
||||||
name: &str,
|
|
||||||
) -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
|
|
||||||
match name {
|
|
||||||
"name" => ::core::option::Option::Some(&mut self.name),
|
|
||||||
_ => ::core::option::Option::None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn field_at(&self, index: usize) -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
|
|
||||||
match index {
|
|
||||||
0usize => ::core::option::Option::Some(&self.name),
|
|
||||||
_ => ::core::option::Option::None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn field_at_mut(
|
|
||||||
&mut self,
|
|
||||||
index: usize,
|
|
||||||
) -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
|
|
||||||
match index {
|
|
||||||
0usize => ::core::option::Option::Some(&mut self.name),
|
|
||||||
_ => ::core::option::Option::None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
|
|
||||||
match index {
|
|
||||||
0usize => ::core::option::Option::Some("name"),
|
|
||||||
_ => ::core::option::Option::None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn field_len(&self) -> usize {
|
|
||||||
1usize
|
|
||||||
}
|
|
||||||
fn iter_fields(&self) -> bevy_reflect::FieldIter {
|
|
||||||
bevy_reflect::FieldIter::new(self)
|
|
||||||
}
|
|
||||||
fn clone_dynamic(&self) -> bevy_reflect::DynamicStruct {
|
|
||||||
let mut dynamic: bevy_reflect::DynamicStruct = ::core::default::Default::default();
|
|
||||||
dynamic.set_represented_type(bevy_reflect::Reflect::get_represented_type_info(self));
|
|
||||||
dynamic.insert_boxed("name", bevy_reflect::Reflect::clone_value(&self.name));
|
|
||||||
dynamic
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl bevy_reflect::Reflect for Entity
|
impl bevy_reflect::Reflect for Entity
|
||||||
where
|
where
|
||||||
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
||||||
Option<String>: bevy_reflect::FromReflect
|
|
||||||
+ bevy_reflect::TypePath
|
|
||||||
+ bevy_reflect::__macro_exports::RegisterForReflection,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_represented_type_info(
|
fn get_represented_type_info(
|
||||||
|
@ -172,7 +150,29 @@ const _: () = {
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone_value(&self) -> ::std::boxed::Box<dyn bevy_reflect::Reflect> {
|
fn clone_value(&self) -> ::std::boxed::Box<dyn bevy_reflect::Reflect> {
|
||||||
::std::boxed::Box::new(bevy_reflect::Struct::clone_dynamic(self))
|
::std::boxed::Box::new(::core::clone::Clone::clone(self))
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn try_apply(
|
||||||
|
&mut self,
|
||||||
|
value: &dyn bevy_reflect::Reflect,
|
||||||
|
) -> ::core::result::Result<(), bevy_reflect::ApplyError> {
|
||||||
|
let any = bevy_reflect::Reflect::as_any(value);
|
||||||
|
if let ::core::option::Option::Some(value) =
|
||||||
|
<dyn ::core::any::Any>::downcast_ref::<Self>(any)
|
||||||
|
{
|
||||||
|
*self = ::core::clone::Clone::clone(value);
|
||||||
|
} else {
|
||||||
|
return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedTypes {
|
||||||
|
from_type: ::core::convert::Into::into(
|
||||||
|
bevy_reflect::DynamicTypePath::reflect_type_path(value),
|
||||||
|
),
|
||||||
|
to_type: ::core::convert::Into::into(
|
||||||
|
<Self as bevy_reflect::TypePath>::type_path(),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
::core::result::Result::Ok(())
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set(
|
fn set(
|
||||||
|
@ -183,75 +183,32 @@ const _: () = {
|
||||||
::core::result::Result::Ok(())
|
::core::result::Result::Ok(())
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_apply(
|
|
||||||
&mut self,
|
|
||||||
value: &dyn bevy_reflect::Reflect,
|
|
||||||
) -> ::core::result::Result<(), bevy_reflect::ApplyError> {
|
|
||||||
if let bevy_reflect::ReflectRef::Struct(struct_value) =
|
|
||||||
bevy_reflect::Reflect::reflect_ref(value)
|
|
||||||
{
|
|
||||||
for (i, value) in ::core::iter::Iterator::enumerate(
|
|
||||||
bevy_reflect::Struct::iter_fields(struct_value),
|
|
||||||
) {
|
|
||||||
let name = bevy_reflect::Struct::name_at(struct_value, i).unwrap();
|
|
||||||
if let ::core::option::Option::Some(v) =
|
|
||||||
bevy_reflect::Struct::field_mut(self, name)
|
|
||||||
{
|
|
||||||
bevy_reflect::Reflect::try_apply(v, value)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
|
|
||||||
from_kind: bevy_reflect::Reflect::reflect_kind(value),
|
|
||||||
to_kind: bevy_reflect::ReflectKind::Struct,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
::core::result::Result::Ok(())
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
|
fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
|
||||||
bevy_reflect::ReflectKind::Struct
|
bevy_reflect::ReflectKind::Value
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
|
fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
|
||||||
bevy_reflect::ReflectRef::Struct(self)
|
bevy_reflect::ReflectRef::Value(self)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
|
fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
|
||||||
bevy_reflect::ReflectMut::Struct(self)
|
bevy_reflect::ReflectMut::Value(self)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reflect_owned(self: ::std::boxed::Box<Self>) -> bevy_reflect::ReflectOwned {
|
fn reflect_owned(self: ::std::boxed::Box<Self>) -> bevy_reflect::ReflectOwned {
|
||||||
bevy_reflect::ReflectOwned::Struct(self)
|
bevy_reflect::ReflectOwned::Value(self)
|
||||||
}
|
|
||||||
fn reflect_partial_eq(
|
|
||||||
&self,
|
|
||||||
value: &dyn bevy_reflect::Reflect,
|
|
||||||
) -> ::core::option::Option<bool> {
|
|
||||||
bevy_reflect::struct_partial_eq(self, value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl bevy_reflect::FromReflect for Entity
|
impl bevy_reflect::FromReflect for Entity
|
||||||
where
|
where
|
||||||
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
Self: ::core::any::Any + ::core::marker::Send + ::core::marker::Sync,
|
||||||
Option<String>: bevy_reflect::FromReflect
|
|
||||||
+ bevy_reflect::TypePath
|
|
||||||
+ bevy_reflect::__macro_exports::RegisterForReflection,
|
|
||||||
{
|
{
|
||||||
fn from_reflect(reflect: &dyn bevy_reflect::Reflect) -> ::core::option::Option<Self> {
|
fn from_reflect(reflect: &dyn bevy_reflect::Reflect) -> ::core::option::Option<Self> {
|
||||||
if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
|
::core::option::Option::Some(::core::clone::Clone::clone(
|
||||||
bevy_reflect::Reflect::reflect_ref(reflect)
|
<dyn ::core::any::Any>::downcast_ref::<Entity>(
|
||||||
{
|
<dyn bevy_reflect::Reflect>::as_any(reflect),
|
||||||
::core::option::Option::Some(Self {
|
)?,
|
||||||
name: (|| {
|
))
|
||||||
<Option<String> as bevy_reflect::FromReflect>::from_reflect(
|
|
||||||
bevy_reflect::Struct::field(__ref_struct, "name")?,
|
|
||||||
)
|
|
||||||
})()?,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
::core::option::Option::None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,8 +8,6 @@ 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;
|
||||||
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
use bevy::{
|
|
||||||
log::{info, warn},
|
|
||||||
prelude::Entity,
|
|
||||||
reflect::{FromReflect, Reflect},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{fake_entity, reflect_ext};
|
|
||||||
|
|
||||||
pub fn patch_reflect_entity(reflect: &mut dyn Reflect) -> Option<Entity> {
|
|
||||||
let maybe_fake = fake_entity::Entity::from_reflect(reflect).map(|fake| fake.name.clone());
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
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> {}
|
|
|
@ -1,36 +0,0 @@
|
||||||
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> {}
|
|
|
@ -1,36 +0,0 @@
|
||||||
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> {}
|
|
|
@ -1,34 +0,0 @@
|
||||||
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> {}
|
|
|
@ -1,56 +0,0 @@
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
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> {}
|
|
|
@ -1,35 +0,0 @@
|
||||||
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> {}
|
|
|
@ -1,35 +0,0 @@
|
||||||
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, patch_entity::patch_reflect_entity};
|
use super::{capitalize_first_letter, fake_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 mut component = reflect_deserializer
|
let component = reflect_deserializer
|
||||||
.deserialize(&mut deserializer)
|
.deserialize(&mut deserializer)
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -136,8 +136,6 @@ 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