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;