mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
moved ComponentProvider trait to fyrox_code + added proc macro for it
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
use darling::*;
|
||||
use proc_macro2::{TokenStream as TokenStream2, TokenStream};
|
||||
use quote::*;
|
||||
use syn::*;
|
||||
|
||||
#[derive(FromDeriveInput)]
|
||||
#[darling(attributes(component), supports(struct_any, enum_any))]
|
||||
pub struct TypeArgs {
|
||||
pub ident: Ident,
|
||||
pub generics: Generics,
|
||||
pub data: ast::Data<VariantArgs, FieldArgs>,
|
||||
}
|
||||
|
||||
#[derive(FromField, Clone)]
|
||||
#[darling(attributes(component))]
|
||||
pub struct FieldArgs {
|
||||
pub ident: Option<Ident>,
|
||||
pub ty: Type,
|
||||
#[darling(default)]
|
||||
pub include: bool,
|
||||
#[darling(default)]
|
||||
pub path: Option<String>,
|
||||
#[darling(default)]
|
||||
pub dest_type: Option<Type>,
|
||||
}
|
||||
|
||||
#[derive(FromVariant)]
|
||||
#[darling(attributes(component))]
|
||||
pub struct VariantArgs {
|
||||
pub ident: Ident,
|
||||
pub fields: ast::Fields<FieldArgs>,
|
||||
}
|
||||
|
||||
pub fn impl_type_uuid_provider(ast: DeriveInput) -> TokenStream2 {
|
||||
let ty_args = TypeArgs::from_derive_input(&ast).unwrap();
|
||||
match &ty_args.data {
|
||||
ast::Data::Struct(ref field_args) => impl_type_uuid_provider_struct(&ty_args, field_args),
|
||||
ast::Data::Enum(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_field_components(
|
||||
// false if enum variant
|
||||
is_struct: bool,
|
||||
fields: &[FieldArgs],
|
||||
field_style: ast::Style,
|
||||
mutable: bool,
|
||||
) -> Vec<TokenStream2> {
|
||||
if field_style == ast::Style::Unit {
|
||||
// `Unit` struct/enum variant has no components.
|
||||
return Default::default();
|
||||
}
|
||||
|
||||
let prefix = if is_struct {
|
||||
if mutable {
|
||||
Some(quote!(&mut self.))
|
||||
} else {
|
||||
Some(quote!(&self.))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
fields
|
||||
.iter()
|
||||
.filter(|arg| arg.include)
|
||||
.map(|arg| {
|
||||
let ident = &arg.ident;
|
||||
let ty = &arg.ty;
|
||||
if let Some(path) = &arg.path {
|
||||
let path: TokenStream = parse_str(path).unwrap();
|
||||
|
||||
if let Some(dest_type) = arg.dest_type.as_ref() {
|
||||
quote! {
|
||||
if type_id == std::any::TypeId::of::<#dest_type>() {
|
||||
return Some(#prefix #path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
if type_id == std::any::TypeId::of::<#ty>() {
|
||||
return Some(#prefix #path);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
if type_id == std::any::TypeId::of::<#ty>() {
|
||||
return Some(#prefix #ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn impl_type_uuid_provider_struct(
|
||||
ty_args: &TypeArgs,
|
||||
field_args: &ast::Fields<FieldArgs>,
|
||||
) -> TokenStream2 {
|
||||
let (field_refs, field_ref_muts) = if field_args.style == ast::Style::Unit {
|
||||
(quote! {}, quote! {})
|
||||
} else {
|
||||
let field_refs = create_field_components(true, &field_args.fields, field_args.style, false);
|
||||
let field_ref_muts =
|
||||
create_field_components(true, &field_args.fields, field_args.style, true);
|
||||
(quote! { #(#field_refs)* }, quote! { #(#field_ref_muts)* })
|
||||
};
|
||||
|
||||
let ty_ident = &ty_args.ident;
|
||||
let (impl_generics, ty_generics, where_clause) = ty_args.generics.split_for_impl();
|
||||
|
||||
quote! {
|
||||
impl #impl_generics ComponentProvider for #ty_ident #ty_generics #where_clause {
|
||||
fn query_component_ref(&self, type_id: std::any::TypeId) -> Option<&dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
|
||||
#field_refs
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn query_component_mut(
|
||||
&mut self,
|
||||
type_id: std::any::TypeId,
|
||||
) -> Option<&mut dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
|
||||
#field_ref_muts
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
mod component;
|
||||
mod reflect;
|
||||
mod uuid;
|
||||
mod visit;
|
||||
@@ -53,3 +54,12 @@ pub fn type_uuid(input: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(input as DeriveInput);
|
||||
TokenStream::from(uuid::impl_type_uuid_provider(ast))
|
||||
}
|
||||
|
||||
/// Implements `ComponentProvider` trait
|
||||
///
|
||||
/// User has to import `ComponentProvider` trait to use this macro.
|
||||
#[proc_macro_derive(ComponentProvider, attributes(component))]
|
||||
pub fn component(input: TokenStream) -> TokenStream {
|
||||
let ast = parse_macro_input!(input as DeriveInput);
|
||||
TokenStream::from(component::impl_type_uuid_provider(ast))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
use fyrox_core::type_traits::prelude::*;
|
||||
|
||||
#[derive(ComponentProvider)]
|
||||
pub struct Foo {
|
||||
#[component(include)]
|
||||
component: Component,
|
||||
#[component(include)]
|
||||
other_component: OtherComponent,
|
||||
#[component(
|
||||
include,
|
||||
path = "wrapper.some_other_component",
|
||||
dest_type = "SomeOtherComponent"
|
||||
)]
|
||||
wrapper: Wrapper,
|
||||
#[allow(dead_code)]
|
||||
non_component: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Component {
|
||||
stuff: f32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct OtherComponent {
|
||||
other_stuff: u32,
|
||||
}
|
||||
|
||||
pub struct Wrapper {
|
||||
some_other_component: SomeOtherComponent,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct SomeOtherComponent {
|
||||
other_stuff: u8,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_component_provider() {
|
||||
#[allow(clippy::disallowed_names)] // Stupid fucking clippy
|
||||
let mut foo = Foo {
|
||||
component: Component { stuff: 123.321 },
|
||||
other_component: OtherComponent { other_stuff: 123 },
|
||||
wrapper: Wrapper {
|
||||
some_other_component: SomeOtherComponent { other_stuff: 77 },
|
||||
},
|
||||
non_component: Default::default(),
|
||||
};
|
||||
assert_eq!(
|
||||
(&foo as &dyn ComponentProvider).component_ref::<Component>(),
|
||||
Some(Component { stuff: 123.321 }).as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
(&foo as &dyn ComponentProvider).component_ref::<OtherComponent>(),
|
||||
Some(OtherComponent { other_stuff: 123 }).as_ref()
|
||||
);
|
||||
assert_eq!(
|
||||
(&foo as &dyn ComponentProvider).component_ref::<SomeOtherComponent>(),
|
||||
Some(SomeOtherComponent { other_stuff: 77 }).as_ref()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
(&mut foo as &mut dyn ComponentProvider).component_mut::<Component>(),
|
||||
Some(Component { stuff: 123.321 }).as_mut()
|
||||
);
|
||||
assert_eq!(
|
||||
(&mut foo as &mut dyn ComponentProvider).component_mut::<OtherComponent>(),
|
||||
Some(OtherComponent { other_stuff: 123 }).as_mut()
|
||||
);
|
||||
assert_eq!(
|
||||
(&mut foo as &mut dyn ComponentProvider).component_mut::<SomeOtherComponent>(),
|
||||
Some(SomeOtherComponent { other_stuff: 77 }).as_mut()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
(&foo as &dyn ComponentProvider).component_ref::<String>(),
|
||||
None
|
||||
);
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
// #![feature(trace_macros)]
|
||||
// trace_macros!(true);
|
||||
|
||||
pub mod component;
|
||||
pub mod reflect;
|
||||
pub mod uuid;
|
||||
pub mod visit;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
pub use fyrox_core_derive::ComponentProvider;
|
||||
pub use fyrox_core_derive::TypeUuidProvider;
|
||||
use std::any::{Any, TypeId};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::{combine_uuids, TypeUuidProvider};
|
||||
pub use super::{combine_uuids, ComponentProvider, TypeUuidProvider};
|
||||
pub use uuid::{uuid, Uuid};
|
||||
}
|
||||
|
||||
@@ -67,3 +69,89 @@ pub fn combine_uuids(a: Uuid, b: Uuid) -> Uuid {
|
||||
|
||||
Uuid::from_bytes(combined_bytes)
|
||||
}
|
||||
|
||||
/// Component provider provides dynamic access to inner components of an object by their type id.
|
||||
pub trait ComponentProvider {
|
||||
/// Allows an object to provide access to inner components.
|
||||
fn query_component_ref(&self, type_id: TypeId) -> Option<&dyn Any>;
|
||||
|
||||
/// Allows an object to provide access to inner components.
|
||||
fn query_component_mut(&mut self, type_id: TypeId) -> Option<&mut dyn Any>;
|
||||
}
|
||||
|
||||
impl dyn ComponentProvider {
|
||||
/// Tries to borrow a component of given type.
|
||||
#[inline]
|
||||
pub fn component_ref<T: Any>(&self) -> Option<&T> {
|
||||
ComponentProvider::query_component_ref(self, TypeId::of::<T>())
|
||||
.and_then(|c| c.downcast_ref())
|
||||
}
|
||||
|
||||
/// Tries to borrow a component of given type.
|
||||
#[inline]
|
||||
pub fn component_mut<T: Any>(&mut self) -> Option<&mut T> {
|
||||
ComponentProvider::query_component_mut(self, TypeId::of::<T>())
|
||||
.and_then(|c| c.downcast_mut())
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements [`ComponentProvider::query_component_ref`] and [`ComponentProvider::query_component_mut`] in a much
|
||||
/// shorter way.
|
||||
#[macro_export]
|
||||
macro_rules! impl_component_provider {
|
||||
($dest_type:ty) => {
|
||||
impl $crate::type_traits::ComponentProvider for $dest_type {
|
||||
fn query_component_ref(&self, type_id: std::any::TypeId) -> Option<&dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn query_component_mut(
|
||||
&mut self,
|
||||
type_id: std::any::TypeId,
|
||||
) -> Option<&mut dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($dest_type:ty, $($($comp_field:ident).*: $comp_type:ty),*) => {
|
||||
impl $crate::type_traits::ComponentProvider for $dest_type {
|
||||
fn query_component_ref(&self, type_id: std::any::TypeId) -> Option<&dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
|
||||
$(
|
||||
if type_id == std::any::TypeId::of::<$comp_type>() {
|
||||
return Some(&self.$($comp_field).*)
|
||||
}
|
||||
)*
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn query_component_mut(
|
||||
&mut self,
|
||||
type_id: std::any::TypeId,
|
||||
) -> Option<&mut dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
|
||||
$(
|
||||
if type_id == std::any::TypeId::of::<$comp_type>() {
|
||||
return Some(&mut self.$($comp_field).*)
|
||||
}
|
||||
)*
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
//! Flying camera controller script is used to create flying cameras, that can be rotated via mouse and moved via keyboard keys.
|
||||
//! See [`FlyingCameraController`] docs for more info and usage examples.
|
||||
|
||||
use fyrox::core::uuid_provider;
|
||||
use fyrox::{
|
||||
core::algebra::UnitVector3,
|
||||
core::{
|
||||
algebra::{UnitQuaternion, Vector3},
|
||||
algebra::{UnitQuaternion, UnitVector3, Vector3},
|
||||
curve::{Curve, CurveKey, CurveKeyKind},
|
||||
impl_component_provider,
|
||||
math::Vector3Ext,
|
||||
reflect::prelude::*,
|
||||
uuid_provider,
|
||||
variable::InheritableVariable,
|
||||
visitor::prelude::*,
|
||||
},
|
||||
event::{DeviceEvent, ElementState, Event, WindowEvent},
|
||||
gui::{key::KeyBinding, message::KeyCode},
|
||||
impl_component_provider,
|
||||
script::{ScriptContext, ScriptTrait},
|
||||
utils,
|
||||
};
|
||||
|
||||
+5
-7
@@ -2168,9 +2168,11 @@ impl Drop for Engine {
|
||||
mod test {
|
||||
use crate::{
|
||||
asset::manager::ResourceManager,
|
||||
core::{pool::Handle, reflect::prelude::*, visitor::prelude::*},
|
||||
engine::ScriptProcessor,
|
||||
impl_component_provider,
|
||||
core::{
|
||||
impl_component_provider, pool::Handle, reflect::prelude::*, task::TaskPool,
|
||||
uuid_provider, visitor::prelude::*,
|
||||
},
|
||||
engine::{task::TaskPoolHandler, GraphicsContext, ScriptProcessor},
|
||||
scene::{base::BaseBuilder, node::Node, pivot::PivotBuilder, Scene, SceneContainer},
|
||||
script::{
|
||||
Script, ScriptContext, ScriptDeinitContext, ScriptMessageContext, ScriptMessagePayload,
|
||||
@@ -2179,10 +2181,6 @@ mod test {
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::engine::task::TaskPoolHandler;
|
||||
use crate::engine::GraphicsContext;
|
||||
use fyrox_core::task::TaskPool;
|
||||
use fyrox_core::uuid_provider;
|
||||
use std::sync::mpsc::{self, Sender, TryRecvError};
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
|
||||
+1
-2
@@ -151,8 +151,7 @@ impl TaskPoolHandler {
|
||||
///
|
||||
/// ```rust ,no_run
|
||||
/// # use fyrox::{
|
||||
/// # core::{reflect::prelude::*, uuid::Uuid, visitor::prelude::*},
|
||||
/// # impl_component_provider,
|
||||
/// # core::{reflect::prelude::*, uuid::Uuid, visitor::prelude::*, impl_component_provider},
|
||||
/// # resource::model::{Model, ModelResourceExtension},
|
||||
/// # script::{ScriptContext, ScriptTrait},
|
||||
/// # };
|
||||
|
||||
@@ -571,6 +571,7 @@ mod test {
|
||||
core::{
|
||||
algebra::{Matrix4, Vector3},
|
||||
futures::executor::block_on,
|
||||
impl_component_provider,
|
||||
reflect::prelude::*,
|
||||
uuid::{uuid, Uuid},
|
||||
variable::InheritableVariable,
|
||||
@@ -578,7 +579,6 @@ mod test {
|
||||
TypeUuidProvider,
|
||||
},
|
||||
engine::{self, SerializationContext},
|
||||
impl_component_provider,
|
||||
resource::model::{Model, ModelResourceExtension},
|
||||
scene::{
|
||||
base::BaseBuilder,
|
||||
|
||||
+9
-17
@@ -2,24 +2,22 @@
|
||||
|
||||
//! Script is used to add custom logic to scene nodes. See [ScriptTrait] for more info.
|
||||
|
||||
use crate::engine::task::TaskPoolHandler;
|
||||
use crate::engine::GraphicsContext;
|
||||
use crate::{
|
||||
asset::manager::ResourceManager,
|
||||
core::{
|
||||
log::Log,
|
||||
pool::Handle,
|
||||
reflect::{FieldInfo, Reflect, ReflectArray, ReflectList},
|
||||
type_traits::ComponentProvider,
|
||||
uuid::Uuid,
|
||||
visitor::{Visit, VisitResult, Visitor},
|
||||
TypeUuidProvider,
|
||||
},
|
||||
engine::ScriptMessageDispatcher,
|
||||
engine::{task::TaskPoolHandler, GraphicsContext, ScriptMessageDispatcher},
|
||||
event::Event,
|
||||
plugin::Plugin,
|
||||
scene::{node::Node, Scene},
|
||||
utils::component::ComponentProvider,
|
||||
};
|
||||
use fyrox_core::TypeUuidProvider;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
fmt::{Debug, Formatter},
|
||||
@@ -185,10 +183,10 @@ pub trait BaseScript: Visit + Reflect + Send + Debug + 'static {
|
||||
/// core::uuid::Uuid,
|
||||
/// script::ScriptTrait,
|
||||
/// core::TypeUuidProvider,
|
||||
/// core::uuid::uuid, impl_component_provider
|
||||
/// core::uuid::uuid, core::type_traits::prelude::*
|
||||
/// };
|
||||
///
|
||||
/// #[derive(Reflect, Visit, Debug, Clone)]
|
||||
/// #[derive(Reflect, Visit, Debug, Clone, ComponentProvider)]
|
||||
/// struct MyScript { }
|
||||
///
|
||||
/// // Implement TypeUuidProvider trait that will return type uuid of the type.
|
||||
@@ -201,8 +199,6 @@ pub trait BaseScript: Visit + Reflect + Send + Debug + 'static {
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// impl_component_provider!(MyScript);
|
||||
///
|
||||
/// impl ScriptTrait for MyScript { }
|
||||
/// ```
|
||||
fn id(&self) -> Uuid;
|
||||
@@ -388,8 +384,7 @@ pub trait ScriptTrait: BaseScript + ComponentProvider {
|
||||
///
|
||||
/// ```rust
|
||||
/// use fyrox::{
|
||||
/// core::{reflect::prelude::*, uuid::Uuid, visitor::prelude::*},
|
||||
/// impl_component_provider,
|
||||
/// core::{reflect::prelude::*, uuid::Uuid, visitor::prelude::*, type_traits::prelude::*},
|
||||
/// core::TypeUuidProvider,
|
||||
/// script::ScriptTrait,
|
||||
/// script::{ScriptContext, ScriptMessageContext, ScriptMessagePayload},
|
||||
@@ -397,7 +392,7 @@ pub trait ScriptTrait: BaseScript + ComponentProvider {
|
||||
///
|
||||
/// struct Message;
|
||||
///
|
||||
/// #[derive(Reflect, Visit, Debug, Clone)]
|
||||
/// #[derive(Reflect, Visit, Debug, Clone, ComponentProvider)]
|
||||
/// struct MyScript {}
|
||||
///
|
||||
/// # impl TypeUuidProvider for MyScript {
|
||||
@@ -406,8 +401,6 @@ pub trait ScriptTrait: BaseScript + ComponentProvider {
|
||||
/// # }
|
||||
/// # }
|
||||
///
|
||||
/// # impl_component_provider!(MyScript);
|
||||
///
|
||||
/// impl ScriptTrait for MyScript {
|
||||
/// fn on_start(&mut self, ctx: &mut ScriptContext) {
|
||||
/// // Subscription is mandatory to receive any message of the type!
|
||||
@@ -612,10 +605,9 @@ impl Script {
|
||||
mod test {
|
||||
use crate::{
|
||||
core::{
|
||||
reflect::prelude::*, variable::try_inherit_properties, variable::InheritableVariable,
|
||||
visitor::prelude::*,
|
||||
impl_component_provider, reflect::prelude::*, variable::try_inherit_properties,
|
||||
variable::InheritableVariable, visitor::prelude::*,
|
||||
},
|
||||
impl_component_provider,
|
||||
scene::base::Base,
|
||||
script::{Script, ScriptTrait},
|
||||
};
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
//! Component provider provides dynamic access to inner components of an object by their type id.
|
||||
|
||||
use std::any::{Any, TypeId};
|
||||
|
||||
/// Component provider provides dynamic access to inner components of an object by their type id.
|
||||
pub trait ComponentProvider {
|
||||
/// Allows an object to provide access to inner components.
|
||||
fn query_component_ref(&self, type_id: TypeId) -> Option<&dyn Any>;
|
||||
|
||||
/// Allows an object to provide access to inner components.
|
||||
fn query_component_mut(&mut self, type_id: TypeId) -> Option<&mut dyn Any>;
|
||||
}
|
||||
|
||||
/// Implements [`ComponentProvider::query_component_ref`] and [`ComponentProvider::query_component_mut`] in a much
|
||||
/// shorter way.
|
||||
#[macro_export]
|
||||
macro_rules! impl_component_provider {
|
||||
($dest_type:ty) => {
|
||||
impl $crate::utils::component::ComponentProvider for $dest_type {
|
||||
fn query_component_ref(&self, type_id: std::any::TypeId) -> Option<&dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn query_component_mut(
|
||||
&mut self,
|
||||
type_id: std::any::TypeId,
|
||||
) -> Option<&mut dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($dest_type:ty, $($($comp_field:ident).*: $comp_type:ty),*) => {
|
||||
impl $crate::utils::component::ComponentProvider for $dest_type {
|
||||
fn query_component_ref(&self, type_id: std::any::TypeId) -> Option<&dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
|
||||
$(
|
||||
if type_id == std::any::TypeId::of::<$comp_type>() {
|
||||
return Some(&self.$($comp_field).*)
|
||||
}
|
||||
)*
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn query_component_mut(
|
||||
&mut self,
|
||||
type_id: std::any::TypeId,
|
||||
) -> Option<&mut dyn std::any::Any> {
|
||||
if type_id == std::any::TypeId::of::<Self>() {
|
||||
return Some(self);
|
||||
}
|
||||
|
||||
$(
|
||||
if type_id == std::any::TypeId::of::<$comp_type>() {
|
||||
return Some(&mut self.$($comp_field).*)
|
||||
}
|
||||
)*
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
pub mod astar;
|
||||
pub mod behavior;
|
||||
pub mod component;
|
||||
pub mod lightmap;
|
||||
pub mod navmesh;
|
||||
pub mod raw_mesh;
|
||||
|
||||
Reference in New Issue
Block a user