I am still following this ECS tutorial and cannot figure out what is happening in that function
There is a lot of syntax that looks unfamiliar but I will get there with the book hopefully. What I am wondering right now is the logic of moving boxes around:
Here is the whole function (with the author comments):
pub struct InputSystem {}
impl<'a> System<'a> for InputSystem {
type SystemData = (
Write<'a, InputQueue>,
Entities<'a>,
WriteStorage<'a, Position>,
ReadStorage<'a, Player>,
ReadStorage<'a, Movable>,
ReadStorage<'a, Immovable>,
);
fn run(&mut self, data: Self::SystemData) {
let (mut input_queue, entities, mut positions, players, movables, immovables) = data;
let mut to_move = Vec::new();
for (position, _player) in (&positions, &players).join() {
if let Some(key) = input_queue.keys_pressed.pop() {
//get all movables and immovables
let mov: HashMap<(u8, u8), Index> = (&entities, &movables, &positions)
.join()
.map(|t| ((t.2.x, t.2.y), t.0.id()))
.collect::<HashMap<_, _>>();
let immov: HashMap<(u8, u8), Index> = (&entities, &immovables, &positions)
.join()
.map(|t| ((t.2.x, t.2.y), t.0.id()))
.collect::<HashMap<_, _>>();
// now iterate through current position to the end of the map on
// correct axis
let (start, end, is_x) = match key {
KeyCode::Up => (position.y, 0, false),
KeyCode::Down => (position.y, MAP_HEIGHT, false),
KeyCode::Left => (position.x, 0, true),
KeyCode::Right => (position.x, MAP_WIDTH, true),
_ => continue,
};
let range = if start < end {
(start..=end).collect::<Vec<_>>()
} else {
(end..=start).rev().collect::<Vec<_>>()
};
for x_or_y in range {
let pos = if is_x {
(x_or_y, position.y)
} else {
(position.x, x_or_y)
};
//find a movable
//if it exist, we try to move and continue
// if it doesn't we continue to try to find an immovable instead
match mov.get(&pos) {
Some(id) => to_move.push((key, id.clone())),
None => {
//find an immovable
// if it exist we need to stop and not move anything
//if it doesn't exist we stop because we found a gap
match immov.get(&pos) {
Some(id) => to_move.clear(),
None => break,
}
}
}
}
}
}
//now let's move what need to be moved
for (key, id) in to_move {
let position = positions.get_mut(entities.entity(id));
if let Some(position) = position {
match key {
KeyCode::Up => position.y -= 1,
KeyCode::Down => position.y += 1,
KeyCode::Left => position.x -= 1,
KeyCode::Right => position.x += 1,
_ => (),
}
}
}
}
}
- What is meant by "iterating on the correct axis"?
let (start, end, is_x) = match key {
KeyCode::Up => (position.y, 0, false),
KeyCode::Down => (position.y, MAP_HEIGHT, false),
KeyCode::Left => (position.x, 0, true),
KeyCode::Right => (position.x, MAP_WIDTH, true),
_ => continue,
};
- what are we doing with those vectors?
let range = if start < end {
(start..=end).collect::<Vec<_>>()
} else {
(end..=start).rev().collect::<Vec<_>>()
};
- what are we doing with those tuples?
for x_or_y in range {
let pos = if is_x {
(x_or_y, position.y)
} else {
(position.x, x_or_y)
};
- how does she proceeds with movables and immovables here?
match mov.get(&pos) {
Some(id) => to_move.push((key, id.clone())),
None => {
//find an immovable
// if it exist we need to stop and not move anything
//if it doesn't exist we stop because we found a gap
match immov.get(&pos) {
Some(id) => to_move.clear(),
None => break,
}
}
}
I am aware I should probably sleep on this and reread with a fresh head tomorrow morning but I understood a lot from discussing with you, so I would be very grateful if someone could share their insights