shipyard 0.11.2

Entity Component System
Documentation
0.4 comes with a few big changes, this chapter aims to facilitate the transition.

## Imports


Let's start small, prelude and internal no longer exist, you just have to replace all `shipyard::prelude` and `shipyard::internal` by `shipyard`.

## Systems


Following [an issue](https://github.com/leudz/shipyard/issues/75) opened by [@cart](https://github.com/cart), systems will become functions instead of an instance of the `System` trait.  

To make this work, borrowing is now done with the actual types you get when you borrow a storage instead of using references.  

In 0.3:
```rust, noplaypen
struct MySystem;
impl<'sys> System<'sys> for MySystem {
    type Data = (
        EntitiesMut,
        &mut usize,
    );
    fn run((mut entities, mut usizes): <Self::Data as SystemData<'sys>>::View) {}
}

// or with the macro

#[system(MySystem)]

fn run(mut entities: &mut Entities, mut usizes: &mut usize) {}
```
In 0.4:
```rust, noplaypen
fn my_system(mut entities: EntitiesViewMut, mut usizes: ViewMut<usize>) {}
```

This change also affects `run` and `borrow`.  
`World::run_system` is no longer needed and you can run systems with `run` directly.

```rust, noplaypen
world.run(my_system);

// and closures still work

world.run(|mut entities: EntitiesViewMut, mut usizes: ViewMut<usize>| {});
```

`run` has the same return type as the system or closure and it doesn't require any tuple most of the time.

Here's the complete list:

0.3|0.4
:---:|:---:
`AllStorages` / `&mut AllStorages`|[`AllStoragesViewMut`]https://docs.rs/shipyard/latest/shipyard/struct.AllStoragesViewMut.html
`Entities` / `&Entities`|[`EntitiesView`]https://docs.rs/shipyard/latest/shipyard/struct.EntitiesView.html
`EntitiesMut` / `&mut Entities`|[`EntitiesViewMut`]https://docs.rs/shipyard/latest/shipyard/struct.EntitiesViewMut.html
`&T`|[`View<T>`]https://docs.rs/shipyard/latest/shipyard/struct.View.html
`&mut T`|[`ViewMut<T>`]https://docs.rs/shipyard/latest/shipyard/struct.ViewMut.html
`ThreadPool` / `&ThreadPool`|[`ThreadPoolView`]https://docs.rs/shipyard/latest/shipyard/struct.ThreadPoolView.html
`Unique<&T>`|[`UniqueView<T>`]https://docs.rs/shipyard/latest/shipyard/struct.UniqueView.html
`Unique<&mut T>`|[`UniqueViewMut<T>`]https://docs.rs/shipyard/latest/shipyard/struct.UniqueViewMut.html
`NonSend<&T>`|[`NonSend<View<T>>`]https://docs.rs/shipyard/latest/shipyard/struct.NonSend.html
`NonSend<&mut T>`|[`NonSend<ViewMut<T>>`]https://docs.rs/shipyard/latest/shipyard/struct.NonSend.html
`Unique<NonSend<&T>>`|[`NonSend<UniqueView<T>>`]https://docs.rs/shipyard/latest/shipyard/struct.NonSend.html
`Unique<NonSend<&mut T>>`|[`NonSend<UniqueViewMut<T>>`]https://docs.rs/shipyard/latest/shipyard/struct.NonSend.html
`FakeBorrow<T>`|[`FakeBorrow<T>`]https://docs.rs/shipyard/latest/shipyard/struct.FakeBorrow.html

[`NonSync`](https://docs.rs/shipyard/latest/shipyard/struct.NonSync.html) and [`NonSendSync`](https://docs.rs/shipyard/latest/shipyard/struct.NonSendSync.html) follow the same pattern as `NonSend`.

## Macro


The system proc macro doesn't exist anymore. With the new system design the advantage it provides are not great enough to justify it.

## Workloads


### The ugly


Workloads are the only one suffering a downgrade. You'll have to give all systems twice to the function plus a few things.

In 0.3:
```rust, noplaypen
world.add_workload<(Sys1, Sys2), _>("Workload1");
```
In 0.4:
```rust, noplaypen
world
    .add_workload("Workload1")
    .with_system((
        |world: &World| world.try_run(sys1),
        sys1
    ))
    .with_system((
        |world: &World| world.try_run(sys2),
        sys2
    ))
    .build();

// with a macro

world
    .add_workload("Workload1")
    .with_system(system!(sys1))
    .with_system(system!(sys2))
    .build();
```

⚠️ The two arguments are wrapped in a tuple.

This repetition will disappear someday but I don't expect it to be soon.  
You don't have to use a closure, any function with `&World` as argument and returning `Result<(), shipyard::error::Run>` are valid.  
It's very important to pass the same function twice, the workload might always error if this isn't the case.

### The good


Workloads don't come with only a downgrade. You can now return errors from systems inside workloads.

```rust, noplaypen
#[derive(Debug)]

struct TerribleError;

impl Display for TerribleError {
    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
        Debug::fmt(self, fmt)
    }
}
impl Error for TerribleError {}

fn my_sys(mut entities: EntitiesViewMut) -> Result<(), TerribleError> {
    Err(TerribleError)
}

fn main() {
    use shipyard::error::{Run, RunWorkload};

    let world = World::new();
    world
        .add_workload("May fail")
        .with_system((
            |world: &World| world.try_run(my_sys)?.map_err(Run::from_custom),
            my_sys,
        ))
        .build();
    match world.try_run_default().map_err(RunWorkload::custom_error) {
        Err(Some(error)) => {
            assert!(error.is::<TerribleError>());
        }
        _ => {}
    }
}
```

The error has to be anonymized so you'll get back a `Box<dyn Error + Send>` with std and a `Box<dyn Any + Send>` with no_std.  
Workloads stop at the first error encountered, just like 0.3.  
You can also use the `try_system!` macro the same way as `system!`.

```rust, noplaypen
world
    .add_workload("May fail")
    .with_system(try_system!(my_sys))
    .build();
```
It'll generate the same code as above.

## Iterator


You can now use `std::iter::Iterator` and `for loop` with views without having to call `into_iter`.  
All iteration code from 0.3 will still work.

```rust, noplaypen
fn my_sys((mut usizes, u32s): (ViewMut<usize>, View<u32>)) {
    for (i, &j) in (&mut usizes, &u32s).iter() {
        *i += j as usize;
    }
}
```

## Get


The `GetComponent` trait has been renamed `Get`.

What follows is only true for 0.4. 0.5 went back to `get` returning a `Result`.  
`Get::get` has been renamed `try_get` and a new `get` method has been added to unwrap errors.

If you used `get` followed by `unwrap`, you can simply remove the `unwrap`.  
If you used another error handling method you'll have to replace `get` by `try_get`.