summaryrefslogtreecommitdiff
path: root/ecs/src/component.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-02-25 23:25:03 +0100
committerHampusM <hampus@hampusmat.com>2024-02-26 19:54:00 +0100
commit1019924a29527eba2c8ec8bd976ece6ed76075b0 (patch)
treeb26d8bd872684a0c87802e057d8952c42be31f7a /ecs/src/component.rs
parent00055d6af92d59a86eb00f110c77c699a562d33e (diff)
feat(ecs): add support for multiple system queries & local components
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r--ecs/src/component.rs54
1 files changed, 52 insertions, 2 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs
index bead3b5..59b737e 100644
--- a/ecs/src/component.rs
+++ b/ecs/src/component.rs
@@ -4,6 +4,9 @@ use std::ops::{Deref, DerefMut};
use seq_macro::seq;
+use crate::system::{Input as SystemInput, Param as SystemParam, System};
+use crate::ComponentStorage;
+
pub trait Component: Any
{
#[doc(hidden)]
@@ -114,20 +117,65 @@ seq!(C in 0..=64 {
/// Holds a component which is local to a single system.
#[derive(Debug)]
-pub struct Local<'world, Value>
+pub struct Local<'world, Value: SystemInput>
{
value: &'world mut Value,
}
impl<'world, Value> Local<'world, Value>
+where
+ Value: SystemInput,
{
- pub(crate) fn new(value: &'world mut Value) -> Self
+ fn new(value: &'world mut Value) -> Self
{
Self { value }
}
}
+unsafe impl<'world, Value: 'static> SystemParam<'world> for Local<'world, Value>
+where
+ Value: SystemInput,
+{
+ type Flags = ();
+ type Input = Value;
+
+ fn initialize<SystemImpl>(system: &mut impl System<SystemImpl>, input: Self::Input)
+ {
+ system.set_local_component(input);
+ }
+
+ fn new<SystemImpl>(
+ system: &'world mut impl System<SystemImpl>,
+ _component_storage: &'world mut ComponentStorage,
+ ) -> Self
+ {
+ let local_component = system
+ .get_local_component_mut::<Value>()
+ .expect("Local component is uninitialized");
+
+ Self::new(local_component)
+ }
+
+ fn is_compatible<Other: SystemParam<'world>>() -> bool
+ {
+ let other_comparable = Other::get_comparable();
+
+ let Some(other_type_id) = other_comparable.downcast_ref::<TypeId>() else {
+ return true;
+ };
+
+ TypeId::of::<Value>() != *other_type_id
+ }
+
+ fn get_comparable() -> Box<dyn Any>
+ {
+ Box::new(TypeId::of::<Value>())
+ }
+}
+
impl<'world, Value> Deref for Local<'world, Value>
+where
+ Value: SystemInput,
{
type Target = Value;
@@ -138,6 +186,8 @@ impl<'world, Value> Deref for Local<'world, Value>
}
impl<'world, Value> DerefMut for Local<'world, Value>
+where
+ Value: SystemInput,
{
fn deref_mut(&mut self) -> &mut Self::Target
{