specs 0.15.1

Specs is an Entity-Component-System library written in Rust.
Documentation
# The `setup` stage

So far for all our component storages and resources, we've been adding
them to the `World` manually. In Specs, this is not required if you use
`setup`. This is a manually invoked stage that goes through `SystemData`
and calls `register`, `insert`, etc. for all (with some exceptions)
components and resources found. The `setup` function can be found in
the following locations:

* `ReadStorage`, `WriteStorage`, `Read`, `Write`
* `SystemData`
* `System`
* `RunNow`
* `Dispatcher`
* `ParSeq`

During setup, all components encountered will be registered, and all
resources that have a `Default` implementation or a custom `SetupHandler`
will be added. Note that resources encountered in `ReadExpect` and `WriteExpect`
will not be added to the `World` automatically.

The recommended way to use `setup` is to run it on `Dispatcher` or `ParSeq`
after the system graph is built, but before the first `dispatch`. This will go
through all `System`s in the graph, and call `setup` on each.

Let's say you began by registering Components and Resources first:

```rust,ignore
use specs::prelude::*;

struct Gravity;

struct Velocity;

impl Component for Position {
    type Storage = VecStorage<Self>;
}

struct SimulationSystem;

impl<'a> System<'a> for SimulationSystem {
    type SystemData = (Read<'a, Gravity>, WriteStorage<'a, Velocity>);

    fn run(_, _) {}
}

fn main() {
    let mut world = World::new();
    world.insert(Gravity);
    world.register::<Velocity>();

    for _ in 0..5 {
        world.create_entity().with(Velocity).build();
    }

    let mut dispatcher = DispatcherBuilder::new()
        .with(SimulationSystem, "simulation", &[])
        .build();

    dispatcher.dispatch(&mut world);
    world.maintain();
}

```

You could get rid of that phase by calling `setup()` and re-ordering your main function:

```rust,ignore
fn main() {
    let mut world = World::new();
    let mut dispatcher = DispatcherBuilder::new()
        .with(SimulationSystem, "simulation", &[])
        .build();

    dispatcher.setup(&mut world);

    for _ in 0..5 {
        world.create_entity().with(Velocity).build();
    }

    dispatcher.dispatch(&mut world);
    world.maintain();
}

```


## Custom `setup` functionality

The good qualities of `setup` don't end here however. We can also use `setup`
to create our non-`Default` resources, and also to initialize our `System`s!
We do this by custom implementing the `setup` function in our `System`.

Let's say we have a `System` that process events, using `shrev::EventChannel`:

```rust,ignore
struct Sys {
    reader: ReaderId<Event>,
}

impl<'a> System<'a> for Sys {
    type SystemData = Read<'a, EventChannel<Event>>;

    fn run(&mut self, events: Self::SystemData) {
        for event in events.read(&mut self.reader) {
            [..]
        }
    }
}
```

This looks pretty OK, but there is a problem here if we want to use `setup`.
The issue is that `Sys` needs a `ReaderId` on creation, but to get a `ReaderId`,
we need `EventChannel<Event>` to be initialized. This means the user of `Sys` need
to create the `EventChannel` themselves and add it manually to the `World`.
We can do better!

```rust,ignore
use specs::prelude::*;

#[derive(Default)]
struct Sys {
    reader: Option<ReaderId<Event>>,
}

impl<'a> System<'a> for Sys {
    type SystemData = Read<'a, EventChannel<Event>>;

    fn run(&mut self, events: Self::SystemData) {
        for event in events.read(&mut self.reader.as_mut().unwrap()) {
            [..]
        }
    }

    fn setup(&mut self, world: &mut World) {
        Self::SystemData::setup(world);
        self.reader = Some(world.fetch_mut::<EventChannel<Event>>().register_reader());
    }
}
```

This is much better; we can now use `setup` to fully initialize `Sys` without
requiring our users to create and add resources manually to `World`!

**If we override the `setup` function on a `System`, it is vitally important that we remember to add `Self::SystemData::setup(world);`, or setup will not be performed for the `System`s `SystemData`.**
This could cause panics during setup or during the first dispatch.

## Setting up in bulk

In the case of libraries making use of `specs`, it is sometimes helpful to provide
a way to add many things at once.
It's generally recommended to provide a standalone function to register multiple
Components/Resources at once, while allowing the user to add individual systems
by themselves.

```rust,ignore
fn add_physics_engine(world: &mut World, config: LibraryConfig) -> Result<(), LibraryError> {
    world.register::<Velocity>();
    // etc
}
```