Skip to content

Commit

Permalink
Merge #322
Browse files Browse the repository at this point in the history
322: Document aliasing rules for resources r=torkleyy a=torkleyy

Fixes #314

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/slide-rs/specs/322)
<!-- Reviewable:end -->
  • Loading branch information
bors[bot] committed Dec 25, 2017
2 parents ec80a40 + a18f62d commit 7d2ec0a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
24 changes: 24 additions & 0 deletions book/src/06_system_data.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# [DRAFT] System Data

Every system can request data which it needs to run. This data can be specified
using the `System::SystemData` type. Typical implementors of the `SystemData` trait
are `ReadStorage`, `WriteStorage`, `Fetch`, `FetchMut` and `Entities`.
A tuple of types implementing `SystemData` automatically also implements `SystemData`.
This means you can specify your `System::SystemData` as follows:

```rust
struct Sys;

impl<'a> System<'a> for Sys {
type SystemData = (WriteStorage<'a, Pos>, ReadStorage<'a, Vel>);

fn run(&mut self, (pos, vel): Self::SystemData) {
/* ... */
}
}
```

It is very important that you don't fetch both a `ReadStorage` and a `WriteStorage`
for the same component or a `Fetch` and a `FetchMut` for the same resource.
This is just like the borrowing rules of Rust, where you can't borrow something
mutably and immutably at the same time. In Specs, we have to check this at
runtime, thus you'll get a panic if you don't follow this rule.

## Accessing Entities

You want to create/delete entities from a system? There is
Expand Down
20 changes: 20 additions & 0 deletions src/storage/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ use storage::MaskedStorage;
/// however make sure to also check out the documentation for the
/// respective methods on `Storage`.
///
/// ## Aliasing
///
/// **It is strictly disallowed to fetch both a `ReadStorage` and a `WriteStorage`
/// of the same component.**
/// Because Specs uses interior mutability for its resources, we can't check
/// this at compile time. If you try to do this, you will get a panic.
///
/// It is explicitly allowed to fetch multiple `ReadStorage`s for the same
/// component.
///
/// ## Joining storages
///
/// `&ReadStorage` implements `Join`, which allows to do
Expand Down Expand Up @@ -124,6 +134,16 @@ where
///
/// Additionally to what `ReadStorage` can do a storage with mutable access allows:
///
/// ## Aliasing
///
/// **It is strictly disallowed to fetch both a `ReadStorage` and a `WriteStorage`
/// of the same component.**
/// Because Specs uses interior mutability for its resources, we can't check
/// this at compile time. If you try to do this, you will get a panic.
///
/// It is also disallowed to fetch multiple `WriteStorage`s for the same
/// component.
///
/// ## Retrieve components mutably
///
/// This works just like `Storage::get`, but returns a mutable reference:
Expand Down
4 changes: 2 additions & 2 deletions src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ impl World {
///
/// ## Panics
///
/// Panics if it is already borrowed.
/// Panics if it is already borrowed (either immutably or mutably).
/// Panics if the component has not been registered.
pub fn write<T: Component>(&self) -> WriteStorage<T> {
self.write_with_id(0)
Expand All @@ -426,7 +426,7 @@ impl World {
///
/// # Panics
///
/// Panics if it is already borrowed.
/// Panics if it is already borrowed (either immutably or mutably).
/// Also panics if the component is not registered with `World::register`.
pub fn write_with_id<T: Component>(&self, id: usize) -> WriteStorage<T> {
let entities = self.entities();
Expand Down

0 comments on commit 7d2ec0a

Please sign in to comment.