From 64519b2b4fe298e47534560e1669c26c13838aab Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Fri, 22 Dec 2023 12:22:10 -0500 Subject: [PATCH] [lyra-ecs] Add World::get_resource_or_else, update README.md --- lyra-ecs/README.md | 20 ++++++++------------ lyra-ecs/src/archetype.rs | 4 +++- lyra-ecs/src/world.rs | 21 +++++++++++++++++++-- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/lyra-ecs/README.md b/lyra-ecs/README.md index 2859881..7a42101 100644 --- a/lyra-ecs/README.md +++ b/lyra-ecs/README.md @@ -5,7 +5,7 @@ An ECS for the Lyra game engine. I couldn't find anything that fulfilled my needs, specifically an ECS that can store arbitrary components without knowing about the types. This makes it easier to implement into a scripting engine that has the ability to create its own components. ## Features -- [ ] Archetypes +- [x] Archetypes - [x] Spawning entities - [x] Despawning entities - [x] Delete entities from archetypes @@ -14,19 +14,15 @@ I couldn't find anything that fulfilled my needs, specifically an ECS that can s - [x] Grow archetype as it fills up - [x] Borrow safety of components inside Archetypes - [x] Return `Ref` and `RefMut` from borrow queries -- [ ] Querying components from archetypes +- [x] Querying components from archetypes - [x] Views - - [ ] Mutable views - - [ ] Make it possible so that ONLY `ViewMut` can borrow mutably + - [x] Mutable views - [x] Resources - [x] Get resources in views somehow - [ ] Relationships (maybe this can be done through queries, idk) -- [ ] Dynamic queries +- [x] Dynamic queries * Needed for scripting engines that can create their own components that Rust does not know the types of. -- [ ] Systems - - [ ] Dispatchers/Executors - - [ ] Execution graph that follows dependencies - -
- -To be honest, the name may change at some point \ No newline at end of file +- [x] Systems + - [x] Dispatchers/Executors + - [x] Execution graph that follows dependencies +- [ ] Track when components on entities are changed \ No newline at end of file diff --git a/lyra-ecs/src/archetype.rs b/lyra-ecs/src/archetype.rs index a63ea7a..d676dd4 100644 --- a/lyra-ecs/src/archetype.rs +++ b/lyra-ecs/src/archetype.rs @@ -2,6 +2,7 @@ use std::{ptr::{NonNull, self}, alloc::{self, Layout, alloc, dealloc}, mem, coll use crate::{world::{Entity, ArchetypeEntityId}, bundle::Bundle, component_info::ComponentInfo, DynTypeId}; +#[derive(Clone)] pub struct ComponentColumn { pub data: RefCell>, pub len: usize, @@ -187,7 +188,7 @@ impl ComponentColumn { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)] pub struct ArchetypeId(pub u64); impl ArchetypeId { @@ -200,6 +201,7 @@ impl ArchetypeId { } } +#[derive(Clone, Default)] pub struct Archetype { pub id: ArchetypeId, pub(crate) entities: HashMap, diff --git a/lyra-ecs/src/world.rs b/lyra-ecs/src/world.rs index 36b5515..f8d472f 100644 --- a/lyra-ecs/src/world.rs +++ b/lyra-ecs/src/world.rs @@ -31,8 +31,8 @@ pub struct World { resources: HashMap, } -impl World { - pub fn new() -> Self { +impl Default for World { + fn default() -> Self { Self { archetypes: HashMap::new(), next_archetype_id: ArchetypeId(0), @@ -42,6 +42,12 @@ impl World { resources: HashMap::new(), } } +} + +impl World { + pub fn new() -> Self { + Self::default() + } fn get_new_entity(&mut self) -> Entity { match self.dead_entities.pop_front() { @@ -201,6 +207,17 @@ impl World { self.resources.insert(TypeId::of::(), ResourceData::new(data)); } + /// Get a resource from the world, or insert it into the world with the provided + /// `fn` and return it. + pub fn get_resource_or_else(&mut self, f: F) -> RefMut + where + F: Fn() -> T + 'static + { + self.resources.entry(TypeId::of::()) + .or_insert_with(|| ResourceData::new(f())) + .get_mut() + } + /// Gets a resource from the World. /// /// Will panic if the resource is not in the world. See [`try_get_resource`] for