I find myself often implementing the following pattern, where I create a separate version of a SystemParam that operates on read-only data instead of mutable data:
#[derive(SystemParam)]
pub struct ChunkMapper<'w, 's> {
map: Res<'w, ChunkMap>,
chunks: Query<'w, 's, &'static Chunk, With<IsChunk>>,
}
impl<'w, 's> ChunkMapper<'w, 's> {
pub fn get_chunk(&self, position: &ChunkPos) -> Option<&Chunk> {
let entity = self.map.get(position)?;
self.chunks.get(*entity).ok()
}
}
#[derive(SystemParam)]
pub struct ChunkMapperMut<'w, 's> {
map: Res<'w, ChunkMap>,
chunks: Query<'w, 's, &'static mut Chunk, With<IsChunk>>,
}
impl<'w, 's> ChunkMapperMut<'w, 's> {
pub fn get_chunk(&self, position: &ChunkPos) -> Option<&Chunk> {
let entity = self.map.get(position)?;
self.chunks.get(*entity).ok()
}
pub fn get_chunk_mut(&mut self, position: &ChunkPos) -> Option<Mut<Chunk>> {
let entity = self.map.get(position)?;
self.chunks.get_mut(*entity).ok()
}
}
I do this to avoid conflicts.
How can I make this pattern simpler?
AFAIK it's not possible to use Traits for this, due to type restrictions around Query