This commit is contained in:
LunarAkai 2025-08-04 23:06:15 +02:00
commit 022fac5966
8 changed files with 150 additions and 13 deletions

View file

@ -0,0 +1,20 @@
use std::{collections::HashMap, marker::PhantomData};
use crate::generational_index::{self, GenerationalIndex};
#[derive(Debug)]
pub struct Component<T: ComponentType> {
id: usize,
component_type: T,
}
pub trait ComponentType{}
impl<T: ComponentType> Component<T> {
pub fn new(id: usize, component_type: T) -> Self {
Self {
id,
component_type
}
}
}

View file

@ -0,0 +1,36 @@
use crate::{entity, generational_index::{GenerationalIndex, GenerationalIndexAllocator}};
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash)]
pub struct Entity(GenerationalIndex);
impl Entity {
pub fn index(&self) -> usize {
self.0.index()
}
pub fn generation(&self) -> u64 {
self.0.generation()
}
}
#[derive(Debug, Clone)]
pub struct EntityAllocator(GenerationalIndexAllocator);
impl EntityAllocator {
pub fn new() -> Self {
EntityAllocator(GenerationalIndexAllocator::new())
}
pub fn allocate(&mut self) -> Entity {
Entity(self.0.allocate())
}
pub fn deallocate(&mut self, entity: Entity) -> bool {
self.0.deallocate(entity.0)
}
pub fn is_live(&self, entity: Entity) -> bool {
self.0.is_live(entity.0)
}
}

View file

@ -1,4 +1,4 @@
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub struct GenerationalIndex {
index: usize,
generation: u64,
@ -14,17 +14,22 @@ impl GenerationalIndex {
}
}
#[derive(Debug, Clone)]
struct AllocatorEntry {
is_live: bool,
generation: u64,
}
#[derive(Debug, Clone, Default)]
pub struct GenerationalIndexAllocator {
entries: Vec<AllocatorEntry>,
free: Vec<usize>,
}
impl GenerationalIndexAllocator {
pub fn new() -> Self {
Default::default()
}
pub fn allocate(&mut self) -> GenerationalIndex {
match self.free.pop() {
Some(index) =>{
@ -64,6 +69,10 @@ impl GenerationalIndexAllocator {
pub fn is_live(&self, index: GenerationalIndex) -> bool {
index.index() < self.entries.len() && self.entries[index.index()].generation == index.generation && self.entries[index.index()].is_live
}
pub fn max_allocated_index(&self) -> usize {
self.entries.len()
}
}
struct ArrayEntry<T> {
@ -74,7 +83,15 @@ struct ArrayEntry<T> {
pub struct GenerationalIndexArray<T>(Vec<Option<ArrayEntry<T>>>);
impl <T> GenerationalIndexArray<T> {
pub fn set(&mut self, index: GenerationalIndex, value: T) {
pub fn new() -> GenerationalIndexArray<T> {
GenerationalIndexArray(Vec::new())
}
pub fn clear(&mut self) {
self.0.clear();
}
pub fn insert(&mut self, index: GenerationalIndex, value: T) {
while self.0.len() <= index.index() {
self.0.push(None);
}

View file

@ -1,15 +1,55 @@
use std::{collections::HashMap, path::{Component, Components}};
use anymap::AnyMap;
use crate::generational_index::{GenerationalIndex, GenerationalIndexAllocator, GenerationalIndexArray};
use crate::{entity::{Entity, EntityAllocator}, generational_index::{GenerationalIndex, GenerationalIndexAllocator, GenerationalIndexArray}};
pub mod generational_index;
pub mod world;
pub mod entity;
pub mod component;
pub type Entity = GenerationalIndex;
pub type EntityMap<T> = GenerationalIndexArray<T>;
// based on: https://kyren.github.io/2018/09/14/rustconf-talk.html
/* Moonhare ECS Design
--------------------------------------
Game
🠟
Systems
(RenderSystem, PhysicsSystem, EnemyAISystem, EnemyCollisionSystem,...)
🠟
Entity
🠟
Components
--------------------------------------
*/
#[derive(Debug)]
pub struct ECS {
pub entity_allocator: GenerationalIndexAllocator,
pub entity_components: AnyMap,
pub resources: AnyMap
}
entities: EntityAllocator,
components: AnyMap
}
impl ECS {
pub fn new() -> ECS {
ECS {
entities: EntityAllocator::new(),
components: AnyMap::new(),
}
}
pub fn add_entity(&mut self) -> Entity {
self.entities.allocate()
}
pub fn entity_is_live(&self, entity: Entity) -> bool {
self.entities.is_live(entity)
}
pub fn register_component() {
}
}

View file

@ -0,0 +1,22 @@
use std::fmt::Error;
use anymap::AnyMap;
use crate::{Entity, ECS};
/// stores Entitys, Components and resources
/// provides methods to search for specific Entitys
#[derive(Debug)]
pub struct World {
ecs: ECS,
resources: AnyMap
}
impl World {
pub fn new() -> Self {
Self {
ecs: ECS::new(),
resources: AnyMap::new(),
}
}
}