mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
split reflect mod into smaller modules
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
use crate::blank_reflect;
|
||||
use crate::reflect::Reflect;
|
||||
use crate::reflect::*;
|
||||
use fyrox_core_derive::impl_reflect;
|
||||
|
||||
/// [`Reflect`] sub trait for working with slices.
|
||||
pub trait ReflectArray: Reflect {
|
||||
fn reflect_index(&self, index: usize) -> Option<&dyn Reflect>;
|
||||
fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
|
||||
fn reflect_len(&self) -> usize;
|
||||
}
|
||||
|
||||
/// [`Reflect`] sub trait for working with `Vec`-like types
|
||||
pub trait ReflectList: ReflectArray {
|
||||
fn reflect_push(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
|
||||
fn reflect_pop(&mut self) -> Option<Box<dyn Reflect>>;
|
||||
fn reflect_remove(&mut self, index: usize) -> Option<Box<dyn Reflect>>;
|
||||
fn reflect_insert(
|
||||
&mut self,
|
||||
index: usize,
|
||||
value: Box<dyn Reflect>,
|
||||
) -> Result<(), Box<dyn Reflect>>;
|
||||
}
|
||||
|
||||
impl<const N: usize, T: Reflect + Clone> ReflectArray for [T; N] {
|
||||
fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
|
||||
if let Some(item) = self.get(index) {
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
|
||||
if let Some(item) = self.get_mut(index) {
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn reflect_len(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize, T: Reflect + Clone> Reflect for [T; N] {
|
||||
blank_reflect!();
|
||||
|
||||
fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
|
||||
func(Some(self))
|
||||
}
|
||||
|
||||
fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
|
||||
func(Some(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl_reflect! {
|
||||
#[reflect(ReflectList, ReflectArray)]
|
||||
pub struct Vec<T: Reflect + Clone>;
|
||||
}
|
||||
|
||||
impl<T: Reflect + Clone> ReflectArray for Vec<T> {
|
||||
fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
|
||||
self.get(index).map(|x| x as &dyn Reflect)
|
||||
}
|
||||
|
||||
fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
|
||||
self.get_mut(index).map(|x| x as &mut dyn Reflect)
|
||||
}
|
||||
|
||||
fn reflect_len(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
}
|
||||
|
||||
/// REMARK: `Reflect` is implemented for `Vec<T>` where `T: Reflect` only.
|
||||
impl<T: Reflect + Clone> ReflectList for Vec<T> {
|
||||
fn reflect_push(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
|
||||
self.push(*value.downcast::<T>()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reflect_pop(&mut self) -> Option<Box<dyn Reflect>> {
|
||||
if let Some(item) = self.pop() {
|
||||
Some(Box::new(item))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn reflect_remove(&mut self, index: usize) -> Option<Box<dyn Reflect>> {
|
||||
if index < self.len() {
|
||||
Some(Box::new(self.remove(index)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn reflect_insert(
|
||||
&mut self,
|
||||
index: usize,
|
||||
value: Box<dyn Reflect>,
|
||||
) -> Result<(), Box<dyn Reflect>> {
|
||||
self.insert(index, *value.downcast::<T>()?);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
use crate::reflect::Reflect;
|
||||
use std::any::TypeId;
|
||||
use std::fmt;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
/// An error returned from a failed path string query.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum ReflectPathError<'a> {
|
||||
// syntax errors
|
||||
UnclosedBrackets { s: &'a str },
|
||||
InvalidIndexSyntax { s: &'a str },
|
||||
|
||||
// access errors
|
||||
UnknownField { s: &'a str },
|
||||
NoItemForIndex { s: &'a str },
|
||||
|
||||
// type cast errors
|
||||
InvalidDowncast,
|
||||
NotAnArray,
|
||||
}
|
||||
|
||||
impl std::error::Error for ReflectPathError<'_> {}
|
||||
|
||||
impl Display for ReflectPathError<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ReflectPathError::UnclosedBrackets { s } => {
|
||||
write!(f, "unclosed brackets: `{s}`")
|
||||
}
|
||||
ReflectPathError::InvalidIndexSyntax { s } => {
|
||||
write!(f, "not index syntax: `{s}`")
|
||||
}
|
||||
ReflectPathError::UnknownField { s } => {
|
||||
write!(f, "given unknown field: `{s}`")
|
||||
}
|
||||
ReflectPathError::NoItemForIndex { s } => {
|
||||
write!(f, "no item for index: `{s}`")
|
||||
}
|
||||
ReflectPathError::InvalidDowncast => {
|
||||
write!(
|
||||
f,
|
||||
"failed to downcast to the target type after path resolution"
|
||||
)
|
||||
}
|
||||
ReflectPathError::NotAnArray => {
|
||||
write!(f, "tried to resolve index access, but the reflect type does not implement list API")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that can occur during "type casting"
|
||||
#[derive(Debug)]
|
||||
pub enum CastError {
|
||||
/// Given type does not match expected.
|
||||
TypeMismatch {
|
||||
/// A name of the field.
|
||||
property_name: String,
|
||||
|
||||
/// Expected type identifier.
|
||||
expected_type_id: TypeId,
|
||||
|
||||
/// Actual type identifier.
|
||||
actual_type_id: TypeId,
|
||||
},
|
||||
}
|
||||
|
||||
impl std::error::Error for CastError {}
|
||||
|
||||
impl Display for CastError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
CastError::TypeMismatch { property_name, .. } => {
|
||||
write!(
|
||||
f,
|
||||
"Given type does not match expected for property {property_name:?}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SetFieldError {
|
||||
NoSuchField {
|
||||
name: String,
|
||||
value: Box<dyn Reflect>,
|
||||
},
|
||||
InvalidValue {
|
||||
field_type_name: &'static str,
|
||||
value: Box<dyn Reflect>,
|
||||
},
|
||||
}
|
||||
|
||||
impl std::error::Error for SetFieldError {}
|
||||
|
||||
impl Display for SetFieldError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
SetFieldError::NoSuchField { name, value } => {
|
||||
write!(f, "No such field as {name:?} for value {value:?}")
|
||||
}
|
||||
SetFieldError::InvalidValue {
|
||||
field_type_name,
|
||||
value,
|
||||
} => write!(
|
||||
f,
|
||||
"Invalid value for field type {field_type_name}: {value:?}"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SetFieldByPathError<'p> {
|
||||
InvalidPath {
|
||||
value: Box<dyn Reflect>,
|
||||
reason: ReflectPathError<'p>,
|
||||
},
|
||||
InvalidValue {
|
||||
field_type_name: &'static str,
|
||||
value: Box<dyn Reflect>,
|
||||
},
|
||||
SetFieldError(SetFieldError),
|
||||
}
|
||||
|
||||
impl std::error::Error for SetFieldByPathError<'_> {}
|
||||
|
||||
impl Display for SetFieldByPathError<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
SetFieldByPathError::InvalidPath { value, reason } => {
|
||||
write!(f, "Invalid path: {value:?}. Reason: {reason}")
|
||||
}
|
||||
SetFieldByPathError::InvalidValue {
|
||||
field_type_name,
|
||||
value,
|
||||
} => {
|
||||
write!(f, "Invalid value: {value:?}. Type: {field_type_name}")
|
||||
}
|
||||
SetFieldByPathError::SetFieldError(set_field_error) => Display::fmt(set_field_error, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
//! Runtime reflection
|
||||
|
||||
mod array;
|
||||
mod error;
|
||||
mod external_impls;
|
||||
mod macros;
|
||||
mod map;
|
||||
@@ -34,11 +36,13 @@ use crate::{
|
||||
pub use fyrox_core_derive::Reflect;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
fmt::{self, Debug, Display, Formatter},
|
||||
fmt::{self, Debug},
|
||||
mem::ManuallyDrop,
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
pub use array::*;
|
||||
pub use error::*;
|
||||
pub use macros::*;
|
||||
pub use map::*;
|
||||
|
||||
@@ -85,37 +89,6 @@ impl<T: Reflect> FieldValue for T {
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that can occur during "type casting"
|
||||
#[derive(Debug)]
|
||||
pub enum CastError {
|
||||
/// Given type does not match expected.
|
||||
TypeMismatch {
|
||||
/// A name of the field.
|
||||
property_name: String,
|
||||
|
||||
/// Expected type identifier.
|
||||
expected_type_id: TypeId,
|
||||
|
||||
/// Actual type identifier.
|
||||
actual_type_id: TypeId,
|
||||
},
|
||||
}
|
||||
|
||||
impl std::error::Error for CastError {}
|
||||
|
||||
impl Display for CastError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
CastError::TypeMismatch { property_name, .. } => {
|
||||
write!(
|
||||
f,
|
||||
"Given type does not match expected for property {property_name:?}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FieldMetadata<'s> {
|
||||
/// A name of the property.
|
||||
@@ -446,25 +419,6 @@ pub trait ReflectHandle: Reflect {
|
||||
fn reflect_as_erased(&self) -> ErasedHandle;
|
||||
}
|
||||
|
||||
/// [`Reflect`] sub trait for working with slices.
|
||||
pub trait ReflectArray: Reflect {
|
||||
fn reflect_index(&self, index: usize) -> Option<&dyn Reflect>;
|
||||
fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
|
||||
fn reflect_len(&self) -> usize;
|
||||
}
|
||||
|
||||
/// [`Reflect`] sub trait for working with `Vec`-like types
|
||||
pub trait ReflectList: ReflectArray {
|
||||
fn reflect_push(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
|
||||
fn reflect_pop(&mut self) -> Option<Box<dyn Reflect>>;
|
||||
fn reflect_remove(&mut self, index: usize) -> Option<Box<dyn Reflect>>;
|
||||
fn reflect_insert(
|
||||
&mut self,
|
||||
index: usize,
|
||||
value: Box<dyn Reflect>,
|
||||
) -> Result<(), Box<dyn Reflect>>;
|
||||
}
|
||||
|
||||
pub trait ReflectInheritableVariable: Reflect {
|
||||
/// Tries to inherit a value from parent. It will succeed only if the current variable is
|
||||
/// not marked as modified.
|
||||
@@ -501,52 +455,6 @@ pub trait ReflectInheritableVariable: Reflect {
|
||||
fn inner_value_ref(&self) -> &dyn Reflect;
|
||||
}
|
||||
|
||||
/// An error returned from a failed path string query.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum ReflectPathError<'a> {
|
||||
// syntax errors
|
||||
UnclosedBrackets { s: &'a str },
|
||||
InvalidIndexSyntax { s: &'a str },
|
||||
|
||||
// access errors
|
||||
UnknownField { s: &'a str },
|
||||
NoItemForIndex { s: &'a str },
|
||||
|
||||
// type cast errors
|
||||
InvalidDowncast,
|
||||
NotAnArray,
|
||||
}
|
||||
|
||||
impl std::error::Error for ReflectPathError<'_> {}
|
||||
|
||||
impl Display for ReflectPathError<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ReflectPathError::UnclosedBrackets { s } => {
|
||||
write!(f, "unclosed brackets: `{s}`")
|
||||
}
|
||||
ReflectPathError::InvalidIndexSyntax { s } => {
|
||||
write!(f, "not index syntax: `{s}`")
|
||||
}
|
||||
ReflectPathError::UnknownField { s } => {
|
||||
write!(f, "given unknown field: `{s}`")
|
||||
}
|
||||
ReflectPathError::NoItemForIndex { s } => {
|
||||
write!(f, "no item for index: `{s}`")
|
||||
}
|
||||
ReflectPathError::InvalidDowncast => {
|
||||
write!(
|
||||
f,
|
||||
"failed to downcast to the target type after path resolution"
|
||||
)
|
||||
}
|
||||
ReflectPathError::NotAnArray => {
|
||||
write!(f, "tried to resolve index access, but the reflect type does not implement list API")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ResolvePath {
|
||||
fn resolve_path<'p>(
|
||||
&self,
|
||||
@@ -860,69 +768,6 @@ impl ResolvePath for dyn Reflect {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SetFieldError {
|
||||
NoSuchField {
|
||||
name: String,
|
||||
value: Box<dyn Reflect>,
|
||||
},
|
||||
InvalidValue {
|
||||
field_type_name: &'static str,
|
||||
value: Box<dyn Reflect>,
|
||||
},
|
||||
}
|
||||
|
||||
impl std::error::Error for SetFieldError {}
|
||||
|
||||
impl Display for SetFieldError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
SetFieldError::NoSuchField { name, value } => {
|
||||
write!(f, "No such field as {name:?} for value {value:?}")
|
||||
}
|
||||
SetFieldError::InvalidValue {
|
||||
field_type_name,
|
||||
value,
|
||||
} => write!(
|
||||
f,
|
||||
"Invalid value for field type {field_type_name}: {value:?}"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SetFieldByPathError<'p> {
|
||||
InvalidPath {
|
||||
value: Box<dyn Reflect>,
|
||||
reason: ReflectPathError<'p>,
|
||||
},
|
||||
InvalidValue {
|
||||
field_type_name: &'static str,
|
||||
value: Box<dyn Reflect>,
|
||||
},
|
||||
SetFieldError(SetFieldError),
|
||||
}
|
||||
|
||||
impl std::error::Error for SetFieldByPathError<'_> {}
|
||||
|
||||
impl Display for SetFieldByPathError<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
SetFieldByPathError::InvalidPath { value, reason } => {
|
||||
write!(f, "Invalid path: {value:?}. Reason: {reason}")
|
||||
}
|
||||
SetFieldByPathError::InvalidValue {
|
||||
field_type_name,
|
||||
value,
|
||||
} => {
|
||||
write!(f, "Invalid value: {value:?}. Type: {field_type_name}")
|
||||
}
|
||||
SetFieldByPathError::SetFieldError(set_field_error) => Display::fmt(set_field_error, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Type-erased API
|
||||
impl dyn Reflect {
|
||||
pub fn downcast<T: Reflect>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>> {
|
||||
|
||||
@@ -81,92 +81,6 @@ impl_reflect_tuple! {
|
||||
(T0, T1, T2, T3, T4,);
|
||||
}
|
||||
|
||||
impl<const N: usize, T: Reflect + Clone> Reflect for [T; N] {
|
||||
blank_reflect!();
|
||||
|
||||
fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
|
||||
func(Some(self))
|
||||
}
|
||||
|
||||
fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
|
||||
func(Some(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize, T: Reflect + Clone> ReflectArray for [T; N] {
|
||||
fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
|
||||
if let Some(item) = self.get(index) {
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
|
||||
if let Some(item) = self.get_mut(index) {
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn reflect_len(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl_reflect! {
|
||||
#[reflect(ReflectList, ReflectArray)]
|
||||
pub struct Vec<T: Reflect + Clone>;
|
||||
}
|
||||
|
||||
impl<T: Reflect + Clone> ReflectArray for Vec<T> {
|
||||
fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
|
||||
self.get(index).map(|x| x as &dyn Reflect)
|
||||
}
|
||||
|
||||
fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
|
||||
self.get_mut(index).map(|x| x as &mut dyn Reflect)
|
||||
}
|
||||
|
||||
fn reflect_len(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
}
|
||||
|
||||
/// REMARK: `Reflect` is implemented for `Vec<T>` where `T: Reflect` only.
|
||||
impl<T: Reflect + Clone> ReflectList for Vec<T> {
|
||||
fn reflect_push(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
|
||||
self.push(*value.downcast::<T>()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reflect_pop(&mut self) -> Option<Box<dyn Reflect>> {
|
||||
if let Some(item) = self.pop() {
|
||||
Some(Box::new(item))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn reflect_remove(&mut self, index: usize) -> Option<Box<dyn Reflect>> {
|
||||
if index < self.len() {
|
||||
Some(Box::new(self.remove(index)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn reflect_insert(
|
||||
&mut self,
|
||||
index: usize,
|
||||
value: Box<dyn Reflect>,
|
||||
) -> Result<(), Box<dyn Reflect>> {
|
||||
self.insert(index, *value.downcast::<T>()?);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflect for () {
|
||||
blank_reflect!();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user