//! Barrier stepping: the scene freezes while LLM calls are in flight and //! only advances once every due person's decision has landed. use bevy::prelude::*; use std::collections::{HashMap, HashSet}; use crate::llm::DecisionResult; /// Simulated clock in minutes since day 1, 00:00. Day runs 09:00–17:00. #[derive(Resource)] pub struct SimClock(pub f32); impl SimClock { pub fn day(&self) -> u32 { (self.0 / 1440.0) as u32 + 1 } pub fn minute_of_day(&self) -> f32 { self.0 % 1440.0 } pub fn hhmm(&self) -> String { let m = self.minute_of_day() as u32; format!("{:02}:{:02}", m / 60, m % 60) } } pub const DAY_START: f32 = 9.0 * 60.0; pub const DAY_END: f32 = 17.0 * 60.0; pub const LUNCH_START: f32 = 12.0 * 60.0; pub const LUNCH_END: f32 = 13.0 * 60.0; /// Sim minutes per barrier round. pub const STEP_MINUTES: f32 = 30.0; /// Real seconds the scene animates between compute rounds. pub const STEP_ANIM: f32 = 2.0; /// Deadman: force-complete a round this late (endpoint died mid-round). pub const COMPUTE_TIMEOUT: f32 = 240.0; #[derive(Resource, PartialEq, Clone, Copy, Debug)] pub enum Phase { /// Scene animates: bodies move, bubbles show. Stepping, /// LLM results pending — world frozen until the round completes. Computing, } impl Default for Phase { fn default() -> Self { Phase::Stepping } } #[derive(Resource, Default)] pub struct RoundState { /// People whose decision has not come back this round. pub pending: HashSet, /// Work-log expansions still outstanding (split mode only). pub pending_writes: usize, /// Work decisions waiting on their coder-model content. pub deferred: HashMap, pub results: Vec, pub rounds: u64, /// Real-time when computing started. pub computing_since: f32, /// Real-time until the animation window ends. pub step_until: f32, } impl RoundState { pub fn done(&self) -> bool { self.pending.is_empty() && self.pending_writes == 0 } pub fn start_round(&mut self) { self.pending.clear(); self.deferred.clear(); self.pending_writes = 0; self.results.clear(); } } /// Active company-wide event (meeting / standup). #[derive(Resource, Default)] pub struct CompanyEvents { pub meeting: Option, pub meeting_snapped: bool, } #[derive(Clone)] pub struct Meeting { pub topic: String, pub until: f32, // sim clock minutes }