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());
|
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.
|
/// 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) {
|
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);
|
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]
|
#[test]
|
||||||
fn looping_edges() {
|
fn looping_edges() {
|
||||||
let mut world = World::new();
|
let mut world = World::new();
|
||||||
|
|||||||
@ -214,16 +214,12 @@ fn setup_ui(
|
|||||||
// but don't loop around when the edge is reached.
|
// 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.
|
// While looping is a very reasonable choice, we're not doing it here to demonstrate the different options.
|
||||||
for col in 0..N_COLS {
|
for col in 0..N_COLS {
|
||||||
// Don't iterate over the last row, as no lower row exists to connect to
|
let entities_in_column: Vec<Entity> = (0..N_ROWS)
|
||||||
for row in 0..N_ROWS - 1 {
|
.map(|row| button_entities.get(&(row, col)).unwrap())
|
||||||
let upper_entity = button_entities.get(&(row, col)).unwrap();
|
.copied()
|
||||||
let lower_entity = button_entities.get(&(row + 1, col)).unwrap();
|
.collect();
|
||||||
directional_nav_map.add_symmetrical_edge(
|
|
||||||
*upper_entity,
|
directional_nav_map.add_edges(&entities_in_column, CompassOctant::South);
|
||||||
*lower_entity,
|
|
||||||
CompassOctant::South,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When changing scenes, remember to set an initial focus!
|
// When changing scenes, remember to set an initial focus!
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user