use crate::AutoDefault; use crate::core::AnyCast; use crate::core::action::{ActionBox, ActionDispatcher}; use crate::trace; use parking_lot::RwLock; #[derive(AutoDefault)] pub struct ActionsList(RwLock>); impl ActionsList { pub fn new() -> Self { Self::default() } pub fn add(&mut self, action: ActionBox) { let mut list = self.0.write(); list.push(action); list.sort_by_key(|a| a.weight()); } pub fn for_each(&self, mut f: F) where A: ActionDispatcher, F: FnMut(&A), { let list = self.0.read(); for a in list.iter().rev() { if let Some(action) = (**a).downcast_ref::() { f(action); } else { trace::error!("Failed to downcast action of type {}", (**a).type_name()); } } } pub fn try_for_each(&self, mut f: F) where A: ActionDispatcher, F: FnMut(&A) -> std::ops::ControlFlow<()>, { let list = self.0.read(); for a in list.iter().rev() { if let Some(action) = (**a).downcast_ref::() { if f(action).is_break() { break; } } else { trace::error!("Failed to downcast action of type {}", (**a).type_name()); } } } }