use super::UndoAction;
use crate::document::Document;
use crate::gpu::compositor::Compositor;
use crate::gpu::region_store::UndoRegionEntry;
use crate::layer::LayerId;
use std::collections::{HashMap, HashSet};
pub struct CompoundAction {
actions: Vec<Box<dyn UndoAction>>,
}
impl CompoundAction {
pub fn new(actions: Vec<Box<dyn UndoAction>>) -> Self {
CompoundAction { actions }
}
}
impl UndoAction for CompoundAction {
fn undo(&mut self, doc: &mut Document) -> HashMap<LayerId, HashSet<(i32, i32)>> {
let mut all = HashMap::new();
for action in self.actions.iter_mut().rev() {
for (id, coords) in action.undo(doc) {
all.entry(id).or_insert_with(HashSet::new).extend(coords);
}
}
all
}
fn redo(&mut self, doc: &mut Document) -> HashMap<LayerId, HashSet<(i32, i32)>> {
let mut all = HashMap::new();
for action in self.actions.iter_mut() {
for (id, coords) in action.redo(doc) {
all.entry(id).or_insert_with(HashSet::new).extend(coords);
}
}
all
}
fn gpu_region_entry_mut(&mut self) -> Option<&mut UndoRegionEntry> {
self.actions
.iter_mut()
.find_map(|a| a.gpu_region_entry_mut())
}
fn gpu_region_entries_mut(&mut self) -> Vec<&mut UndoRegionEntry> {
self.actions
.iter_mut()
.flat_map(|a| a.gpu_region_entries_mut())
.collect()
}
fn on_evict(&mut self, compositor: &mut Compositor) {
for action in self.actions.iter_mut() {
action.on_evict(compositor);
}
}
fn byte_cost(&self) -> u64 {
self.actions
.iter()
.map(|a| a.byte_cost())
.fold(0u64, u64::saturating_add)
}
}