makepad_platform/
live_traits.rs

1use {
2    crate::{
3        makepad_live_compiler::*,
4        cx::Cx,
5    }
6};
7
8pub use crate::live_cx::LiveBody;
9
10pub trait LiveHook {
11    fn before_live_design(_cx:&mut Cx){}
12        
13    fn apply_value_unknown(&mut self, cx: &mut Cx, _apply_from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
14        if !nodes[index].origin.node_has_prefix() {
15            cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
16        }
17        nodes.skip_node(index)
18    }
19
20    fn apply_value_instance(&mut self, _cx: &mut Cx, _apply_from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
21        nodes.skip_node(index)
22    }
23    
24    fn skip_apply(&mut self, _cx: &mut Cx, _apply_from: ApplyFrom, _index: usize, _nodes: &[LiveNode])->Option<usize>{None}
25    fn before_apply(&mut self, _cx: &mut Cx, _apply_from: ApplyFrom, _index: usize, _nodes: &[LiveNode]){}
26    fn after_apply(&mut self, _cx: &mut Cx, _apply_from: ApplyFrom, _index: usize, _nodes: &[LiveNode]) {}
27    fn after_apply_from(&mut self, cx: &mut Cx, apply_from: ApplyFrom) {
28        match apply_from{
29            ApplyFrom::NewFromDoc{..}=>self.after_new_from_doc(cx),
30            _=>()
31        }
32    }
33    fn after_new_from_doc(&mut self, _cx:&mut Cx){}
34    fn after_new_before_apply(&mut self, _cx: &mut Cx) {}
35}
36
37pub trait LiveHookDeref {
38    fn deref_before_apply(&mut self, _cx: &mut Cx, _apply_from: ApplyFrom, _index: usize, _nodes: &[LiveNode]){}
39    fn deref_after_apply(&mut self, _cx: &mut Cx, _apply_from: ApplyFrom, _index: usize, _nodes: &[LiveNode]){}
40}
41
42pub trait LiveNew: LiveApply {
43    fn new(cx: &mut Cx) -> Self;
44    
45    fn live_design_with(_cx: &mut Cx) {}
46    
47    fn live_type_info(cx: &mut Cx) -> LiveTypeInfo;
48    
49    fn new_apply(cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> Self where Self: Sized {
50        let mut ret = Self::new(cx);
51        ret.apply(cx, from, index, nodes);
52        ret
53    }
54    
55    fn new_apply_mut_index(cx: &mut Cx, from: ApplyFrom, index: &mut usize, nodes: &[LiveNode]) -> Self where Self: Sized {
56        let mut ret = Self::new(cx);
57        *index = ret.apply(cx, from, *index, nodes);
58        ret
59    }
60
61    fn new_from_ptr(cx: &mut Cx, live_ptr: Option<LivePtr>) -> Self where Self: Sized {
62        let mut ret = Self::new(cx);
63        if let Some(live_ptr) = live_ptr{
64            cx.get_nodes_from_live_ptr(live_ptr, |cx, file_id, index, nodes|{
65                ret.apply(cx, ApplyFrom::NewFromDoc {file_id}, index, nodes)
66            });
67        }
68        return ret
69    }
70    
71    fn new_main(cx: &mut Cx) -> Self where Self: Sized {
72        let lti = Self::live_type_info(cx);
73        {
74            let live_registry_rc = cx.live_registry.clone();
75            let mut live_registry = live_registry_rc.borrow_mut();
76            live_registry.main_module = Some((lti.module_id, lti.type_name));
77        }
78        Self::new_from_module(cx, lti.module_id, lti.type_name).unwrap()
79    }
80    
81    fn update_main(&mut self, cx:&mut Cx){
82        let (module_id, id) = {
83            let live_registry_rc = cx.live_registry.clone();
84            let live_registry = live_registry_rc.borrow_mut();
85            live_registry.main_module.unwrap()
86        };
87        self.update_from_module(cx, module_id, id);
88    }
89    
90    fn new_local(cx: &mut Cx) -> Self where Self: Sized {
91        let lti = Self::live_type_info(cx);
92        Self::new_from_module(cx, lti.module_id, lti.type_name).unwrap()
93    }
94    
95    fn new_from_module(cx: &mut Cx, module_id: LiveModuleId, id: LiveId) -> Option<Self> where Self: Sized {
96        let live_registry_rc = cx.live_registry.clone();
97        let live_registry = live_registry_rc.borrow();
98        if let Some(file_id) = live_registry.module_id_to_file_id.get(&module_id) {
99            let file = live_registry.file_id_to_file(*file_id);
100            if let Some(index) = file.expanded.nodes.child_by_name(0, id.as_instance()) {
101                let mut ret = Self::new(cx);
102                ret.apply(cx, ApplyFrom::NewFromDoc {file_id: *file_id}, index, &file.expanded.nodes);
103                return Some(ret)
104            }
105        }
106        None
107    }
108    
109    fn update_from_module(&mut self, cx: &mut Cx, module_id: LiveModuleId, id: LiveId)  {
110        let live_registry_rc = cx.live_registry.clone();
111        let live_registry = live_registry_rc.borrow();
112        if let Some(file_id) = live_registry.module_id_to_file_id.get(&module_id) {
113            let file = live_registry.file_id_to_file(*file_id);
114            if let Some(index) = file.expanded.nodes.child_by_name(0, id.as_instance()) {
115                
116                self.apply(cx, ApplyFrom::UpdateFromDoc {file_id: *file_id}, index, &file.expanded.nodes);
117            }
118        }
119    }
120}
121
122pub trait ToLiveValue {
123    fn to_live_value(&self) -> LiveValue;
124}
125
126pub trait LiveApplyValue {
127    fn apply_value(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize;
128}
129
130pub trait LiveApply {
131    fn apply(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize;
132    
133    fn apply_over(&mut self, cx: &mut Cx, nodes: &[LiveNode]) {
134        self.apply(cx, ApplyFrom::ApplyOver, 0, nodes);
135    }
136}
137
138pub trait LiveRead{
139    fn live_read_to(&self, id:LiveId, out:&mut Vec<LiveNode>);
140    fn live_read(&self)->Vec<LiveNode>{
141        let mut out = Vec::new();
142        self.live_read_to(LiveId(0),&mut out);
143        out
144    }
145    
146}
147
148impl<T, const N:usize> LiveRead for [T;N]  where T: LiveRead {
149    fn live_read_to(&self, id:LiveId, out:&mut Vec<LiveNode>){
150        out.open_array(id);
151        for i in 0..N{
152            self[i].live_read_to(LiveId(i as u64), out);
153        }
154        out.close();
155    }
156} 
157
158#[derive(Debug, Clone, Copy)]
159pub enum ApplyFrom {
160    NewFromDoc {file_id: LiveFileId}, // newed from DSL
161    UpdateFromDoc {file_id: LiveFileId}, // live DSL substantially updated
162    
163    New, // Bare new without file info
164    Animate, // from animate
165    AnimatorInit,
166    ApplyOver, // called from bare apply_live() call
167}
168
169impl ApplyFrom {
170    pub fn is_from_doc(&self) -> bool {
171        match self {
172            Self::NewFromDoc {..} => true,
173            Self::UpdateFromDoc {..} => true,
174            _ => false
175        }
176    }
177
178    pub fn is_new_from_doc(&self) -> bool {
179        match self {
180            Self::NewFromDoc {..} => true,
181            _ => false
182        }
183    }
184    
185    pub fn file_id(&self) -> Option<LiveFileId> {
186        match self {
187            Self::NewFromDoc {file_id} => Some(*file_id),
188            Self::UpdateFromDoc {file_id} => Some(*file_id),
189            _ => None
190        }
191    }
192}
193
194
195impl<T> LiveHook for Option<T> where T: LiveApply + LiveNew + 'static {}
196impl<T> LiveApply for Option<T> where T: LiveApply + LiveNew + 'static {
197    fn apply(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
198        if let Some(v) = self {
199            v.apply(cx, from, index, nodes)
200        }
201        else {
202            let mut inner = T::new(cx);
203            let index = inner.apply(cx, from, index, nodes);
204            *self = Some(inner);
205            index
206        }
207    }
208} 
209
210impl<T> LiveNew for Option<T> where T: LiveApply + LiveNew + 'static{
211    fn new(_cx: &mut Cx) -> Self {
212        Self::None
213    }
214    fn new_apply(cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> Self {
215        let mut ret = Self::None;
216        ret.apply(cx, from, index, nodes);
217        ret
218    }
219    
220    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
221        T::live_type_info(_cx)
222    }
223}
224
225
226impl<T> LiveHook for Vec<T> where T: LiveApply + LiveNew + 'static {}
227impl<T> LiveApply for Vec<T> where T: LiveApply + LiveNew + 'static {
228    fn apply(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
229        // we can only apply from an Array
230        self.clear();
231        if nodes[index].is_array(){
232            let mut index = index + 1;
233            loop{
234                if nodes[index].is_close(){
235                    index += 1;
236                    break;
237                }
238                let mut inner = T::new(cx);
239                index = inner.apply(cx, from, index, nodes);
240                self.push(inner);
241            }
242            index
243        }
244        else{
245            cx.apply_error_expected_array(live_error_origin!(), index, nodes);
246            nodes.skip_node(index)
247        }
248    }
249} 
250
251impl<T> LiveNew for Vec<T> where T: LiveApply + LiveNew + 'static{
252    fn new(_cx: &mut Cx) -> Self {
253        Vec::new()
254    }
255    fn new_apply(cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> Self {
256        let mut ret = Vec::new();
257        ret.apply(cx, from, index, nodes);
258        ret
259    }
260    
261    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
262        T::live_type_info(_cx)
263    }
264}
265
266
267impl<T, const N:usize> LiveHook for [T;N] where T: LiveApply + LiveNew + 'static{}
268impl<T, const N:usize> LiveApply for [T;N]  where T: LiveApply + LiveNew + 'static {
269    fn apply(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
270        // we can only apply from an Array
271        if nodes[index].is_array(){
272            let mut index = index + 1;
273            let mut count = 0;
274            loop{
275                if nodes[index].is_close(){
276                    index += 1;
277                    break;
278                }
279                if count < self.len(){
280                    index = self[count].apply(cx, from, index, nodes);
281                    count += 1;
282                }
283                else{
284                   index = nodes.skip_node(index)
285                }
286            }
287            index
288        }
289        else{
290            cx.apply_error_expected_array(live_error_origin!(), index, nodes);
291            nodes.skip_node(index)
292        }
293    }
294} 
295
296impl<T, const N:usize> LiveNew for [T;N] where T: LiveApply + LiveNew + 'static{
297    fn new(cx: &mut Cx) -> Self {
298        std::array::from_fn(|_| T::new(cx))
299    }
300    
301    fn new_apply(cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> Self {
302        let mut ret = Self::new(cx);
303        ret.apply(cx, from, index, nodes);
304        ret
305    }
306    
307    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
308        T::live_type_info(_cx)
309    }
310}
311
312
313
314