use crate::{client::Client, helper::from_timestamp}; use chrono::NaiveDateTime; use karlcommon::{ClientboundPacket, ServerboundPacket, Task}; use log::warn; use std::{ collections::{HashMap, VecDeque}, ops::Range, }; pub struct Globals { pub client: Client, pub tasks: HashMap, pub awaiting_instance_requests: VecDeque<(u64, Range)>, pub instance_cache: HashMap<(u64, Range), Option>>>>, } impl Globals { pub fn new(client: Client) -> Self { Globals { client, tasks: Default::default(), instance_cache: Default::default(), awaiting_instance_requests: Default::default(), } } pub fn update_network(&mut self) { while let Ok(p) = self.client.receiver.try_recv() { match p { ClientboundPacket::TaskList(t) => { self.tasks = HashMap::from_iter(t.into_iter().map(|e| (e.id, e))); } ClientboundPacket::Sync => { self.client.busy = false; } ClientboundPacket::InstanceList(is) => { if let Some(i) = self.awaiting_instance_requests.pop_front() { self.instance_cache.insert( i, Some( is.iter() .map(|r| r.start.map(from_timestamp)..r.end.map(from_timestamp)) .collect(), ), ); } else { warn!("got unknown instance list packet") } } ClientboundPacket::InvalidateState => { self.instance_cache.clear(); self.tasks.clear(); self.client.send_sync(ServerboundPacket::ListTasks); } _ => {} } } } pub fn get_instances_range( &mut self, task: u64, start: NaiveDateTime, end: NaiveDateTime, ) -> &Option>>> { // looks silly but the borrow checker likes it more let has = self.instance_cache.contains_key(&(task, start..end)); if has { if let Some(c) = self.instance_cache.get(&(task, start..end)) { return c; } return &None; } self.awaiting_instance_requests .push_back((task, start..end)); self.instance_cache.insert((task, start..end), None); self.client.send_sync(ServerboundPacket::ListInstances { task, range: Some(start.timestamp())..Some(end.timestamp()), limit: 4069, }); &None } }