From cb73cb7cccb45b3381c3b0e600d151fc0c8477aa Mon Sep 17 00:00:00 2001 From: chexit Date: Wed, 4 Nov 2026 15:54:53 +0300 Subject: [PATCH] Move world cache report to presentation adapter Co-Authored-By: Codex --- airdef-mod/examples/sim_run/harness.rs | 4 ++- airdef-mod/src/lib.rs | 3 ++- airdef-mod/src/sim/world.rs | 21 ---------------- airdef-mod/src/world_view.rs | 34 ++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 airdef-mod/src/world_view.rs diff --git a/airdef-mod/examples/sim_run/harness.rs b/airdef-mod/examples/sim_run/harness.rs index e6c4c01..050c685 100644 --- a/airdef-mod/examples/sim_run/harness.rs +++ b/airdef-mod/examples/sim_run/harness.rs @@ -5,6 +5,8 @@ //! Native timings say nothing about the WASM build or the GPU; use them to compare runs of the //! same machine. #![allow(dead_code)] +#[path = "../../src/world_view.rs"] +mod world_view; use airdef::sim::{Aim, Approach, DroneKind, Ground, Out, RaidOrder, Sam, SamKind, Sim}; use glam::DVec3; use std::collections::HashMap; @@ -229,7 +231,7 @@ pub fn run(sc: &Scenario) -> Report { r.hits = sim.hits; r.fired = sim.sams.iter().map(|s| s.fired).sum(); r.raids_ordered = ordered.iter().filter(|o| **o).count(); - r.world = ground.world.text(); + r.world = world_view::text(&ground.world); r.crashes = sim.crashes; r.failures = sim.tally.text(); r.raids_ended = ended.iter().filter(|o| **o).count(); diff --git a/airdef-mod/src/lib.rs b/airdef-mod/src/lib.rs index 50ad017..b3ae2d2 100644 --- a/airdef-mod/src/lib.rs +++ b/airdef-mod/src/lib.rs @@ -30,6 +30,7 @@ mod smoke; pub use airdef_core::sim; mod scenario; mod wave; +mod world_view; use sim::{Class, DroneKind, Ground, Out, Sam, SamKind, Sim}; const ITEMS: [&str; sim::catalog::INVENTORY_COUNT] = sim::catalog::INVENTORY; @@ -2546,7 +2547,7 @@ impl Mod for AirDef { self.sim.strikes.stunned, self.sim.strikes.missed, self.sim.strikes.shot_down, - self.ground.world.text() + world_view::text(&self.ground.world) )), _ => return Err(help()), }; diff --git a/airdef-mod/src/sim/world.rs b/airdef-mod/src/sim/world.rs index 8a5d039..5f6add2 100644 --- a/airdef-mod/src/sim/world.rs +++ b/airdef-mod/src/sim/world.rs @@ -238,27 +238,6 @@ impl WorldCache { pub fn is_empty(&self) -> bool { self.secs.is_empty() } - /// One line for the report. - pub fn text(&self) -> String { - let s = &self.stats; - format!( - "мир: {} секций ({} КБ), запросов {}, неизвестно {}, лучей {} (ударов {}, неизв. {}), клеток {}; взрывы в блоках: {} (подтверждено {}, без перемен {}, нет чанка {}), чужих ответов {}", - self.len(), - self.bytes() / 1024, - s.sections_asked, - s.sections_unknown, - s.sweeps, - s.hits, - s.unknown_sweeps, - s.cells, - s.blasts_asked, - s.blasts_confirmed, - s.blasts_unchanged, - s.blasts_unloaded, - s.late_dropped - ) - } - /// The game's note of changes: another world voids everything; changed /// sections (or too many to say) are read again when next used. pub fn changed(&mut self, epoch: u32, overflow: bool, sections: &[Sec]) { diff --git a/airdef-mod/src/world_view.rs b/airdef-mod/src/world_view.rs new file mode 100644 index 0000000..070347c --- /dev/null +++ b/airdef-mod/src/world_view.rs @@ -0,0 +1,34 @@ +//! Player-facing world-cache report, also used by the headless scenario driver. +use airdef_core::sim::world::WorldCache; + +pub fn text(world: &WorldCache) -> String { + let s = &world.stats; + format!( + "мир: {} секций ({} КБ), запросов {}, неизвестно {}, лучей {} (ударов {}, неизв. {}), клеток {}; взрывы в блоках: {} (подтверждено {}, без перемен {}, нет чанка {}), чужих ответов {}", + world.len(), world.bytes() / 1024, s.sections_asked, s.sections_unknown, + s.sweeps, s.hits, s.unknown_sweeps, s.cells, s.blasts_asked, + s.blasts_confirmed, s.blasts_unchanged, s.blasts_unloaded, s.late_dropped + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn reports_cache_counts_in_existing_format() { + let mut world = WorldCache::default(); + world.stats.sections_asked = 1; + world.stats.sections_unknown = 2; + world.stats.sweeps = 3; + world.stats.hits = 4; + world.stats.unknown_sweeps = 5; + world.stats.cells = 6; + world.stats.blasts_asked = 7; + world.stats.blasts_confirmed = 8; + world.stats.blasts_unchanged = 9; + world.stats.blasts_unloaded = 10; + world.stats.late_dropped = 11; + assert_eq!(text(&world), "мир: 0 секций (0 КБ), запросов 1, неизвестно 2, лучей 3 (ударов 4, неизв. 5), клеток 6; взрывы в блоках: 7 (подтверждено 8, без перемен 9, нет чанка 10), чужих ответов 11"); + } +}