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
//! Worlds store collections of entities. An entity is a collection of components, identified
//! by a unique [`Entity`] ID.
//!
//! # Creating a world
//!
//! ```
//! # use legion::*;
//! let mut world = World::default();
//! ```
//!
//! `World::new()` can be used to construct a new world with custom options.
//!
//! # Inserting entities
//!
//! Entities can be inserted via either `push` (for a single entity) or `extend` (for a collection
//! of entities with the same component types). The world will create a unique ID for each entity
//! upon insertion that you can use to refer to that entity later.
//!
//! ```
//! # use legion::*;
//! # let mut world = World::default();
//! // a component is any type that is 'static, sized, send and sync
//! #[derive(Clone, Copy, Debug, PartialEq)]
//! struct Position {
//! x: f32,
//! y: f32,
//! }
//!
//! #[derive(Clone, Copy, Debug, PartialEq)]
//! struct Velocity {
//! dx: f32,
//! dy: f32,
//! }
//!
//! // push a component tuple into the world to create an entity
//! let entity: Entity = world.push((Position { x: 0.0, y: 0.0 }, Velocity { dx: 0.0, dy: 0.0 }));
//!
//! // or extend via an IntoIterator of tuples to add many at once
//! // this is faster than individual pushes
//! let entities: &[Entity] = world.extend(vec![
//! (Position { x: 0.0, y: 0.0 }, Velocity { dx: 0.0, dy: 0.0 }),
//! (Position { x: 1.0, y: 1.0 }, Velocity { dx: 0.0, dy: 0.0 }),
//! (Position { x: 2.0, y: 2.0 }, Velocity { dx: 0.0, dy: 0.0 }),
//! ]);
//! ```
//!
//! If your data is already organized as such, you can alternatively insert entities as a
//! strucure-of-arrays.
//!
//! ```
//! # use legion::*;
//! let mut world = World::default();
//! let _entities = world.extend(
//! (
//! vec![1usize, 2usize, 3usize],
//! vec![false, true, false],
//! vec![5.3f32, 5.3f32, 5.2f32],
//! )
//! .into_soa(),
//! );
//! ```
//!
//! SoA inserts require all vectors to have the same length. These inserts are faster than inserting
//! via an iterator of tuples.
//!
//! # Modifying entities
//!
//! Components can be added or removed from an existing entity via the [`Entry`] API.
//!
//! ```
//! # use legion::*;
//! # let mut world = World::default();
//! # let entity = world.push((false, 1usize));
//! // entries return `None` if the entity does not exist
//! if let Some(mut entry) = world.entry(entity) {
//! // add an extra component
//! entry.add_component(12f32);
//!
//! // remove a component
//! entry.remove_component::<usize>();
//! }
//! ```
//!
//! Note that it is significantly faster to create an entity with its initial set of components
//! via `push` or `extend` than it is to add the components one-by-one after creating the entity.
//!
//! # Accessing components
//!
//! The fastest way to access a large number of entities' components is via [queries](crate::query).
//!
//! The entry API also allows access to an individual entity's components.
//!
//! ```
//! # use legion::*;
//! # let mut world = World::default();
//! # let entity = world.push((false, 12f32));
//! // entries return `None` if the entity does not exist
//! if let Some(mut entry) = world.entry(entity) {
//! // access information about the entity's archetype
//! println!(
//! "{:?} has {:?}",
//! entity,
//! entry.archetype().layout().component_types()
//! );
//!
//! // access the entity's components, returns `None` if the entity does not have the component
//! assert_eq!(entry.get_component::<f32>().unwrap(), &12f32);
//! }
//! ```
//!
//! # Events
//!
//! Notifications about archetype creation and entity insertion/removal from an archetype can be sent
//! to an [`EventSender`] by subscribing to the world. A layout filter specifies which archetypes the
//! subscriber is interested in.
//!
//! ```ignore
//! # use legion::*;
//! # let mut world = World::default();
//! # struct Position;
//! // subscribe to events involving entities with a `Position` with a
//! // crossbeam channel.
//! let (tx, rx) = crossbeam_channel::unbounded::<legion::world::Event>();
//! world.subscribe(tx, component::<Position>());
//! ```
//!
//! # World splitting
//!
//! World splitting allows mutable access to a world via multiple entries or queries at the same time,
//! provided that their component accesses do not conflict with one another.
//!
//! ```
//! # use legion::*;
//! # struct A;
//! # struct B;
//! # struct C;
//! let mut world = World::default();
//! let entity = world.push((A, B, C));
//! let (mut left, mut right) = world.split::<(Read<A>, Write<B>)>();
//!
//! // left only has permission to read A and read/write B.
//! let b: &mut B = left
//! .entry_mut(entity)
//! .unwrap()
//! .get_component_mut::<B>()
//! .unwrap();
//!
//! // right can access anything _but_ writes to A and read/write to B.
//! let a: &A = right
//! .entry_ref(entity)
//! .unwrap()
//! .get_component::<A>()
//! .unwrap();
//! let c: &C = right
//! .entry_ref(entity)
//! .unwrap()
//! .get_component::<C>()
//! .unwrap();
//! ```
pub use crate::internals::{
entity::{Allocate, Entity, EntityHasher, EntityLocation, LocationMap},
entry::{ComponentError, Entry, EntryMut, EntryRef},
event::{Event, EventSender},
permissions::Permissions,
subworld::{ArchetypeAccess, ComponentAccess, SubWorld},
world::{
Duplicate, EntityAccessError, EntityRewrite, EntityStore, Merger, StorageAccessor, World,
WorldId, WorldOptions,
},
};