use crate::misc::ItemCollection;
use super::Blueprint;
#[derive(Debug, Clone)]
pub struct HistoricalSelection {
pub index: usize,
pub selection: ItemCollection,
}
impl From<(usize, ItemCollection)> for HistoricalSelection {
fn from((index, selection): (usize, ItemCollection)) -> Self {
Self { index, selection }
}
}
const MAX_SELECTION_HISTORY_LENGTH: usize = 100;
#[derive(Clone, Default, Debug)]
pub struct SelectionHistory {
pub(crate) current: usize,
pub(crate) stack: Vec<ItemCollection>,
}
impl SelectionHistory {
pub(crate) fn on_frame_start(&mut self, blueprint: &Blueprint) {
crate::profile_function!();
let mut i = 0;
self.stack.retain_mut(|selection| {
selection.purge_invalid(blueprint);
let retain = !selection.is_empty();
if !retain && i <= self.current {
self.current = self.current.saturating_sub(1);
}
i += 1;
retain
});
self.current = self.current.min(self.stack.len().saturating_sub(1));
}
pub fn current(&self) -> Option<HistoricalSelection> {
self.stack
.get(self.current)
.cloned()
.map(|s| (self.current, s).into())
}
pub fn previous(&self) -> Option<HistoricalSelection> {
let prev_index = self.current.checked_sub(1)?;
let prev = self.stack.get(prev_index)?;
Some((prev_index, prev.clone()).into())
}
pub fn next(&self) -> Option<HistoricalSelection> {
self.stack
.get(self.current + 1)
.map(|sel| (self.current + 1, sel.clone()).into())
}
pub fn update_selection(&mut self, item_collection: &ItemCollection) {
if item_collection.is_empty() {
return;
}
if self.current().as_ref().map(|c| &c.selection) == Some(item_collection) {
return;
}
self.stack.truncate(self.current + 1);
self.stack.push(item_collection.clone());
if self.stack.len() > MAX_SELECTION_HISTORY_LENGTH {
self.stack
.drain((self.stack.len() - MAX_SELECTION_HISTORY_LENGTH)..self.stack.len());
}
self.current = self.stack.len() - 1;
}
}