mirror of
https://github.com/Xevion/smart-rgb.git
synced 2025-12-08 20:08:27 -06:00
Update source files
This commit is contained in:
206
crates/borders-core/tests/common/mod.rs
Normal file
206
crates/borders-core/tests/common/mod.rs
Normal file
@@ -0,0 +1,206 @@
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
/// Shared test utilities and helpers
|
||||
///
|
||||
/// This module provides infrastructure for testing the Bevy ECS-based game logic:
|
||||
/// - `builders`: Fluent API for constructing test worlds and maps
|
||||
/// - `assertions`: Fluent assertion API for ECS state verification
|
||||
/// - `fixtures`: Pre-built test scenarios for integration tests
|
||||
///
|
||||
/// # Usage Example
|
||||
/// ```
|
||||
/// use common::builders::TestWorld;
|
||||
///
|
||||
/// let mut world = TestWorld::new()
|
||||
/// .with_player(NationId::ZERO, 100.0)
|
||||
/// .with_map_size(50, 50)
|
||||
/// .build();
|
||||
///
|
||||
/// world.conquer_tile(U16Vec2::new(5, 5), NationId::ZERO);
|
||||
/// world.assert().player_owns(U16Vec2::new(5, 5), NationId::ZERO);
|
||||
/// ```
|
||||
use borders_core::prelude::*;
|
||||
use extension_traits::extension;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
mod assertions;
|
||||
mod builders;
|
||||
mod fixtures;
|
||||
|
||||
// Re-export commonly used items
|
||||
pub use assertions::*;
|
||||
pub use builders::*;
|
||||
pub use fixtures::*;
|
||||
|
||||
/// Extension trait providing convenient action methods for World in tests
|
||||
#[extension(pub trait WorldTestExt)]
|
||||
impl World {
|
||||
/// Conquer a tile for a player
|
||||
fn conquer_tile(&mut self, tile: U16Vec2, player: NationId) {
|
||||
self.resource_mut::<TerritoryManager>().conquer(tile, player);
|
||||
}
|
||||
|
||||
/// Conquer multiple tiles for a player
|
||||
fn conquer_tiles(&mut self, tiles: &[U16Vec2], player: NationId) {
|
||||
let mut territory_manager = self.resource_mut::<TerritoryManager>();
|
||||
for &tile in tiles {
|
||||
territory_manager.conquer(tile, player);
|
||||
}
|
||||
}
|
||||
|
||||
/// Conquer a square region of tiles centered at a position
|
||||
///
|
||||
/// Conquers all tiles within `radius` steps of `center` (using taxicab distance).
|
||||
/// For radius=1, conquers a 3x3 square. For radius=2, conquers a 5x5 square, etc.
|
||||
fn conquer_region(&mut self, center: U16Vec2, radius: i32, player: NationId) {
|
||||
let mut territory_manager = self.resource_mut::<TerritoryManager>();
|
||||
for dy in -radius..=radius {
|
||||
for dx in -radius..=radius {
|
||||
let tile = center.as_ivec2() + glam::IVec2::new(dx, dy);
|
||||
if tile.x >= 0 && tile.y >= 0 {
|
||||
let tile = tile.as_u16vec2();
|
||||
if tile.x < territory_manager.width() && tile.y < territory_manager.height() {
|
||||
territory_manager.conquer(tile, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Conquer all 4-directional neighbors of a tile
|
||||
fn conquer_neighbors(&mut self, center: U16Vec2, player: NationId) {
|
||||
let map_size = {
|
||||
let mgr = self.resource::<TerritoryManager>();
|
||||
U16Vec2::new(mgr.width(), mgr.height())
|
||||
};
|
||||
|
||||
let mut territory_manager = self.resource_mut::<TerritoryManager>();
|
||||
for neighbor in neighbors(center, map_size) {
|
||||
territory_manager.conquer(neighbor, player);
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear ownership of a tile, returning the previous owner
|
||||
fn clear_tile(&mut self, tile: U16Vec2) -> Option<NationId> {
|
||||
self.resource_mut::<TerritoryManager>().clear(tile)
|
||||
}
|
||||
|
||||
fn est(&mut self) {}
|
||||
|
||||
/// Clear all territory changes from the change buffer
|
||||
fn clear_territory_changes(&mut self) {
|
||||
self.resource_mut::<TerritoryManager>().clear_changes();
|
||||
}
|
||||
|
||||
/// Deactivate the spawn phase
|
||||
fn deactivate_spawn_phase(&mut self) {
|
||||
self.resource_mut::<SpawnPhase>().active = false;
|
||||
}
|
||||
|
||||
/// Activate the spawn phase
|
||||
fn activate_spawn_phase(&mut self) {
|
||||
self.resource_mut::<SpawnPhase>().active = true;
|
||||
}
|
||||
|
||||
/// Get the number of territory changes in the ChangeBuffer
|
||||
fn get_change_count(&self) -> usize {
|
||||
self.resource::<TerritoryManager>().iter_changes().count()
|
||||
}
|
||||
|
||||
/// Get the entity associated with a player
|
||||
fn get_player_entity(&self, player_id: NationId) -> Entity {
|
||||
let entity_map = self.resource::<PlayerEntityMap>();
|
||||
*entity_map.0.get(&player_id).unwrap_or_else(|| panic!("Player entity not found for player {}", player_id.get()))
|
||||
}
|
||||
|
||||
/// Run the border update logic (inline implementation for testing)
|
||||
fn update_borders(&mut self) {
|
||||
// Check if there are changes
|
||||
{
|
||||
let territory_manager = self.resource::<TerritoryManager>();
|
||||
if !territory_manager.has_changes() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect all data we need from TerritoryManager before mutating
|
||||
let (changed_tiles, map_size, tiles_by_owner) = {
|
||||
let territory_manager = self.resource::<TerritoryManager>();
|
||||
|
||||
let changed_tiles: HashSet<U16Vec2> = territory_manager.iter_changes().collect();
|
||||
let map_size = U16Vec2::new(territory_manager.width(), territory_manager.height());
|
||||
|
||||
let mut affected_tiles = HashSet::with_capacity(changed_tiles.len() * 5);
|
||||
for &tile in &changed_tiles {
|
||||
affected_tiles.insert(tile);
|
||||
affected_tiles.extend(neighbors(tile, map_size));
|
||||
}
|
||||
|
||||
// Group tiles by owner
|
||||
let mut tiles_by_owner: HashMap<NationId, HashSet<U16Vec2>> = HashMap::new();
|
||||
for &tile in &affected_tiles {
|
||||
if let Some(nation_id) = territory_manager.get_nation_id(tile) {
|
||||
tiles_by_owner.entry(nation_id).or_default().insert(tile);
|
||||
}
|
||||
}
|
||||
|
||||
(changed_tiles, map_size, tiles_by_owner)
|
||||
};
|
||||
|
||||
// Build ownership snapshot for border checking
|
||||
let ownership_snapshot: HashMap<U16Vec2, Option<NationId>> = {
|
||||
let territory_manager = self.resource::<TerritoryManager>();
|
||||
let mut snapshot = HashMap::new();
|
||||
for &tile in changed_tiles.iter() {
|
||||
for neighbor in neighbors(tile, map_size) {
|
||||
snapshot.entry(neighbor).or_insert_with(|| territory_manager.get_nation_id(neighbor));
|
||||
}
|
||||
snapshot.insert(tile, territory_manager.get_nation_id(tile));
|
||||
}
|
||||
snapshot
|
||||
};
|
||||
|
||||
// Update each player's borders
|
||||
let mut players_query = self.query::<(&NationId, &mut BorderTiles)>();
|
||||
for (nation_id, mut component_borders) in players_query.iter_mut(self) {
|
||||
let empty_set = HashSet::new();
|
||||
let player_tiles = tiles_by_owner.get(nation_id).unwrap_or(&empty_set);
|
||||
|
||||
// Process tiles owned by this player
|
||||
for &tile in player_tiles {
|
||||
let is_border = neighbors(tile, map_size).any(|neighbor| ownership_snapshot.get(&neighbor).and_then(|&owner| owner) != Some(*nation_id));
|
||||
|
||||
if is_border {
|
||||
component_borders.0.insert(tile);
|
||||
} else {
|
||||
component_borders.0.remove(&tile);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove tiles that changed ownership away from this player
|
||||
for &tile in changed_tiles.iter() {
|
||||
if ownership_snapshot.get(&tile).and_then(|&owner| owner) != Some(*nation_id) {
|
||||
component_borders.0.remove(&tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear territory changes
|
||||
fn clear_borders_changes(&mut self) {
|
||||
self.resource_mut::<TerritoryManager>().clear_changes();
|
||||
}
|
||||
|
||||
/// Get border tiles for a player from ECS component
|
||||
fn get_player_borders(&self, player_id: NationId) -> HashSet<U16Vec2> {
|
||||
let entity = self.get_player_entity(player_id);
|
||||
self.get::<BorderTiles>(entity).expect("Player entity missing BorderTiles component").0.clone()
|
||||
}
|
||||
|
||||
/// Get border tiles for a player from BorderCache
|
||||
fn get_border_cache(&self, player_id: NationId) -> Option<HashSet<U16Vec2>> {
|
||||
self.resource::<BorderCache>().get(player_id).cloned()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user