#![feature( generic_associated_types, never_type, try_blocks, generator_trait, generators, trait_alias, trait_upcasting, control_flow_enum, let_chains )] pub mod ai; pub mod data; pub mod event; pub mod gen; pub mod rule; pub use self::{ data::Data, event::{Event, EventCtx, OnTick}, rule::{Rule, RuleError}, }; use anymap2::SendSyncAnyMap; use atomic_refcell::AtomicRefCell; use common::resources::{Time, TimeOfDay}; use std::{ any::type_name, ops::{Deref, DerefMut}, }; use tracing::{error, info}; use world::{IndexRef, World}; pub struct RtState { resources: SendSyncAnyMap, rules: SendSyncAnyMap, event_handlers: SendSyncAnyMap, } type RuleState = AtomicRefCell; type EventHandlersOf = Vec>; impl RtState { pub fn new(data: Data) -> Self { let mut this = Self { resources: SendSyncAnyMap::new(), rules: SendSyncAnyMap::new(), event_handlers: SendSyncAnyMap::new(), } .with_resource(data); this.start_default_rules(); this } pub fn with_resource(mut self, r: R) -> Self { self.resources.insert(AtomicRefCell::new(r)); self } fn start_default_rules(&mut self) { info!("Starting default rtsim rules..."); self.start_rule::(); self.start_rule::(); self.start_rule::(); } pub fn start_rule(&mut self) { info!("Initiating '{}' rule...", type_name::()); match R::start(self) { Ok(rule) => { self.rules.insert::>(AtomicRefCell::new(rule)); }, Err(e) => error!("Error when initiating '{}' rule: {}", type_name::(), e), } } fn rule_mut(&self) -> impl DerefMut + '_ { self.rules .get::>() .unwrap_or_else(|| { panic!( "Tried to access rule '{}' but it does not exist", type_name::() ) }) .borrow_mut() } pub fn bind( &mut self, mut f: impl FnMut(EventCtx) + Send + Sync + 'static, ) { let f = AtomicRefCell::new(f); self.event_handlers .entry::>() .or_default() .push(Box::new(move |state, world, index, event| { (f.borrow_mut())(EventCtx { state, rule: &mut state.rule_mut(), event, world, index, }) })); } pub fn data(&self) -> impl Deref + '_ { self.resource() } pub fn data_mut(&self) -> impl DerefMut + '_ { self.resource_mut() } pub fn resource(&self) -> impl Deref + '_ { self.resources .get::>() .unwrap_or_else(|| { panic!( "Tried to access resource '{}' but it does not exist", type_name::() ) }) .borrow() } pub fn resource_mut(&self) -> impl DerefMut + '_ { self.resources .get::>() .unwrap_or_else(|| { panic!( "Tried to access resource '{}' but it does not exist", type_name::() ) }) .borrow_mut() } pub fn emit(&mut self, e: E, world: &World, index: IndexRef) { self.event_handlers .get::>() .map(|handlers| handlers.iter().for_each(|f| f(self, world, index, &e))); } pub fn tick( &mut self, world: &World, index: IndexRef, time_of_day: TimeOfDay, time: Time, dt: f32, ) { self.data_mut().time_of_day = time_of_day; let event = OnTick { time_of_day, time, dt, }; self.emit(event, world, index); } }