bevyengine / bevyengine/bevy

`StaticSystemParam` usage

Open
#10,850 2 comments 0 reactions 0 assignees View on GitHub
A-ECS C-Docs
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

_For context i am fairly new to Rust and very new to Bevy and games programming_

## How can Bevy's documentation be improved?
While learning how to use bevy I came across the `SystemParam` derive and usage which i found to be incredibly ergonomic and straightforward, upon further use I found a use-case where i wanted to make my `SystemParam` generic and the documentation obligingly pointed me to `StaticSystemParam` ([docs](https://docs.rs/bevy/latest/bevy/ecs/system/struct.StaticSystemParam.html)), all good so far.

My issue was actually making use of the generic nature of of this param, and while the docs do have this section:

> Note that in a real case you’d generally want additional bounds on P, for your use of the parameter to have a reason to be generic.
>
> For example, using this would allow a type to be generic over whether a resource is accessed mutably or not, with impls being bounded on [P: Deref](https://doc.rust-lang.org/nightly/core/ops/deref/trait.Deref.html), and [P: DerefMut](https://doc.rust-lang.org/nightly/core/ops/deref/trait.DerefMut.html) depending on whether the method requires mutable access or not.

It was not clear to me what this `P` was or how to implement this bound correctly in my code, and the example above in the docs:

>` fn do_thing_generically(t: StaticSystemParam) {}`

Also lead to confusion as the `StaticSystemParam` / `SystemParamItem` / `SystemParm` types & traits are not super straightforward to use as a beginner and using a `StaticSystemParam` as the underlying `T` (which is presumably what people want to do) is a little tricky

## Suggested solution

I'd like to see a more concrete example on how to use `StaticSystemParam` properly. My implementation ended up looking something like this:

```rust
trait MyTrait{
fn does_something(&self);
}

#[derive(SystemParam)]
struct Param1;

impl MyTrait for Param1{
fn does_something(&self){
info!("Hello from 1");
}
}

#[derive(SystemParam)]
struct Param2;

impl MyTrait for Param2{
fn does_something(&self){
info!("Hello from 2");
}
}

#[derive(SystemParam)]
struct GenericParam<'w,'s,T>
where for<'w2, 's2> SystemParamItem<'w2, 's2, T>: MyTrait, T:SystemParam + 'static
{
param: StaticSystemParam<'w,'s,T>
}

impl GenericParam<'_,'_,T>
where for<'w2, 's2> SystemParamItem<'w2, 's2, T>: MyTrait, T:SystemParam + 'static
{
pub fn do_it(&self){
param.deref().does_something();
}
}
```
### Requests for feedback
1. I'm not sure if this should live in the code docs or if it's better suited as an example
2. I'm not sure my implementation is best practice
3. If this is to be an example, then should the existing code docs change and if so how?
4. If this is to be an example, then is there a better more concrete use-case here? My use-case was for getting the size of a sprite out of either a texture atlas or just an image.

Contributor guide

Open the contributing guide

Research direction

Start with the StaticSystemParam documentation on docs.rs and compare its generic example with the reporter's concrete GenericParam implementation. Determine whether the explanation belongs in the code docs or an example, then clarify what P, SystemParamItem, and the relevant trait bounds represent and show a concrete use case.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
documentation
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.