use crate::prelude::*;
use bevy::prelude::*;
#[derive(Message)]
pub struct EventUpdateCostfieldsCell {
cell: FieldCell,
sector: SectorID,
cell_value: u8,
}
impl EventUpdateCostfieldsCell {
#[cfg(not(tarpaulin_include))]
pub fn new(cell: FieldCell, sector: SectorID, cell_value: u8) -> Self {
EventUpdateCostfieldsCell {
cell,
sector,
cell_value,
}
}
#[cfg(not(tarpaulin_include))]
pub fn get_cell(&self) -> FieldCell {
self.cell
}
#[cfg(not(tarpaulin_include))]
pub fn get_sector(&self) -> SectorID {
self.sector
}
#[cfg(not(tarpaulin_include))]
pub fn get_cost_value(&self) -> u8 {
self.cell_value
}
}
#[cfg(not(tarpaulin_include))]
pub fn process_costfields_updates(
mut events: MessageReader<EventUpdateCostfieldsCell>,
mut query: Query<(
&mut PortalGraph,
&mut SectorPortals,
&mut SectorCostFields,
&MapDimensions,
)>,
mut event_cache_clean: MessageWriter<EventCleanCaches>,
) {
let mut coalesced_sectors = Vec::new();
for event in events.read() {
let field_cell = event.get_cell();
let sector_id = event.get_sector();
let cost = event.get_cost_value();
for (_portal_graph, mut sector_portals, mut sector_cost_fields, dimensions) in
query.iter_mut()
{
sector_cost_fields.set_field_cell_value(sector_id, cost, field_cell, dimensions);
sector_portals.update_portals(sector_id, sector_cost_fields.as_ref(), dimensions);
}
if !coalesced_sectors.contains(§or_id) {
coalesced_sectors.push(sector_id);
}
}
for sector_id in coalesced_sectors.iter() {
debug!("Rebuilding fields of {:?}", sector_id.get());
for (mut portal_graph, sector_portals, sector_cost_fields, dimensions) in query.iter_mut() {
portal_graph.update_graph(
*sector_id,
sector_portals.as_ref(),
sector_cost_fields.as_ref(),
dimensions,
);
}
event_cache_clean.write(EventCleanCaches(*sector_id));
}
}
#[derive(Message)]
pub struct EventCleanCaches(SectorID);
#[cfg(not(tarpaulin_include))]
pub fn clean_cache(
mut events: MessageReader<EventCleanCaches>,
mut q_flow: Query<&mut FlowFieldCache>,
mut q_route: Query<&mut RouteCache>,
mut event_path_request: MessageWriter<EventPathRequest>,
) {
let mut sectors = Vec::new();
for event in events.read() {
sectors.push(event.0);
}
if !sectors.is_empty() {
for mut flow_cache in q_flow.iter_mut() {
let mut to_purge = Vec::new();
let map = flow_cache.get_queue_mut();
for id in sectors.iter() {
'next: for (metadata, builder) in map.iter() {
let path = builder.get_route().get();
for (route_sector, _) in path.iter() {
if *id == *route_sector {
to_purge.push(*metadata);
continue 'next;
}
}
}
}
for purge_me in to_purge.iter() {
flow_cache.remove_queue_item(*purge_me);
}
let mut to_purge = Vec::new();
let map = flow_cache.get_mut();
for id in sectors.iter() {
for metadata in map.keys() {
if *id == metadata.get_sector_id() {
to_purge.push(*metadata);
}
}
}
for purge_me in to_purge.iter() {
flow_cache.remove_field(*purge_me);
}
}
for mut route_cache in q_route.iter_mut() {
let mut to_purge = Vec::new();
let map = route_cache.get_queue_mut();
for id in sectors.iter() {
'next: for (metadata, route) in map.iter() {
if *id == metadata.get_source_sector() {
to_purge.push(*metadata);
continue 'next;
}
if *id == metadata.get_target_sector() {
to_purge.push(*metadata);
continue 'next;
}
for (route_sector, _) in route.get().iter() {
if *id == *route_sector {
to_purge.push(*metadata);
continue 'next;
}
}
}
}
for purge_me in to_purge.iter() {
route_cache.remove_queued_route(*purge_me);
}
let mut to_purge = Vec::new();
let map = route_cache.get_mut();
for id in sectors.iter() {
'next: for (metadata, route) in map.iter() {
if *id == metadata.get_source_sector() {
to_purge.push(*metadata);
continue 'next;
}
if *id == metadata.get_target_sector() {
to_purge.push(*metadata);
continue 'next;
}
for (route_sector, _) in route.get().iter() {
if *id == *route_sector {
to_purge.push(*metadata);
continue 'next;
}
}
}
}
for purge_me in to_purge.iter() {
route_cache.remove_route(*purge_me);
}
for metadata in to_purge.iter() {
event_path_request.write(EventPathRequest::new(
metadata.get_source_sector(),
metadata.get_source_field_cell(),
metadata.get_target_sector(),
metadata.get_target_goal(),
));
}
}
}
}