Refactor indexing into individual setter functions.

This commit is contained in:
Nolan Darilek 2021-05-24 10:19:01 -05:00
parent f78e23c332
commit 41bfe08a03
3 changed files with 114 additions and 66 deletions

View File

@ -314,6 +314,17 @@ fn area_description(
} }
} }
fn remove_coordinates(removed: RemovedComponents<Coordinates>, mut map: Query<&mut Map>) {
for removed in removed.iter() {
println!("Removing {:?} from map", removed);
for mut map in map.iter_mut() {
for entities in map.entities.iter_mut() {
entities.retain(|e| *e != removed);
}
}
}
}
#[derive(Default, Deref, DerefMut)] #[derive(Default, Deref, DerefMut)]
struct PreviousIndex(HashMap<Entity, usize>); struct PreviousIndex(HashMap<Entity, usize>);
@ -369,6 +380,12 @@ impl Plugin for MapPlugin {
.label(SPAWN_PORTALS) .label(SPAWN_PORTALS)
.before(UPDATE_ENTITY_INDEX_LABEL), .before(UPDATE_ENTITY_INDEX_LABEL),
) )
.add_system_to_stage(
CoreStage::PostUpdate,
remove_coordinates
.system()
.before(UPDATE_ENTITY_INDEX_LABEL),
)
.add_system_to_stage( .add_system_to_stage(
CoreStage::PostUpdate, CoreStage::PostUpdate,
entity_indexing.system().label(UPDATE_ENTITY_INDEX_LABEL), entity_indexing.system().label(UPDATE_ENTITY_INDEX_LABEL),

View File

@ -215,6 +215,24 @@ fn movement(
} }
} }
pub(crate) fn set_motion_blocked(
map: &Map,
index: usize,
motion_blockers: &Query<&BlocksMotion>,
motion_blocked: &mut MotionBlocked,
) {
let mut new_motion_blocked = map.base.tiles[index].blocks_motion();
if !new_motion_blocked {
for e in &map.entities[index] {
if motion_blockers.get(*e).is_ok() {
new_motion_blocked = true;
break;
}
}
}
motion_blocked[index] = new_motion_blocked;
}
pub const UPDATE_COLLISION_INDEX_LABEL: &str = "UPDATE_COLLISION_INDEX"; pub const UPDATE_COLLISION_INDEX_LABEL: &str = "UPDATE_COLLISION_INDEX";
#[derive(Default, Deref, DerefMut)] #[derive(Default, Deref, DerefMut)]
@ -236,17 +254,7 @@ fn blocks_motion_indexing(
if *prev_idx == idx { if *prev_idx == idx {
continue; continue;
} }
let tile = map.base.tiles[*prev_idx]; set_motion_blocked(map, *prev_idx, &motion_blockers, &mut motion_blocked);
let mut new_motion_blocked = tile.blocks_motion();
if !new_motion_blocked {
for e in &map.entities[*prev_idx] {
if motion_blockers.get(*e).is_ok() {
new_motion_blocked = true;
break;
}
}
}
motion_blocked[*prev_idx] = new_motion_blocked;
} }
motion_blocked[idx] = true; motion_blocked[idx] = true;
prev_index.insert(entity, idx); prev_index.insert(entity, idx);
@ -262,22 +270,35 @@ fn remove_blocks_motion(
blocks_motion: Query<&BlocksMotion>, blocks_motion: Query<&BlocksMotion>,
) { ) {
for entity in removed.iter() { for entity in removed.iter() {
if let Ok(coordinates) = coordinates.get_component::<Coordinates>(entity) { for (map, mut motion_blocked) in map.iter_mut() {
if let Some(prev) = prev_index.get(&entity) {
set_motion_blocked(&map, *prev, &blocks_motion, &mut motion_blocked)
}
prev_index.remove(&entity); prev_index.remove(&entity);
for (map, mut motion_blocked) in map.iter_mut() { if let Ok(coordinates) = coordinates.get(entity) {
let idx = (**coordinates).to_index(map.width()); let idx = coordinates.to_index(map.width());
let tile = map.base.tiles[idx]; set_motion_blocked(&map, idx, &blocks_motion, &mut motion_blocked)
let mut new_motion_blocked = tile.blocks_motion();
for e in &map.entities[idx] {
new_motion_blocked = new_motion_blocked
|| blocks_motion.get_component::<BlocksMotion>(*e).is_ok();
}
motion_blocked[idx] = new_motion_blocked;
} }
} }
} }
} }
pub(crate) fn set_monitors_collisions(
map: &Map,
index: usize,
collision_monitors: &Query<&MonitorsCollisions>,
collisions_monitored: &mut CollisionsMonitored,
) {
let mut new_collisions_monitored = false;
for e in &map.entities[index] {
if collision_monitors.get(*e).is_ok() {
new_collisions_monitored = true;
break;
}
}
collisions_monitored[index] = new_collisions_monitored;
}
#[derive(Default, Deref, DerefMut)] #[derive(Default, Deref, DerefMut)]
struct PreviousMonitorsCollisionsIndex(HashMap<Entity, usize>); struct PreviousMonitorsCollisionsIndex(HashMap<Entity, usize>);
@ -297,14 +318,12 @@ fn monitors_collisions_indexing(
if *prev_idx == idx { if *prev_idx == idx {
continue; continue;
} }
let mut new_collisions_monitored = false; set_monitors_collisions(
for e in &map.entities[*prev_idx] { &map,
if collision_monitors.get(*e).is_ok() { *prev_idx,
new_collisions_monitored = true; &collision_monitors,
break; &mut collisions_monitored,
} );
}
collisions_monitored[*prev_idx] = new_collisions_monitored;
} }
collisions_monitored[idx] = true; collisions_monitored[idx] = true;
prev_index.insert(entity, idx); prev_index.insert(entity, idx);
@ -320,18 +339,19 @@ fn remove_monitors_collisions(
monitors_collisions: Query<&MonitorsCollisions>, monitors_collisions: Query<&MonitorsCollisions>,
) { ) {
for entity in removed.iter() { for entity in removed.iter() {
if let Ok(coordinates) = coordinates.get_component::<Coordinates>(entity) { for (map, mut collisions_monitored) in map.iter_mut() {
prev_index.remove(&entity); if let Ok(coordinates) = coordinates.get_component::<Coordinates>(entity) {
for (map, mut collisions_monitored) in map.iter_mut() { if let Some(prev) = prev_index.get(&entity) {
let idx = (**coordinates).to_index(map.width()); set_monitors_collisions(
let mut new_collisions_monitored = false; &map,
for e in &map.entities[idx] { *prev,
new_collisions_monitored = new_collisions_monitored &monitors_collisions,
|| monitors_collisions &mut collisions_monitored,
.get_component::<MonitorsCollisions>(*e) );
.is_ok();
} }
collisions_monitored[idx] = new_collisions_monitored; prev_index.remove(&entity);
let idx = coordinates.to_index(map.width());
set_monitors_collisions(&map, idx, &monitors_collisions, &mut collisions_monitored);
} }
} }
} }

View File

@ -38,7 +38,6 @@ impl Default for Viewshed {
} }
} }
#[allow(dead_code)]
impl Viewshed { impl Viewshed {
pub fn is_visible(&self, point: &dyn PointLike) -> bool { pub fn is_visible(&self, point: &dyn PointLike) -> bool {
self.visible.contains(&point.into()) self.visible.contains(&point.into())
@ -82,6 +81,24 @@ fn add_visibility_indices(
} }
} }
pub(crate) fn set_visibility_blocked(
map: &Map,
index: usize,
visibility_blockers: &Query<&BlocksVisibility>,
visibility_blocked: &mut VisibilityBlocked,
) {
let mut new_visibility_blocked = map.base.tiles[index].blocks_visibility();
if !new_visibility_blocked {
for e in &map.entities[index] {
if visibility_blockers.get(*e).is_ok() {
new_visibility_blocked = true;
break;
}
}
}
visibility_blocked[index] = new_visibility_blocked;
}
#[derive(Default, Deref, DerefMut)] #[derive(Default, Deref, DerefMut)]
struct PreviousIndex(HashMap<Entity, usize>); struct PreviousIndex(HashMap<Entity, usize>);
@ -104,17 +121,12 @@ fn map_visibility_indexing(
if *prev_idx == idx { if *prev_idx == idx {
continue; continue;
} }
let tile = map.base.tiles[*prev_idx]; set_visibility_blocked(
let mut new_visibility_blocked = tile.blocks_visibility(); &map,
if !new_visibility_blocked { *prev_idx,
for e in &map.entities[*prev_idx] { &visibility_blockers,
if visibility_blockers.get(*e).is_ok() { &mut visibility_blocked,
new_visibility_blocked = true; );
break;
}
}
}
visibility_blocked[*prev_idx] = new_visibility_blocked;
} }
visibility_blocked[idx] = true; visibility_blocked[idx] = true;
prev_index.insert(entity, idx); prev_index.insert(entity, idx);
@ -130,21 +142,20 @@ fn remove_blocks_visibility(
blocks_visibility: Query<&BlocksVisibility>, blocks_visibility: Query<&BlocksVisibility>,
) { ) {
for entity in removed.iter() { for entity in removed.iter() {
if let Ok(coordinates) = coordinates.get_component::<Coordinates>(entity) { for (map, mut visibility_blocked) in map.iter_mut() {
prev_index.remove(&entity); if let Ok(coordinates) = coordinates.get_component::<Coordinates>(entity) {
for (map, mut visibility_blocked) in map.iter_mut() { if let Some(prev) = prev_index.get(&entity) {
let idx = coordinates.to_index(map.width()); set_visibility_blocked(
let tile = map.base.tiles[idx]; &map,
let mut new_visibility_blocked = tile.blocks_visibility(); *prev,
if !new_visibility_blocked { &blocks_visibility,
for e in &map.entities[idx] { &mut visibility_blocked,
if blocks_visibility.get(*e).is_ok() { );
new_visibility_blocked = true;
break;
}
}
} }
visibility_blocked[idx] = new_visibility_blocked; prev_index.remove(&entity);
let idx = coordinates.to_index(map.width());
set_visibility_blocked(&map, idx, &blocks_visibility, &mut visibility_blocked);
prev_index.insert(entity, idx);
} }
} }
} }