use std::any::type_name; use std::ops::{Deref, DerefMut}; use ecs_macros::Component; use crate::component::{ Component, HandleMut as ComponentHandleMut, IntoParts as _, Parts as ComponentParts, }; use crate::pair::Pair; use crate::system::initializable::Param as InitializableParam; use crate::system::{Metadata as SystemMetadata, Param as SystemParam}; use crate::World; /// Holds a component which is local to a single system. #[derive(Debug)] pub struct Local<'world, LocalComponent: Component> { local_component: ComponentHandleMut<'world, LocalComponent>, } impl<'world, LocalComponent> SystemParam<'world> for Local<'world, LocalComponent> where LocalComponent: Component, { type Input = LocalComponent; fn new(world: &'world World, system_metadata: &SystemMetadata) -> Self { let Some(system_ent) = world.get_entity(system_metadata.ent_id) else { panic!( "System entity with ID {} does not exist", system_metadata.ent_id ); }; let Some(local_component) = system_ent.get_with_id_mut::( Pair::new::(LocalComponent::id()).id(), ) else { panic!( "Local component {} of system with ID {} is uninitialized", type_name::(), system_metadata.ent_id ); }; Self { local_component } } } impl<'world, LocalComponent, SystemT> InitializableParam<'world, SystemT> for Local<'world, LocalComponent> where LocalComponent: Component, SystemT: SystemWithLocalComponents, Self: SystemParam<'world, Input = LocalComponent>, { fn initialize(system: &mut SystemT, input: Self::Input) { system.add_local_component( Pair::new_with_comp_target::(input).into_parts(), ); } } impl Deref for Local<'_, LocalComponent> where LocalComponent: Component, { type Target = LocalComponent; fn deref(&self) -> &Self::Target { &self.local_component } } impl DerefMut for Local<'_, LocalComponent> where LocalComponent: Component, { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.local_component } } pub trait SystemWithLocalComponents { fn add_local_component(&mut self, component_parts: ComponentParts); } #[derive(Component)] struct IsLocalComponent;