makepad_live_compiler/
live_component.rs

1use {
2    std::{
3        any::TypeId,
4        cell::RefCell,
5        rc::Rc,
6        collections::{
7            BTreeSet,
8            HashMap,
9            hash_map::Entry
10        }
11    },
12    crate::{
13        makepad_derive_live::*,
14        makepad_live_tokenizer::{LiveId},
15        LiveType,
16        live_ptr::LiveModuleId,
17    }
18};
19
20#[derive(Clone)]
21pub struct LiveComponentInfo {
22    pub name: LiveId,
23    pub module_id: LiveModuleId,
24}
25
26pub trait LiveComponentRegistry {
27    fn type_id(&self) -> LiveType;
28    fn get_component_info(&self, name: LiveId) -> Option<LiveComponentInfo>;
29    fn component_type(&self) -> LiveId;
30    fn get_module_set(&self, set: &mut BTreeSet<LiveModuleId>);
31}
32
33#[derive(Default, Clone)]
34pub struct LiveComponentRegistries(pub Rc<RefCell<HashMap<LiveType, Box<dyn LiveComponentRegistry >> >>);
35
36generate_ref_cast_api!(LiveComponentRegistry);
37
38impl LiveComponentRegistries {
39    pub fn find_component(&self, ty: LiveId, name: LiveId) -> Option<LiveComponentInfo> {
40        let reg = self.0.borrow();
41        for entry in reg.values() {
42            if entry.component_type() == ty {
43                return entry.get_component_info(name)
44            }
45        }
46        None
47    }
48    
49    pub fn new() -> Self {
50        Self (Rc::new(RefCell::new(HashMap::new())))
51    }
52    
53    pub fn get<T: 'static + LiveComponentRegistry>(&self) -> std::cell::Ref<'_, T> {
54        std::cell::Ref::map(
55            self.0.borrow(),
56            | v | v
57                .get(&TypeId::of::<T>()).unwrap()
58                .cast::<T>().unwrap()
59        )
60    }
61    
62    pub fn get_or_create<T: 'static + Default + LiveComponentRegistry>(&self) -> std::cell::RefMut<'_, T>
63    {
64        let reg = self.0.borrow_mut();
65        std::cell::RefMut::map(
66            reg,
67            | v |
68            match v.entry(TypeId::of::<T>()) {
69                Entry::Occupied(o) => o.into_mut(),
70                Entry::Vacant(v) => v.insert(Box::<T>::default())
71            }
72            .cast_mut::<T>().unwrap()
73        )
74    }
75}
76