* ResourceTypeId, ComponentTypeId, TagTypeId use static str (std::any::type_name) instead of TypeId (std::any::TypeId is not constant across rust binaries)
* Implement "DowncastTypeName" to allow downcasting based on type name
## Benchmarks
Based on the [ecs_bench](https://github.com/lschmierer/ecs_bench) project.
![](bench.png)
## Getting Started
```rust
use legion::prelude::*;
// Define our entity data types
#[derive(Clone, Copy, Debug, PartialEq)]
struct Position {
x: f32,
y: f32,
}
#[derive(Clone, Copy, Debug, PartialEq)]
struct Velocity {
dx: f32,
dy: f32,
}
#[derive(Clone, Copy, Debug, PartialEq)]
struct Model(usize);
#[derive(Clone, Copy, Debug, PartialEq)]
struct Static;
// Create a world to store our entities
let universe = Universe::new();
let mut world = universe.create_world();
// Create entities with `Position` and `Velocity` data
// these entities are also either marked as `Static`, or do *not* have a `Velocity`
}
```
Filter by shared data value:
```rust
// Filters can filter by specific shared data values
let query = Read::<Position>::query()
.filter(tag_value(&Model(3)));
for position in query.iter(&mut world) {
// these entities all have shared data value `Model(3)`
}
```
Change detection:
```rust
// Queries can perform coarse-grained change detection, rejecting entities who's data
// has not changed since the last time the query was iterated.
let query = <(Read<Position>, Shared<Model>)>::query()
.filter(changed::<Position>());
for (pos, model) in query.iter(&mut world) {
// entities who have changed position
}
```
### Content Streaming
Entities can be loaded and initialized in a background `World` on separate threads and then
when ready, merged into the main `World` near instantaneously.
```rust
let universe = Universe::new();
let mut world_a = universe.create_world();
let mut world_b = universe.create_world();
// Merge all entities from `world_b` into `world_a`
// Entity IDs are guarenteed to be unique across worlds and will
// remain unchanged across the merge.
world_a.merge(world_b);
```
### Chunk Iteration
Entity data is allocated in blocks called "chunks", each approximately containing 64KiB of data. The query API exposes each chunk via `iter_chunk`. As all entities in a chunk are guarenteed to contain the same set of entity data and shared data values, it is possible to do batch processing via the chunk API.