Skip to main content

ferroui_base/interactivity/
routed_event_registry.rs

1use super::RoutedEvent;
2use crate::{StaticType, TypeInfo};
3use std::cell::RefCell;
4use std::collections::HashMap;
5
6/// Tracks registered routed events.
7///
8/// Like routed event definitions, the registry is per-thread.
9pub struct RoutedEventRegistry {
10    registered_routed_events: RefCell<HashMap<&'static TypeInfo, Vec<RoutedEvent>>>,
11}
12
13impl Default for RoutedEventRegistry {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl RoutedEventRegistry {
20    /// Creates an empty registry.
21    pub fn new() -> Self {
22        Self { registered_routed_events: RefCell::new(HashMap::new()) }
23    }
24
25    /// The routed event registry instance of the current thread.
26    pub fn instance() -> &'static RoutedEventRegistry {
27        crate::ferro_thread_local! {
28            static INSTANCE: &'static RoutedEventRegistry = Box::leak(Box::new(RoutedEventRegistry::new()));
29        }
30        INSTANCE.with(|instance| *instance)
31    }
32
33    /// Registers a routed event on a type.
34    ///
35    /// You won't usually want to call this method directly: use
36    /// [`RoutedEvent::register`], which calls it.
37    pub fn register<T: ?Sized>(&self, type_: &'static TypeInfo, event: RoutedEvent<T>) {
38        self.registered_routed_events.borrow_mut().entry(type_).or_default().push(event.as_routed_event());
39    }
40
41    /// Returns all routed events registered with the registry.
42    pub fn get_all_registered(&self) -> Vec<RoutedEvent> {
43        self.registered_routed_events.borrow().values().flat_map(|events| events.iter().copied()).collect()
44    }
45
46    /// Returns the routed events registered on a type.
47    pub fn get_registered(&self, type_: &'static TypeInfo) -> Vec<RoutedEvent> {
48        self.registered_routed_events.borrow().get(type_).cloned().unwrap_or_default()
49    }
50
51    /// Returns the routed events registered on class `TOwner`.
52    pub fn get_registered_for<TOwner: StaticType>(&self) -> Vec<RoutedEvent> {
53        self.get_registered(TOwner::TYPE)
54    }
55}