diff options
Diffstat (limited to 'engine-ecs/src/component/local.rs')
| -rw-r--r-- | engine-ecs/src/component/local.rs | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/engine-ecs/src/component/local.rs b/engine-ecs/src/component/local.rs new file mode 100644 index 0000000..29afcee --- /dev/null +++ b/engine-ecs/src/component/local.rs @@ -0,0 +1,101 @@ +use std::any::type_name; +use std::ops::{Deref, DerefMut}; + +use crate::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::{Component, 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::<LocalComponent>( + Pair::builder() + .relation::<IsLocalComponent>() + .target::<LocalComponent>() + .build() + .id(), + ) else { + panic!( + "Local component {} of system with ID {} is uninitialized", + type_name::<LocalComponent>(), + 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::builder() + .relation::<IsLocalComponent>() + .target_as_data(input) + .build() + .into_parts(), + ); + } +} + +impl<LocalComponent> Deref for Local<'_, LocalComponent> +where + LocalComponent: Component, +{ + type Target = LocalComponent; + + fn deref(&self) -> &Self::Target + { + &self.local_component + } +} + +impl<LocalComponent> 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; |
