add_edges
helper for directional navigation (#17389)
# Objective While `add_looping_edges` is a helpful method for manually defining directional navigation maps, we don't always want to loop around! ## Solution Add a non-looping variant. These commits are cherrypicked from the more complex #17247. ## Testing I've updated the `directional_navigation` example to use these changes, and verified that it works. --------- Co-authored-by: Rob Parrett <robparrett@gmail.com> Co-authored-by: Benjamin Brienen <benjamin.brienen@outlook.com>
This commit is contained in:
parent
5cc3f4727e
commit
72f70745c5
@ -173,7 +173,16 @@ impl DirectionalNavigationMap {
|
||||
self.add_edge(b, a, direction.opposite());
|
||||
}
|
||||
|
||||
/// Add symmetrical edges between all entities in the provided slice, looping back to the first entity at the end.
|
||||
/// Add symmetrical edges between each consecutive pair of entities in the provided slice.
|
||||
///
|
||||
/// Unlike [`add_looping_edges`](Self::add_looping_edges), this method does not loop back to the first entity.
|
||||
pub fn add_edges(&mut self, entities: &[Entity], direction: CompassOctant) {
|
||||
for pair in entities.windows(2) {
|
||||
self.add_symmetrical_edge(pair[0], pair[1], direction);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add symmetrical edges between each consecutive pair of entities in the provided slice, looping back to the first entity at the end.
|
||||
///
|
||||
/// This is useful for creating a circular navigation path between a set of entities, such as a menu.
|
||||
pub fn add_looping_edges(&mut self, entities: &[Entity], direction: CompassOctant) {
|
||||
@ -342,6 +351,25 @@ mod tests {
|
||||
assert_eq!(map.get_neighbor(c, CompassOctant::West), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn edges() {
|
||||
let mut world = World::new();
|
||||
let a = world.spawn_empty().id();
|
||||
let b = world.spawn_empty().id();
|
||||
let c = world.spawn_empty().id();
|
||||
|
||||
let mut map = DirectionalNavigationMap::default();
|
||||
map.add_edges(&[a, b, c], CompassOctant::East);
|
||||
|
||||
assert_eq!(map.get_neighbor(a, CompassOctant::East), Some(b));
|
||||
assert_eq!(map.get_neighbor(b, CompassOctant::East), Some(c));
|
||||
assert_eq!(map.get_neighbor(c, CompassOctant::East), None);
|
||||
|
||||
assert_eq!(map.get_neighbor(a, CompassOctant::West), None);
|
||||
assert_eq!(map.get_neighbor(b, CompassOctant::West), Some(a));
|
||||
assert_eq!(map.get_neighbor(c, CompassOctant::West), Some(b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn looping_edges() {
|
||||
let mut world = World::new();
|
||||
|
@ -214,16 +214,12 @@ fn setup_ui(
|
||||
// but don't loop around when the edge is reached.
|
||||
// While looping is a very reasonable choice, we're not doing it here to demonstrate the different options.
|
||||
for col in 0..N_COLS {
|
||||
// Don't iterate over the last row, as no lower row exists to connect to
|
||||
for row in 0..N_ROWS - 1 {
|
||||
let upper_entity = button_entities.get(&(row, col)).unwrap();
|
||||
let lower_entity = button_entities.get(&(row + 1, col)).unwrap();
|
||||
directional_nav_map.add_symmetrical_edge(
|
||||
*upper_entity,
|
||||
*lower_entity,
|
||||
CompassOctant::South,
|
||||
);
|
||||
}
|
||||
let entities_in_column: Vec<Entity> = (0..N_ROWS)
|
||||
.map(|row| button_entities.get(&(row, col)).unwrap())
|
||||
.copied()
|
||||
.collect();
|
||||
|
||||
directional_nav_map.add_edges(&entities_in_column, CompassOctant::South);
|
||||
}
|
||||
|
||||
// When changing scenes, remember to set an initial focus!
|
||||
|
Loading…
Reference in New Issue
Block a user