Provide map() and map_mut() for par_iter_mut()
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## What problem does this solve or what need does it fill?
For when you need to iterate through a query and generate some sort of result from each of the parallel iterators. e.g. reading websockets of sessions and then returning the locally collected requests, flattening it and collecting them all into a single requests list for further processing.
## What solution would you like?
I would like `map()` and `map_mut()` (because websocket readers require mutable access). They should be used like so:
```rust
fn read_ws(mut query: Query<(&mut WsReader)>) {
let reqs = query
.par_iter_mut()
.map_mut(|(mut ws_reader)| {
let mut reqs = Vec::new();
// ... reading from the ws reader
reqs
})
.flatten()
.collect::>();
}
```
## What alternative(s) have you considered?
The alternative is cumbersome, but doable:
```rust
let len = query.iter().len();
let mut i = AtomicUsize::new(0);
let mut reqs = Arc::>>>::default();
reqs.resize_with(len, || MaybeUninit::uninit());
query.par_iter_mut().for_each_mut(|(mut ws_reader)| {
let local_i = i.fetch_add(1, std::sync::atomic::Ordering::AcqRel);
let mut local_reqs = Vec::new();
// ... read from ws
reqs[local_i] = MaybeUninit::new(local_reqs);
});
let reqs = unsafe { std::mem::transmute::<_, Vec>>(results) };
// do something with reqs
```
As you can see, not very pretty.
Contributor guide
Research direction
Start by locating the Query::par_iter_mut() and existing for_each_mut() entry points, then compare how their iterator chains are built. Done means the requested map() and map_mut() calls support the shown flatten() and collect() workflow, including mutable websocket access.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100