entity_data/
lib.rs

1//! A container for entity component data.
2//!
3//! # Use Case
4//! Suppose you need to store large amounts of objects, each of which can have different fields.
5//! But you don't want to use Rust's dynamic-dispatch feature for the following reasons:
6//! 1. Virtual dispatch induces indirection.
7//! 2. You will have to store every object somewhere on heap.
8//! That leads to cache-misses and hence slower iteration over the objects.
9//!
10//! Data-oriented programming helps to overcome these issues.
11//!
12//! # The Architecture
13//!
14//! An *entity* is an identifier for an object.
15//! Each entity can have multiple components ("fields") associated with it.
16//! The storage of all components itself is based on [ECS](https://en.wikipedia.org/wiki/Entity_component_system) technique.
17//!
18//! A unique set of components is called an `Archetype`.
19//! An archetype maintains a contiguous vector for each of its component types.
20//!
21//! # Examples
22//!
23//! Simple usage:
24//! ```
25//! use entity_data::{EntityStorage, Archetype};
26//!
27//! struct Barks {
28//!     bark_sound: String,
29//! }
30//!
31//! impl Barks {
32//!     fn bark(&self) {
33//!         println!("{}", self.bark_sound);
34//!     }
35//! }
36//!
37//! struct Eats {
38//!     favorite_food: String,
39//!     eaten_food: Vec<String>,
40//! }
41//!
42//! impl Eats {
43//!     fn eat(&mut self, food: String) {
44//!         self.eaten_food.push(food);
45//!     }
46//! }
47//!
48//! struct Animal {
49//!     weight: f32,
50//!     habitat: String,
51//! }
52//!
53//! #[derive(Archetype)]
54//! struct Dog {
55//!     animal: Animal,
56//!     barks: Barks,
57//!     eats: Eats,
58//! }
59//!
60//! #[derive(Archetype)]
61//! struct Bird(Animal, Eats);
62//!
63//! fn main() {
64//!     let mut storage = EntityStorage::new();
65//!
66//!     let super_dog_entity = storage.add(Dog {
67//!         animal: Animal { weight: 30.0, habitat: "forest".to_string(), },
68//!         barks: Barks { bark_sound: "bark.ogg".to_string(), },
69//!         eats: Eats { favorite_food: "meat".to_string(), eaten_food: vec![] },
70//!     });
71//!
72//!     let hummingbird_entity = storage.add(Bird(
73//!         Animal { weight: 5.0, habitat: "gardens".to_string()},
74//!         Eats { favorite_food: "apples".to_string(), eaten_food: vec![] }
75//!     ));
76//!
77//!     let mut  super_dog = storage.entry_mut(&super_dog_entity).unwrap();
78//!     let super_dog_barks = super_dog.get::<Barks>().unwrap();
79//!     super_dog_barks.bark();
80//!
81//!     let super_dog_eats = super_dog.get_mut::<Eats>().unwrap();
82//!     super_dog_eats.favorite_food = "beans".to_string();
83//!
84//!     let hummingbird_eats = storage.get_mut::<Eats>(&hummingbird_entity).unwrap();
85//!     hummingbird_eats.eat("seeds".to_string());
86//! }
87
88#[cfg(test)]
89mod tests;
90
91pub mod archetype;
92pub mod entity;
93pub mod entity_storage;
94pub mod entry;
95pub mod private;
96pub mod state;
97pub mod system;
98
99pub use archetype::ArchetypeStorage;
100pub use archetype::component::Component;
101pub use archetype::entities::ArchetypeEntities;
102pub use entity::EntityId;
103pub use entity_storage::EntityStorage;
104pub use entry::{Entry, EntryMut};
105pub use macros::Archetype;
106pub use state::{AnyState, ArchetypeState, StaticArchetype};
107pub use system::component::{GenericComponentGlobalAccess, GlobalComponentAccess};
108pub use system::{System, SystemAccess, SystemHandler};
109
110pub(crate) type HashMap<K, V> = ahash::AHashMap<K, V>;
111
112extern crate self as entity_data;