reflect: remove manual Reflect impls which could be handled by macros (#12596)
# Objective * Adopted #12025 to fix merge conflicts * In some cases we used manual impls for certain types, though they are (at least, now) unnecessary. ## Solution * Use macros and reflecting-by-value to avoid this clutter. * Though there were linker issues with Reflect and the CowArc in AssetPath (see https://github.com/bevyengine/bevy/issues/9747), I checked these are resolved by using #[reflect_value]. --------- Co-authored-by: soqb <cb.setho@gmail.com> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: James Liu <contact@jamessliu.com>
This commit is contained in:
parent
037f9d414b
commit
fdf2ea7cc5
@ -1,15 +1,10 @@
|
||||
use crate::io::AssetSourceId;
|
||||
use bevy_reflect::{
|
||||
std_traits::ReflectDefault, utility::NonGenericTypeInfoCell, FromReflect, FromType,
|
||||
GetTypeRegistration, Reflect, ReflectDeserialize, ReflectFromPtr, ReflectFromReflect,
|
||||
ReflectKind, ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, TypeInfo, TypePath,
|
||||
TypeRegistration, Typed, ValueInfo,
|
||||
};
|
||||
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||
use bevy_utils::CowArc;
|
||||
use serde::{de::Visitor, Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
hash::{Hash, Hasher},
|
||||
hash::Hash,
|
||||
ops::Deref,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
@ -52,7 +47,8 @@ use thiserror::Error;
|
||||
/// This means that the common case of `asset_server.load("my_scene.scn")` when it creates and
|
||||
/// clones internal owned [`AssetPaths`](AssetPath).
|
||||
/// This also means that you should use [`AssetPath::parse`] in cases where `&str` is the explicit type.
|
||||
#[derive(Eq, PartialEq, Hash, Clone, Default)]
|
||||
#[derive(Eq, PartialEq, Hash, Clone, Default, Reflect)]
|
||||
#[reflect_value(Debug, PartialEq, Hash, Serialize, Deserialize)]
|
||||
pub struct AssetPath<'a> {
|
||||
source: AssetSourceId<'a>,
|
||||
path: CowArc<'a, Path>,
|
||||
@ -572,136 +568,6 @@ impl<'de> Visitor<'de> for AssetPathVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: We manually implement "reflect value" because deriving Reflect on `AssetPath` breaks dynamic linking
|
||||
// See https://github.com/bevyengine/bevy/issues/9747
|
||||
// NOTE: This could use `impl_reflect_value` if it supported static lifetimes.
|
||||
|
||||
impl GetTypeRegistration for AssetPath<'static> {
|
||||
fn get_type_registration() -> TypeRegistration {
|
||||
let mut registration = TypeRegistration::of::<Self>();
|
||||
registration.insert::<ReflectFromPtr>(FromType::<Self>::from_type());
|
||||
registration.insert::<ReflectFromReflect>(FromType::<Self>::from_type());
|
||||
registration.insert::<ReflectSerialize>(FromType::<Self>::from_type());
|
||||
registration.insert::<ReflectDeserialize>(FromType::<Self>::from_type());
|
||||
registration.insert::<ReflectDefault>(FromType::<Self>::from_type());
|
||||
registration
|
||||
}
|
||||
}
|
||||
|
||||
impl TypePath for AssetPath<'static> {
|
||||
fn type_path() -> &'static str {
|
||||
"bevy_asset::path::AssetPath<'static>"
|
||||
}
|
||||
fn short_type_path() -> &'static str {
|
||||
"AssetPath<'static>"
|
||||
}
|
||||
fn type_ident() -> Option<&'static str> {
|
||||
Some("AssetPath<'static>")
|
||||
}
|
||||
fn crate_name() -> Option<&'static str> {
|
||||
None
|
||||
}
|
||||
fn module_path() -> Option<&'static str> {
|
||||
None
|
||||
}
|
||||
}
|
||||
impl Typed for AssetPath<'static> {
|
||||
fn type_info() -> &'static TypeInfo {
|
||||
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
||||
CELL.get_or_set(|| {
|
||||
let info = ValueInfo::new::<Self>();
|
||||
TypeInfo::Value(info)
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Reflect for AssetPath<'static> {
|
||||
#[inline]
|
||||
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
|
||||
Some(<Self as Typed>::type_info())
|
||||
}
|
||||
#[inline]
|
||||
fn into_any(self: Box<Self>) -> Box<dyn core::any::Any> {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn as_any(&self) -> &dyn core::any::Any {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn as_any_mut(&mut self) -> &mut dyn core::any::Any {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn as_reflect(&self) -> &dyn Reflect {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
fn apply(&mut self, value: &dyn Reflect) {
|
||||
let value = Reflect::as_any(value);
|
||||
if let Some(value) = value.downcast_ref::<Self>() {
|
||||
*self = value.clone();
|
||||
} else {
|
||||
panic!("Value is not {}.", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn set(
|
||||
&mut self,
|
||||
value: Box<dyn bevy_reflect::Reflect>,
|
||||
) -> Result<(), Box<dyn bevy_reflect::Reflect>> {
|
||||
*self = <dyn bevy_reflect::Reflect>::take(value)?;
|
||||
Ok(())
|
||||
}
|
||||
fn reflect_kind(&self) -> ReflectKind {
|
||||
ReflectKind::Value
|
||||
}
|
||||
fn reflect_ref(&self) -> ReflectRef {
|
||||
ReflectRef::Value(self)
|
||||
}
|
||||
fn reflect_mut(&mut self) -> ReflectMut {
|
||||
ReflectMut::Value(self)
|
||||
}
|
||||
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
||||
ReflectOwned::Value(self)
|
||||
}
|
||||
#[inline]
|
||||
fn clone_value(&self) -> Box<dyn Reflect> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
fn reflect_hash(&self) -> Option<u64> {
|
||||
let mut hasher = bevy_reflect::utility::reflect_hasher();
|
||||
Hash::hash(&::core::any::Any::type_id(self), &mut hasher);
|
||||
Hash::hash(self, &mut hasher);
|
||||
Some(Hasher::finish(&hasher))
|
||||
}
|
||||
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
|
||||
let value = <dyn Reflect>::as_any(value);
|
||||
if let Some(value) = <dyn core::any::Any>::downcast_ref::<Self>(value) {
|
||||
Some(PartialEq::eq(self, value))
|
||||
} else {
|
||||
Some(false)
|
||||
}
|
||||
}
|
||||
fn debug(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
::core::fmt::Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
impl FromReflect for AssetPath<'static> {
|
||||
fn from_reflect(reflect: &dyn Reflect) -> Option<Self> {
|
||||
Some(Clone::clone(<dyn core::any::Any>::downcast_ref::<
|
||||
AssetPath<'static>,
|
||||
>(<dyn Reflect>::as_any(reflect))?))
|
||||
}
|
||||
}
|
||||
|
||||
/// Normalizes the path by collapsing all occurrences of '.' and '..' dot-segments where possible
|
||||
/// as per [RFC 1808](https://datatracker.ietf.org/doc/html/rfc1808)
|
||||
pub(crate) fn normalize_path(path: &Path) -> PathBuf {
|
||||
|
||||
@ -1,17 +1,16 @@
|
||||
use crate::std_traits::ReflectDefault;
|
||||
use crate::{self as bevy_reflect, ReflectFromPtr, ReflectFromReflect, ReflectOwned, TypeRegistry};
|
||||
use crate::{
|
||||
impl_type_path, map_apply, map_partial_eq, Array, ArrayInfo, ArrayIter, DynamicEnum,
|
||||
DynamicMap, Enum, EnumInfo, FromReflect, FromType, GetTypeRegistration, List, ListInfo,
|
||||
ListIter, Map, MapInfo, MapIter, Reflect, ReflectDeserialize, ReflectKind, ReflectMut,
|
||||
ReflectRef, ReflectSerialize, TupleVariantInfo, TypeInfo, TypePath, TypeRegistration, Typed,
|
||||
UnitVariantInfo, UnnamedField, ValueInfo, VariantFieldIter, VariantInfo, VariantType,
|
||||
impl_type_path, map_apply, map_partial_eq, Array, ArrayInfo, ArrayIter, DynamicMap,
|
||||
FromReflect, FromType, GetTypeRegistration, List, ListInfo, ListIter, Map, MapInfo, MapIter,
|
||||
Reflect, ReflectDeserialize, ReflectKind, ReflectMut, ReflectRef, ReflectSerialize, TypeInfo,
|
||||
TypePath, TypeRegistration, Typed, ValueInfo,
|
||||
};
|
||||
|
||||
use crate::utility::{
|
||||
reflect_hasher, GenericTypeInfoCell, GenericTypePathCell, NonGenericTypeInfoCell,
|
||||
};
|
||||
use bevy_reflect_derive::impl_reflect_value;
|
||||
use bevy_reflect_derive::{impl_reflect, impl_reflect_value};
|
||||
use std::fmt;
|
||||
use std::{
|
||||
any::Any,
|
||||
@ -996,252 +995,14 @@ impl<T: Reflect + TypePath + GetTypeRegistration, const N: usize> GetTypeRegistr
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: FromReflect + TypePath + GetTypeRegistration> GetTypeRegistration for Option<T> {
|
||||
fn get_type_registration() -> TypeRegistration {
|
||||
TypeRegistration::of::<Option<T>>()
|
||||
}
|
||||
|
||||
fn register_type_dependencies(registry: &mut TypeRegistry) {
|
||||
registry.register::<T>();
|
||||
impl_reflect! {
|
||||
#[type_path = "core::option"]
|
||||
enum Option<T> {
|
||||
None,
|
||||
Some(T),
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: FromReflect + TypePath + GetTypeRegistration> Enum for Option<T> {
|
||||
fn field(&self, _name: &str) -> Option<&dyn Reflect> {
|
||||
None
|
||||
}
|
||||
|
||||
fn field_at(&self, index: usize) -> Option<&dyn Reflect> {
|
||||
match self {
|
||||
Some(value) if index == 0 => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn field_mut(&mut self, _name: &str) -> Option<&mut dyn Reflect> {
|
||||
None
|
||||
}
|
||||
|
||||
fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
|
||||
match self {
|
||||
Some(value) if index == 0 => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn index_of(&self, _name: &str) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
|
||||
fn name_at(&self, _index: usize) -> Option<&str> {
|
||||
None
|
||||
}
|
||||
|
||||
fn iter_fields(&self) -> VariantFieldIter {
|
||||
VariantFieldIter::new(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn field_len(&self) -> usize {
|
||||
match self {
|
||||
Some(..) => 1,
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn variant_name(&self) -> &str {
|
||||
match self {
|
||||
Some(..) => "Some",
|
||||
None => "None",
|
||||
}
|
||||
}
|
||||
|
||||
fn variant_index(&self) -> usize {
|
||||
match self {
|
||||
None => 0,
|
||||
Some(..) => 1,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn variant_type(&self) -> VariantType {
|
||||
match self {
|
||||
Some(..) => VariantType::Tuple,
|
||||
None => VariantType::Unit,
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_dynamic(&self) -> DynamicEnum {
|
||||
DynamicEnum::from_ref::<Self>(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: FromReflect + TypePath + GetTypeRegistration> Reflect for Option<T> {
|
||||
#[inline]
|
||||
fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
|
||||
Some(<Self as Typed>::type_info())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn into_any(self: Box<Self>) -> Box<dyn Any> {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_reflect(&self) -> &dyn Reflect {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn apply(&mut self, value: &dyn Reflect) {
|
||||
if let ReflectRef::Enum(value) = value.reflect_ref() {
|
||||
if self.variant_name() == value.variant_name() {
|
||||
// Same variant -> just update fields
|
||||
for (index, field) in value.iter_fields().enumerate() {
|
||||
if let Some(v) = self.field_at_mut(index) {
|
||||
v.apply(field.value());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// New variant -> perform a switch
|
||||
match value.variant_name() {
|
||||
"Some" => {
|
||||
let field = T::take_from_reflect(
|
||||
value
|
||||
.field_at(0)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Field in `Some` variant of {} should exist",
|
||||
Self::type_path()
|
||||
)
|
||||
})
|
||||
.clone_value(),
|
||||
)
|
||||
.unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"Field in `Some` variant of {} should be of type {}",
|
||||
Self::type_path(),
|
||||
T::type_path()
|
||||
)
|
||||
});
|
||||
*self = Some(field);
|
||||
}
|
||||
"None" => {
|
||||
*self = None;
|
||||
}
|
||||
_ => panic!("Enum is not a {}.", Self::type_path()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
|
||||
*self = value.take()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reflect_kind(&self) -> ReflectKind {
|
||||
ReflectKind::Enum
|
||||
}
|
||||
|
||||
fn reflect_ref(&self) -> ReflectRef {
|
||||
ReflectRef::Enum(self)
|
||||
}
|
||||
|
||||
fn reflect_mut(&mut self) -> ReflectMut {
|
||||
ReflectMut::Enum(self)
|
||||
}
|
||||
|
||||
fn reflect_owned(self: Box<Self>) -> ReflectOwned {
|
||||
ReflectOwned::Enum(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn clone_value(&self) -> Box<dyn Reflect> {
|
||||
Box::new(Enum::clone_dynamic(self))
|
||||
}
|
||||
|
||||
fn reflect_hash(&self) -> Option<u64> {
|
||||
crate::enum_hash(self)
|
||||
}
|
||||
|
||||
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
|
||||
crate::enum_partial_eq(self, value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: FromReflect + TypePath + GetTypeRegistration> FromReflect for Option<T> {
|
||||
fn from_reflect(reflect: &dyn Reflect) -> Option<Self> {
|
||||
if let ReflectRef::Enum(dyn_enum) = reflect.reflect_ref() {
|
||||
match dyn_enum.variant_name() {
|
||||
"Some" => {
|
||||
let field = T::take_from_reflect(
|
||||
dyn_enum
|
||||
.field_at(0)
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Field in `Some` variant of {} should exist",
|
||||
Option::<T>::type_path()
|
||||
)
|
||||
})
|
||||
.clone_value(),
|
||||
)
|
||||
.unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"Field in `Some` variant of {} should be of type {}",
|
||||
Option::<T>::type_path(),
|
||||
T::type_path()
|
||||
)
|
||||
});
|
||||
Some(Some(field))
|
||||
}
|
||||
"None" => Some(None),
|
||||
name => panic!(
|
||||
"variant with name `{}` does not exist on enum `{}`",
|
||||
name,
|
||||
Self::type_path()
|
||||
),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: FromReflect + TypePath + GetTypeRegistration> Typed for Option<T> {
|
||||
fn type_info() -> &'static TypeInfo {
|
||||
static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new();
|
||||
CELL.get_or_insert::<Self, _>(|| {
|
||||
let none_variant = VariantInfo::Unit(UnitVariantInfo::new("None"));
|
||||
let some_variant =
|
||||
VariantInfo::Tuple(TupleVariantInfo::new("Some", &[UnnamedField::new::<T>(0)]));
|
||||
TypeInfo::Enum(EnumInfo::new::<Self>(&[none_variant, some_variant]))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl_type_path!(::core::option::Option<T>);
|
||||
|
||||
impl<T: TypePath + ?Sized> TypePath for &'static T {
|
||||
fn type_path() -> &'static str {
|
||||
static CELL: GenericTypePathCell = GenericTypePathCell::new();
|
||||
|
||||
@ -7,13 +7,7 @@ use bevy_ecs::{
|
||||
system::{StaticSystemParam, SystemParam, SystemParamItem, SystemState},
|
||||
world::{FromWorld, Mut},
|
||||
};
|
||||
use bevy_reflect::std_traits::ReflectDefault;
|
||||
use bevy_reflect::{
|
||||
utility::{reflect_hasher, NonGenericTypeInfoCell},
|
||||
FromReflect, FromType, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectFromPtr,
|
||||
ReflectFromReflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize,
|
||||
TypeInfo, TypePath, TypeRegistration, Typed, ValueInfo,
|
||||
};
|
||||
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||
use bevy_utils::{HashMap, HashSet};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::marker::PhantomData;
|
||||
@ -77,7 +71,8 @@ bitflags::bitflags! {
|
||||
/// [discussion about memory management](https://github.com/WebAssembly/design/issues/1397) for more
|
||||
/// details.
|
||||
#[repr(transparent)]
|
||||
#[derive(Serialize, TypePath, Deserialize, Hash, Clone, Copy, PartialEq, Eq, Debug)]
|
||||
#[derive(Serialize, Deserialize, Hash, Clone, Copy, PartialEq, Eq, Debug, Reflect)]
|
||||
#[reflect_value(Serialize, Deserialize, Hash, PartialEq, Debug)]
|
||||
pub struct RenderAssetUsages: u8 {
|
||||
const MAIN_WORLD = 1 << 0;
|
||||
const RENDER_WORLD = 1 << 1;
|
||||
@ -98,99 +93,6 @@ impl Default for RenderAssetUsages {
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for RenderAssetUsages {
|
||||
fn get_represented_type_info(&self) -> Option<&'static bevy_reflect::TypeInfo> {
|
||||
Some(<Self as Typed>::type_info())
|
||||
}
|
||||
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||
self
|
||||
}
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
|
||||
self
|
||||
}
|
||||
fn as_reflect(&self) -> &dyn Reflect {
|
||||
self
|
||||
}
|
||||
fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
|
||||
self
|
||||
}
|
||||
fn apply(&mut self, value: &dyn Reflect) {
|
||||
let value = value.as_any();
|
||||
if let Some(&value) = value.downcast_ref::<Self>() {
|
||||
*self = value;
|
||||
} else {
|
||||
panic!("Value is not a {}.", Self::type_path());
|
||||
}
|
||||
}
|
||||
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
|
||||
*self = value.take()?;
|
||||
Ok(())
|
||||
}
|
||||
fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
|
||||
ReflectKind::Value
|
||||
}
|
||||
fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
|
||||
ReflectRef::Value(self)
|
||||
}
|
||||
fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
|
||||
ReflectMut::Value(self)
|
||||
}
|
||||
fn reflect_owned(self: Box<Self>) -> bevy_reflect::ReflectOwned {
|
||||
ReflectOwned::Value(self)
|
||||
}
|
||||
fn clone_value(&self) -> Box<dyn Reflect> {
|
||||
Box::new(*self)
|
||||
}
|
||||
fn reflect_hash(&self) -> Option<u64> {
|
||||
use std::hash::Hash;
|
||||
use std::hash::Hasher;
|
||||
let mut hasher = reflect_hasher();
|
||||
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<bool> {
|
||||
let value = value.as_any();
|
||||
if let Some(value) = value.downcast_ref::<Self>() {
|
||||
Some(std::cmp::PartialEq::eq(self, value))
|
||||
} else {
|
||||
Some(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GetTypeRegistration for RenderAssetUsages {
|
||||
fn get_type_registration() -> TypeRegistration {
|
||||
let mut registration = TypeRegistration::of::<Self>();
|
||||
registration.insert::<ReflectSerialize>(FromType::<Self>::from_type());
|
||||
registration.insert::<ReflectDeserialize>(FromType::<Self>::from_type());
|
||||
registration.insert::<ReflectDefault>(FromType::<Self>::from_type());
|
||||
registration.insert::<ReflectFromReflect>(FromType::<Self>::from_type());
|
||||
registration.insert::<ReflectFromPtr>(FromType::<Self>::from_type());
|
||||
registration
|
||||
}
|
||||
}
|
||||
|
||||
impl FromReflect for RenderAssetUsages {
|
||||
fn from_reflect(reflect: &dyn Reflect) -> Option<Self> {
|
||||
let raw_value = *reflect.as_any().downcast_ref::<u8>()?;
|
||||
Self::from_bits(raw_value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Typed for RenderAssetUsages {
|
||||
fn type_info() -> &'static TypeInfo {
|
||||
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
|
||||
CELL.get_or_set(|| TypeInfo::Value(ValueInfo::new::<Self>()))
|
||||
}
|
||||
}
|
||||
|
||||
/// This plugin extracts the changed assets from the "app world" into the "render world"
|
||||
/// and prepares them for the GPU. They can then be accessed from the [`RenderAssets`] resource.
|
||||
///
|
||||
|
||||
Loading…
Reference in New Issue
Block a user