From f62f21e69fc94eb5e1a8e405e2a98e327ac7e087 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Thu, 25 May 2023 22:59:27 -0400 Subject: [PATCH] simple queries (which will be completely rewritten --- lyra-ecs/src/archetype.rs | 17 +++++++++++------ lyra-ecs/src/bundle.rs | 4 ++-- lyra-ecs/src/component.rs | 8 +++----- lyra-ecs/src/main.rs | 11 +++++++++-- lyra-ecs/src/world.rs | 17 ++++++++++++++++- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/lyra-ecs/src/archetype.rs b/lyra-ecs/src/archetype.rs index 7a9c16d..99b6342 100644 --- a/lyra-ecs/src/archetype.rs +++ b/lyra-ecs/src/archetype.rs @@ -1,6 +1,6 @@ use std::any::{Any, TypeId}; -use crate::{world::{Entity, ArchetypeEntityId}, bundle::Bundle}; +use crate::{world::{Entity, ArchetypeEntityId}, bundle::Bundle, component::Component}; pub trait ComponentColumn: Any { fn as_any(&self) -> &dyn Any; @@ -15,7 +15,7 @@ pub trait ComponentColumn: Any { fn component_type_name(&self) -> String; } -impl ComponentColumn for Vec { +impl ComponentColumn for Vec { fn as_any(&self) -> &dyn Any { self } @@ -74,7 +74,7 @@ pub struct Archetype { impl Archetype { /// Create a new archetype from another archetype and add a column - pub fn new_archetype_add(new_id: ArchetypeId, archetype: &Archetype) -> Archetype { + pub fn new_archetype_add(new_id: ArchetypeId, archetype: &Archetype) -> Archetype { let mut columns: Vec<_> = archetype .columns .iter() @@ -95,7 +95,7 @@ impl Archetype { } /// Create a new archetype from another archetype and remove a column - pub fn new_archetype_remove(new_id: ArchetypeId, archetype: &Archetype) -> Archetype { + pub fn new_archetype_remove(new_id: ArchetypeId, archetype: &Archetype) -> Archetype { let mut columns: Vec<_> = archetype .columns .iter() @@ -123,7 +123,7 @@ impl Archetype { } } - pub fn get_component_mut(&mut self, entity: ArchetypeEntityId) -> Option<&mut T> { + pub fn get_component_mut(&mut self, entity: ArchetypeEntityId) -> Option<&mut T> { for col in self.columns.iter_mut() { if col.as_any().is::>() { let components: &mut Vec = col.as_any_mut().downcast_mut().unwrap(); @@ -135,7 +135,7 @@ impl Archetype { None } - pub fn get_component(&self, entity: ArchetypeEntityId) -> Option<&T> { + pub fn get_component(&self, entity: ArchetypeEntityId) -> Option<&T> { for col in self.columns.iter() { if col.as_ref().as_any().is::>() { let components: &Vec = col.as_any().downcast_ref().unwrap(); @@ -147,6 +147,11 @@ impl Archetype { None } + pub fn get_component_column(&self) -> Option<&Vec> { + let col = self.columns.iter().find(|c| c.as_any().is::>())?; + col.as_any().downcast_ref() + } + pub(crate) fn add_entity(&mut self, components: Vec>) -> ArchetypeEntityId { let mut created_entity: Option = None; diff --git a/lyra-ecs/src/bundle.rs b/lyra-ecs/src/bundle.rs index 6f3b3e9..287875e 100644 --- a/lyra-ecs/src/bundle.rs +++ b/lyra-ecs/src/bundle.rs @@ -1,6 +1,6 @@ use std::any::{TypeId, Any}; -use crate::archetype::ComponentColumn; +use crate::{archetype::ComponentColumn, component::Component}; pub trait Bundle { // Get a list of type ids that this bundle is storing @@ -13,7 +13,7 @@ pub trait Bundle { macro_rules! impl_bundle_tuple { ( $(($name: ident, $index: tt))+ ) => ( - impl<$($name: Send + Sync + 'static),+> Bundle for ($($name,)+) { + impl<$($name: Component),+> Bundle for ($($name,)+) { fn types(&self) -> Vec { vec![$(self.$index.type_id()),+] } diff --git a/lyra-ecs/src/component.rs b/lyra-ecs/src/component.rs index e262482..af3a9e0 100644 --- a/lyra-ecs/src/component.rs +++ b/lyra-ecs/src/component.rs @@ -1,5 +1,3 @@ -use std::any::Any; - -pub trait Component : Any { - -} \ No newline at end of file +/// Shorthand for `Send + Sync + 'static`, so it never needs to be implemented manually. +pub trait Component: Send + Sync + 'static {} +impl Component for T {} \ No newline at end of file diff --git a/lyra-ecs/src/main.rs b/lyra-ecs/src/main.rs index 9a3a5aa..81973c2 100644 --- a/lyra-ecs/src/main.rs +++ b/lyra-ecs/src/main.rs @@ -1,5 +1,3 @@ -use std::any::Any; - use crate::world::World; mod archetype; @@ -21,4 +19,13 @@ fn main() { } else { println!("no component found :("); } + + let pos = Position2d(836, 348); + let _e = world.spawn((pos,)); + + println!("\nstart of querying!\n"); + + for pos in world.query::() { + println!("Queried Position2d: {:?}", pos); + } } diff --git a/lyra-ecs/src/world.rs b/lyra-ecs/src/world.rs index 0386921..68f3946 100644 --- a/lyra-ecs/src/world.rs +++ b/lyra-ecs/src/world.rs @@ -1,4 +1,5 @@ use std::{collections::{HashMap, VecDeque}, any::{Any, TypeId}}; +use std::slice::Iter; use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, component::Component}; @@ -103,10 +104,24 @@ impl World { new_entity } - pub fn get_component(&self, entity: Entity) -> Option<&T> { + pub fn get_component(&self, entity: Entity) -> Option<&T> { let record = self.entity_index.get(&entity.id)?; let archetype = self.archetypes.get(&record.id)?; archetype.get_component(record.index) } + + pub fn query(&self) -> impl Iterator { + self.archetypes + .iter() + .filter_map(|(_, a)| a.get_component_column::()) + .flatten() + } + + /* pub fn query_m(&self) -> impl Iterator { + self.archetypes + .iter() + .filter_map(|(_, a)| a.get_component_column::()) + .flatten() + } */ } \ No newline at end of file