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