makepad_live_compiler/
live_component.rs1use {
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