diff options
Diffstat (limited to 'src/fleet/schedule.rs')
| -rw-r--r-- | src/fleet/schedule.rs | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/fleet/schedule.rs b/src/fleet/schedule.rs new file mode 100644 index 0000000..c0e275b --- /dev/null +++ b/src/fleet/schedule.rs @@ -0,0 +1,190 @@ +use std::collections::{BinaryHeap, HashMap, VecDeque}; +use std::ops::Range; +use std::sync::RwLock; + +use crate::fleet::{Fleet, FleetId, FleetsManager}; +use crate::timeman::Second; +use crate::solar_system::{Kilometers, SolarSystem}; + +pub trait ScheduleCommand +{ + //Remaining time interval for this command. + fn time_range(&self, time: &Range<Second>) -> Range<Second>; + + fn tick( + &self, + star_systems: &[SolarSystem], + fleet: &mut Fleet, + time: &Range<Second>) + -> Result<(), Second>; +} + +pub struct Schedule +{ + commands: Vec<Box<dyn ScheduleCommand>>, + groups: Vec<Range<usize>>, + start_time: Second +} + +pub struct ScheduleManager +{ + schedules: HashMap<FleetId, Schedule> +} + +impl Schedule +{ + pub fn new() + -> Self { + Self { + commands: vec![], + groups: vec![], + start_time: 0 + } + } + + pub fn commands(&self) -> &[Box<dyn ScheduleCommand>] { &self.commands } + + pub fn top(&self) -> Option<&Box<dyn ScheduleCommand>> { self.commands.first() } + pub fn top_mut(&mut self) -> Option<&mut Box<dyn ScheduleCommand>> { self.commands.first_mut() } + + pub fn pop(&mut self) -> Option<Box<dyn ScheduleCommand>> { self.commands.pop() } + + pub fn add_command<T: ScheduleCommand + 'static>( + &mut self, + command: T) + { + self.commands.push(Box::new(command)); + } + + pub(crate) fn tick( + &mut self, + star_systems: &[SolarSystem], + fleet: &mut Fleet, + time: &Range<Second>) + -> Result<(), Second> + { + while let Some(command) = self.top() { + if command.time_range(time).end > time.start { + self.pop(); + continue; + } + + return command.tick(star_systems, fleet, time); + }; + Ok(()) + } +} // impl Schedule + +impl ScheduleManager +{ + pub fn new() -> Self + { + Self { + schedules: HashMap::new() + } + } + + pub fn schedules_mut( + &mut self) + -> std::collections::hash_map::IterMut<'_, FleetId, Schedule> + { + self.schedules.iter_mut() + } + + pub fn schedules( + &self) + -> std::collections::hash_map::Iter<'_, FleetId, Schedule> + { + self.schedules.iter() + } + + pub fn add_command_to_schedule + <T: ScheduleCommand + 'static>( + &mut self, + id: FleetId, + command: T) + { + if let Some(schedule) = self.schedules.get_mut(&id) { + schedule.add_command(command); + } + } + + pub fn schedule_mut( + &mut self, + id: FleetId) + -> Option<&mut Schedule> + { + self.schedules.get_mut(&id) + } + + pub fn schedule( + &self, + id: FleetId) + -> Option<&Schedule> + { + self.schedules.get(&id) + } + + pub fn remove_schedule( + &mut self, + id: FleetId) + { + self.schedules.remove_entry(&id); + } + + fn next_schedule_tick( + &self, + time: &Range<Second>) + -> Option<(FleetId, Second)> { + let mut least_cmd: Option<(FleetId, Second)> = None; + for (id, schedule) in self.schedules.iter() { + let top_cmd = match schedule.top() { + Some(cmd) => cmd.time_range(time).end, + None => { continue; } + }; + + if let Some(least_val) = least_cmd { + if least_val.1 > top_cmd { + least_cmd = Some((*id, top_cmd)); + } + }else{ + least_cmd = Some((*id, top_cmd)); + } + } + least_cmd + } + + pub fn subtick( + &mut self, + fleets_man: &mut FleetsManager, + star_systems: &[SolarSystem], + time: &Range<Second>) + -> Result<(), Second> + { + let mut last_time = time.start; + while let Some((fleet_id, fleet_tick)) = self.next_schedule_tick(time) { + if fleet_tick > time.end { + break; + } + let fleet = match fleets_man.fleet_mut(fleet_id) { + Some(v) => v, + None => { + self.remove_schedule(fleet_id); + continue; + } + }; + + let schedule = self.schedules.get_mut(&fleet_id).unwrap(); + let tick_range = last_time..fleet_tick; + let schedule_tick_interrupt = schedule.tick( + star_systems, fleet, &tick_range); + + if schedule_tick_interrupt.is_err() { + return schedule_tick_interrupt; + } + + last_time = fleet_tick; + }; + Ok(()) + } +} |
