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());
//! }
pub use ArchetypeStorage;
pub use Component;
pub use ArchetypeEntities;
pub use EntityId;
pub use EntityStorage;
pub use ;
pub use Archetype;
pub use ;
pub use ;
pub use ;
pub type HashMap<K, V> = AHashMap;
extern crate self as entity_data;