Experiments in applying Entity-Component-System patterns to durable data storage APIs.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Move hierarchy-related functions to its own module

moritz.vongoewels.de 6b76c51f 8ac5e1ae

verified
+74 -53
+70
src/hierarchy.rs
··· 1 + use std::iter; 2 + 3 + use ecsdb_derive::Component; 4 + use serde::{Deserialize, Serialize}; 5 + 6 + use crate::{self as ecsdb, Ecs, Entity, EntityId}; 7 + 8 + #[derive(Component, Clone, Copy, Debug, Serialize, Deserialize)] 9 + pub struct BelongsTo(pub EntityId); 10 + 11 + impl Ecs { 12 + pub fn direct_children<'a>( 13 + &'a self, 14 + entity: EntityId, 15 + ) -> impl Iterator<Item = Entity<'a>> + 'a { 16 + self.find(BelongsTo(entity)) 17 + } 18 + 19 + pub fn all_children<'a>(&'a self, entity: EntityId) -> impl Iterator<Item = Entity<'a>> + 'a { 20 + let mut stack = self.direct_children(entity).collect::<Vec<_>>(); 21 + iter::from_fn(move || -> Option<Entity<'a>> { 22 + let Some(entity) = stack.pop() else { 23 + return None; 24 + }; 25 + 26 + for entity in self.direct_children(entity.id()) { 27 + stack.push(entity); 28 + } 29 + 30 + Some(entity) 31 + }) 32 + } 33 + } 34 + 35 + #[cfg(test)] 36 + mod tests { 37 + use super::*; 38 + 39 + #[test] 40 + fn belongs_to() { 41 + #[derive(Debug, Serialize, Deserialize, Component)] 42 + struct A; 43 + 44 + #[derive(Debug, Serialize, Deserialize, PartialEq, Component)] 45 + struct B; 46 + 47 + let db = Ecs::open_in_memory().unwrap(); 48 + 49 + let parent = db.new_entity().attach(A); 50 + let child1 = db.new_entity().attach(A).attach(BelongsTo(parent.id())); 51 + let child2 = db.new_entity().attach(A).attach(BelongsTo(child1.id())); 52 + 53 + assert_eq!( 54 + parent.direct_children().map(|e| e.id()).collect::<Vec<_>>(), 55 + vec![child1.id()] 56 + ); 57 + 58 + assert_eq!( 59 + parent.all_children().map(|e| e.id()).collect::<Vec<_>>(), 60 + vec![child1.id(), child2.id()] 61 + ); 62 + 63 + assert_eq!( 64 + child1.all_children().map(|e| e.id()).collect::<Vec<_>>(), 65 + vec![child2.id()] 66 + ); 67 + 68 + assert!(child2.all_children().next().is_none()); 69 + } 70 + }
+4 -53
src/lib.rs
··· 5 5 pub mod entity; 6 6 pub use entity::{Entity, NewEntity}; 7 7 8 + pub mod hierarchy; 9 + pub use hierarchy::*; 10 + 8 11 pub mod query; 9 12 10 13 pub mod resource; ··· 13 16 mod system; 14 17 pub use system::*; 15 18 16 - use std::{iter, path::Path}; 19 + use std::path::Path; 17 20 18 21 use query::DataFilter; 19 - use serde::{Deserialize, Serialize}; 20 22 use tracing::{debug, instrument}; 21 23 22 24 pub type EntityId = i64; ··· 140 142 } 141 143 } 142 144 143 - use crate::{self as ecsdb}; 144 - #[derive(Component, Clone, Copy, Debug, Serialize, Deserialize)] 145 - pub struct BelongsTo(pub EntityId); 146 - 147 - impl Ecs { 148 - fn direct_children<'a>(&'a self, entity: EntityId) -> impl Iterator<Item = Entity<'a>> + 'a { 149 - self.find(BelongsTo(entity)) 150 - } 151 - 152 - fn all_children<'a>(&'a self, entity: EntityId) -> impl Iterator<Item = Entity<'a>> + 'a { 153 - let mut stack = self.direct_children(entity).collect::<Vec<_>>(); 154 - iter::from_fn(move || -> Option<Entity<'a>> { 155 - let Some(entity) = stack.pop() else { 156 - return None; 157 - }; 158 - 159 - for entity in self.direct_children(entity.id()) { 160 - stack.push(entity); 161 - } 162 - 163 - Some(entity) 164 - }) 165 - } 166 - } 167 - 168 145 mod sql { 169 146 #[allow(unused)] 170 147 pub enum Components { ··· 339 316 db.find((MarkerComponent, ComponentWithData(12345))).count(), 340 317 1 341 318 ); 342 - } 343 - 344 - #[test] 345 - fn belongs_to() { 346 - let db = Ecs::open_in_memory().unwrap(); 347 - 348 - let parent = db.new_entity().attach(A); 349 - let child1 = db.new_entity().attach(A).attach(BelongsTo(parent.id())); 350 - let child2 = db.new_entity().attach(A).attach(BelongsTo(child1.id())); 351 - 352 - assert_eq!( 353 - parent.direct_children().map(|e| e.id()).collect::<Vec<_>>(), 354 - vec![child1.id()] 355 - ); 356 - 357 - assert_eq!( 358 - parent.all_children().map(|e| e.id()).collect::<Vec<_>>(), 359 - vec![child1.id(), child2.id()] 360 - ); 361 - 362 - assert_eq!( 363 - child1.all_children().map(|e| e.id()).collect::<Vec<_>>(), 364 - vec![child2.id()] 365 - ); 366 - 367 - assert!(child2.all_children().next().is_none()); 368 319 } 369 320 370 321 #[test]