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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
//! Entities, resources, components, and general world management. pub use shred::World; pub use self::{ comp::Component, entity::{ CreateIterAtomic, Entities, EntitiesRes, Entity, EntityResBuilder, Generation, Index, }, lazy::{LazyBuilder, LazyUpdate}, world_ext::WorldExt, }; use shred::{FetchMut, SystemData}; use crate::storage::WriteStorage; mod comp; mod entity; mod lazy; #[cfg(test)] mod tests; mod world_ext; /// An iterator for entity creation. /// Please note that you have to consume /// it because iterators are lazy. /// /// Returned from `World::create_iter`. pub struct CreateIter<'a>(FetchMut<'a, EntitiesRes>); impl<'a> Iterator for CreateIter<'a> { type Item = Entity; fn next(&mut self) -> Option<Entity> { Some(self.0.alloc.allocate()) } } /// A common trait for `EntityBuilder` and `LazyBuilder`, allowing either to be /// used. Entity is definitely alive, but the components may or may not exist /// before a call to `World::maintain`. pub trait Builder { /// Appends a component and associates it with the entity. /// /// If a component was already associated with the entity, it should /// overwrite the previous component. /// /// # Panics /// /// Panics if the component hasn't been `register()`ed in the /// `World`. fn with<C: Component + Send + Sync>(self, c: C) -> Self; /// Finishes the building and returns the entity. fn build(self) -> Entity; } /// The entity builder, allowing to /// build an entity together with its components. /// /// ## Examples /// /// ``` /// use specs::{prelude::*, storage::HashMapStorage}; /// /// struct Health(f32); /// /// impl Component for Health { /// type Storage = HashMapStorage<Self>; /// } /// /// struct Pos { /// x: f32, /// y: f32, /// } /// /// impl Component for Pos { /// type Storage = DenseVecStorage<Self>; /// } /// /// let mut world = World::new(); /// world.register::<Health>(); /// world.register::<Pos>(); /// /// let entity = world /// .create_entity() // This call returns `EntityBuilder` /// .with(Health(4.0)) /// .with(Pos { x: 1.0, y: 3.0 }) /// .build(); // Returns the `Entity` /// ``` /// /// ### Distinguishing Mandatory Components from Optional Components /// /// ``` /// use specs::{prelude::*, storage::HashMapStorage}; /// /// struct MandatoryHealth(f32); /// /// impl Component for MandatoryHealth { /// type Storage = HashMapStorage<Self>; /// } /// /// struct OptionalPos { /// x: f32, /// y: f32, /// } /// /// impl Component for OptionalPos { /// type Storage = DenseVecStorage<Self>; /// } /// /// let mut world = World::new(); /// world.register::<MandatoryHealth>(); /// world.register::<OptionalPos>(); /// /// let mut entitybuilder = world.create_entity().with(MandatoryHealth(4.0)); /// /// // something trivial to serve as our conditional /// let include_optional = true; /// /// if include_optional == true { /// entitybuilder = entitybuilder.with(OptionalPos { x: 1.0, y: 3.0 }) /// } /// /// let entity = entitybuilder.build(); /// ``` #[must_use = "Please call .build() on this to finish building it."] pub struct EntityBuilder<'a> { /// The (already created) entity for which components will be inserted. pub entity: Entity, /// A reference to the `World` for component insertions. pub world: &'a World, built: bool, } impl<'a> Builder for EntityBuilder<'a> { /// Inserts a component for this entity. /// /// If a component was already associated with the entity, it will /// overwrite the previous component. #[inline] fn with<T: Component>(self, c: T) -> Self { { let mut storage: WriteStorage<T> = SystemData::fetch(&self.world); // This can't fail. This is guaranteed by the lifetime 'a // in the EntityBuilder. storage.insert(self.entity, c).unwrap(); } self } /// Finishes the building and returns the entity. As opposed to /// `LazyBuilder`, the components are available immediately. #[inline] fn build(mut self) -> Entity { self.built = true; self.entity } } impl<'a> Drop for EntityBuilder<'a> { fn drop(&mut self) { if !self.built { self.world .read_resource::<EntitiesRes>() .delete(self.entity) .unwrap(); } } }