xecs/lib.rs
1//! # XECS
2//! An Entity-Component-System library
3//! ## Simple Example
4//! ```rust,no_run
5//! // Define two components struct
6//! // Component is Send + Sync + 'static
7//! #[derive(Debug,Copy)]
8//! struct Position{
9//! x : f32,
10//! y : f32
11//! };
12//! struct Hidden;
13//!
14//! // create an empty world
15//! let mut world = World::new();
16//!
17//! // generate 10 entities
18//! for _ in 0..10 {
19//! let x = random();
20//! lety = random();
21//! // andomly generate the positions
22//! world.create_entity()
23//! .attach(Position { x,y });
24//! }
25//!
26//! // print all postions
27//! for pos in world.query::<&Position>() {
28//! print!("{:?}",pos)
29//! }
30//!
31//! // filter some entities need to be hidden
32//! let ids = world.query::<&Position>()
33//! .with_id()
34//! .filter(|(_,_)|random())
35//! .map(|(id,_)|id)
36//! .collect::<Vec<_>>();
37//!
38//! // attach hidden to id
39//! for id in ids {
40//! world.attach_component(id,Hidden);
41//! }
42//!
43//! // make a full-owning group to accelerate the query
44//! world.make_group(full_owning::<Hidden,Position>());
45//!
46//! // only print postions with id that is not hidden
47//! for (id,data) in world.query::<&Position,Without<&Hidden>>() {
48//! print!("{}:{:?}",id,data);
49//! }
50//! ```
51//!
52//! # About entity
53//! Entity in XECS is just an number ID.In XECS, it's just a
54//! [NonZeroUsize](std::num::NonZeroUsize).
55//! The ID is allocated from 1 by world automatically. The ```id=0```
56//! represents a recycled ID without any other flags through ```Option<EntityId>```.
57//!
58//! # ID recycling
59//! When you call ```world.create_entity()```, an ID will be allocated automatically.
60//! If you call ```world.remove_entity(id)```, this ID will be a pit. If the
61//! next ```world.create_entity()``` is called, it will allocate this ID to fill
62//! the pit.Thanks to sparse set, it's still fast to
63//! iterate all components no matter how random of ID
64//!
65//! # Concurrency Safety
66//! Because [Component](crate::component::Component) is just ```T : Send + Sync```.
67//! [World](crate::world::World) can use [RwLock](std::sync::RwLock) to
68//! ensure the borrow check relations of all components.And [World](crate::world::World) can also
69//! be ```Send + Sync```.Therefore,the all other states of world can be guarded
70//! by [RwLock](std::sync::RwLock).So we can use world in concurrency environment by ```RwLock<World>```.
71//!
72//! # System in XECS
73//! System is a [Stream](futures::Stream) with [World](crate::world::World)
74//! as Context. Because [Stream](futures::Stream) is not stable
75//! in [std](std), XECS use [futures](futures)::[Stream](futures::Stream) instead.
76//! # To Run System
77//! Because system is just an async trait, you need a wrapper of runtime from
78//! [tokio](https://tokio.rs) or [async-std](https://async.rs)
79mod world;
80mod entity;
81mod component;
82mod system;
83mod resource;
84/// Some things to accelerate the iteration
85pub mod group;
86/// The query functions
87pub mod query;
88pub(in crate) mod sparse_set;
89/// The resource type
90
91pub use world::World;
92pub use entity::{
93 EntityId,
94 Entity,
95 Entities,
96};
97pub use component::{
98 Component,
99 ComponentRead,
100 ComponentWrite,
101 ComponentStorage,
102 StorageRead,
103 StorageWrite
104};
105pub use system::System;
106pub use resource::{
107 Resource,
108 ResourceRead,
109 ResourceWrite
110};
111