[lyra-ecs] Add World::get_resource_or_else, update README.md

This commit is contained in:
SeanOMik 2023-12-22 12:22:10 -05:00
parent e513d09233
commit 64519b2b4f
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
3 changed files with 30 additions and 15 deletions

View File

@ -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. 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 ## Features
- [ ] Archetypes - [x] Archetypes
- [x] Spawning entities - [x] Spawning entities
- [x] Despawning entities - [x] Despawning entities
- [x] Delete entities from archetypes - [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] Grow archetype as it fills up
- [x] Borrow safety of components inside Archetypes - [x] Borrow safety of components inside Archetypes
- [x] Return `Ref` and `RefMut` from borrow queries - [x] Return `Ref` and `RefMut` from borrow queries
- [ ] Querying components from archetypes - [x] Querying components from archetypes
- [x] Views - [x] Views
- [ ] Mutable views - [x] Mutable views
- [ ] Make it possible so that ONLY `ViewMut` can borrow mutably
- [x] Resources - [x] Resources
- [x] Get resources in views somehow - [x] Get resources in views somehow
- [ ] Relationships (maybe this can be done through queries, idk) - [ ] 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. * Needed for scripting engines that can create their own components that Rust does not know the types of.
- [ ] Systems - [x] Systems
- [ ] Dispatchers/Executors - [x] Dispatchers/Executors
- [ ] Execution graph that follows dependencies - [x] Execution graph that follows dependencies
- [ ] Track when components on entities are changed
<br>
To be honest, the name may change at some point

View File

@ -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}; use crate::{world::{Entity, ArchetypeEntityId}, bundle::Bundle, component_info::ComponentInfo, DynTypeId};
#[derive(Clone)]
pub struct ComponentColumn { pub struct ComponentColumn {
pub data: RefCell<NonNull<u8>>, pub data: RefCell<NonNull<u8>>,
pub len: usize, 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); pub struct ArchetypeId(pub u64);
impl ArchetypeId { impl ArchetypeId {
@ -200,6 +201,7 @@ impl ArchetypeId {
} }
} }
#[derive(Clone, Default)]
pub struct Archetype { pub struct Archetype {
pub id: ArchetypeId, pub id: ArchetypeId,
pub(crate) entities: HashMap<Entity, ArchetypeEntityId>, pub(crate) entities: HashMap<Entity, ArchetypeEntityId>,

View File

@ -31,8 +31,8 @@ pub struct World {
resources: HashMap<TypeId, ResourceData>, resources: HashMap<TypeId, ResourceData>,
} }
impl World { impl Default for World {
pub fn new() -> Self { fn default() -> Self {
Self { Self {
archetypes: HashMap::new(), archetypes: HashMap::new(),
next_archetype_id: ArchetypeId(0), next_archetype_id: ArchetypeId(0),
@ -42,6 +42,12 @@ impl World {
resources: HashMap::new(), resources: HashMap::new(),
} }
} }
}
impl World {
pub fn new() -> Self {
Self::default()
}
fn get_new_entity(&mut self) -> Entity { fn get_new_entity(&mut self) -> Entity {
match self.dead_entities.pop_front() { match self.dead_entities.pop_front() {
@ -201,6 +207,17 @@ impl World {
self.resources.insert(TypeId::of::<T>(), ResourceData::new(data)); self.resources.insert(TypeId::of::<T>(), 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<T: 'static, F>(&mut self, f: F) -> RefMut<T>
where
F: Fn() -> T + 'static
{
self.resources.entry(TypeId::of::<T>())
.or_insert_with(|| ResourceData::new(f()))
.get_mut()
}
/// Gets a resource from the World. /// Gets a resource from the World.
/// ///
/// Will panic if the resource is not in the world. See [`try_get_resource`] for /// Will panic if the resource is not in the world. See [`try_get_resource`] for