makepad_platform/
live_traits.rs

1use {
2    crate::{
3        makepad_live_compiler::*,
4        cx::Cx,
5        scope::Scope,
6    }
7};
8
9pub use crate::live_cx::LiveBody;
10
11pub trait LiveRegister{
12    fn live_register(_cx:&mut Cx){}
13}
14
15pub trait LiveHook {
16    //fn before_live_design(_cx:&mut Cx){}
17        
18    fn apply_value_unknown(&mut self, cx: &mut Cx, _apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
19        if !nodes[index].origin.node_has_prefix() {
20            cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
21        }
22        nodes.skip_node(index)
23    }
24    
25    fn skip_apply_animator(&mut self, _cx: &mut Cx, _apply: &mut Apply, _index: usize, _nodes: &[LiveNode])->bool{
26        false
27    }
28
29    fn apply_value_instance(&mut self, _cx: &mut Cx, _apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
30        nodes.skip_node(index)
31    }
32    
33    fn skip_apply(&mut self, _cx: &mut Cx, _apply: &mut Apply, _index: usize, _nodes: &[LiveNode])->Option<usize>{None}
34    fn before_apply(&mut self, _cx: &mut Cx, _apply: &mut Apply, _index: usize, _nodes: &[LiveNode]){}
35    fn after_apply(&mut self, _cx: &mut Cx, _apply: &mut Apply, _index: usize, _nodes: &[LiveNode]) {}
36    fn after_apply_from(&mut self, cx: &mut Cx, apply: &mut Apply) {
37        match &apply.from{
38            ApplyFrom::NewFromDoc{..}=>{self.after_new_from_doc(cx);self.after_apply_from_doc(cx);}
39            ApplyFrom::UpdateFromDoc{..}=>{self.after_update_from_doc(cx);self.after_apply_from_doc(cx);}
40            _=>()
41        }
42    }
43    fn after_new_from_doc(&mut self, _cx:&mut Cx){}
44    fn after_update_from_doc(&mut self, _cx:&mut Cx){}
45    fn after_apply_from_doc(&mut self, _cx:&mut Cx){}
46    fn after_new_before_apply(&mut self, _cx: &mut Cx) {}
47}
48
49pub trait LiveHookDeref {
50    fn deref_before_apply(&mut self, _cx: &mut Cx, _apply: &mut Apply, _index: usize, _nodes: &[LiveNode]){}
51    fn deref_after_apply(&mut self, _cx: &mut Cx, _apply: &mut Apply, _index: usize, _nodes: &[LiveNode]){}
52}
53
54pub trait LiveNew: LiveApply {
55    fn new(cx: &mut Cx) -> Self;
56    
57    fn live_design_with(_cx: &mut Cx) {}
58    
59    fn live_type_info(cx: &mut Cx) -> LiveTypeInfo;
60    
61    fn new_apply(cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> Self where Self: Sized {
62        let mut ret = Self::new(cx);
63        ret.apply(cx, apply, index, nodes);
64        ret
65    }
66    
67    fn new_apply_over(cx: &mut Cx, nodes: &[LiveNode]) -> Self where Self: Sized {
68        let mut ret = Self::new(cx);
69        ret.apply_over(cx, nodes);
70        ret
71    }
72    
73    fn new_apply_mut_index(cx: &mut Cx, apply: &mut Apply, index: &mut usize, nodes: &[LiveNode]) -> Self where Self: Sized {
74        let mut ret = Self::new(cx);
75        *index = ret.apply(cx, apply, *index, nodes);
76        ret
77    }
78
79    fn new_from_ptr(cx: &mut Cx, live_ptr: Option<LivePtr>) -> Self where Self: Sized {
80        let mut ret = Self::new(cx);
81        if let Some(live_ptr) = live_ptr{ 
82            cx.get_nodes_from_live_ptr(live_ptr, |cx, file_id, index, nodes|{
83                ret.apply(cx, &mut ApplyFrom::NewFromDoc {file_id}.into(), index, nodes)
84            });
85        }
86        return ret
87    }
88    
89    fn update_from_ptr(&mut self, cx: &mut Cx, live_ptr: Option<LivePtr>) {
90        if let Some(live_ptr) = live_ptr{
91            cx.get_nodes_from_live_ptr(live_ptr, |cx, file_id, index, nodes|{
92                self.apply(cx, &mut ApplyFrom::UpdateFromDoc{file_id}.into(), index, nodes)
93            });
94        }
95    }
96    
97    fn update_from_ptr_with_scope(&mut self, cx: &mut Cx, live_ptr: Option<LivePtr>, scope:&mut Scope) {
98        if let Some(live_ptr) = live_ptr{
99            cx.get_nodes_from_live_ptr(live_ptr, |cx, file_id, index, nodes|{
100                self.apply(cx, &mut ApplyFrom::UpdateFromDoc{file_id}.with_scope(scope), index, nodes)
101            });
102        }
103    }
104    
105    fn new_from_ptr_with_scope(cx: &mut Cx, live_ptr: Option<LivePtr>, scope:&mut Scope) -> Self where Self: Sized {
106        let mut ret = Self::new(cx);
107        if let Some(live_ptr) = live_ptr{
108            cx.get_nodes_from_live_ptr(live_ptr, |cx, file_id, index, nodes|{
109                ret.apply(cx, &mut ApplyFrom::NewFromDoc {file_id}.with_scope(scope), index, nodes)
110            });
111        }
112        return ret
113    }
114    
115    fn new_main(cx: &mut Cx) -> Option<Self> where Self: Sized {
116        let lti = Self::live_type_info(cx);
117        Self::new_from_module(cx, lti.module_id, lti.type_name)
118    }
119    
120    fn register_main_module(cx: &mut Cx) {
121        let lti = Self::live_type_info(cx);
122        {
123            let live_registry_rc = cx.live_registry.clone();
124            let mut live_registry = live_registry_rc.borrow_mut();
125            live_registry.main_module = Some(lti.clone());
126        }
127    }
128    
129    fn update_main(&mut self, cx:&mut Cx){
130        let lti = {
131            let live_registry_rc = cx.live_registry.clone();
132            let live_registry = live_registry_rc.borrow_mut();
133            live_registry.main_module.as_ref().unwrap().clone()
134        };
135        self.update_from_module(cx, lti.module_id, lti.type_name);
136    }
137    
138    fn new_local(cx: &mut Cx) -> Self where Self: Sized {
139        let lti = Self::live_type_info(cx);
140        Self::new_from_module(cx, lti.module_id, lti.type_name).unwrap()
141    }
142    
143    fn new_from_module(cx: &mut Cx, module_id: LiveModuleId, id: LiveId) -> Option<Self> where Self: Sized {
144        let live_registry_rc = cx.live_registry.clone();
145        let live_registry = live_registry_rc.borrow();
146        if let Some(file_id) = live_registry.module_id_to_file_id.get(&module_id) {
147            let file = live_registry.file_id_to_file(*file_id);
148            if let Some(index) = file.expanded.nodes.child_by_name(0, id.as_instance()) {
149                let mut ret = Self::new(cx);
150                ret.apply(cx, &mut ApplyFrom::NewFromDoc {file_id: *file_id}.into(), index, &file.expanded.nodes);
151                return Some(ret)
152            }
153        }
154        None
155    }
156    
157    fn update_from_module(&mut self, cx: &mut Cx, module_id: LiveModuleId, id: LiveId)  {
158        let live_registry_rc = cx.live_registry.clone();
159        let live_registry = live_registry_rc.borrow();
160        if let Some(file_id) = live_registry.module_id_to_file_id.get(&module_id) {
161            let file = live_registry.file_id_to_file(*file_id);
162            if let Some(index) = file.expanded.nodes.child_by_name(0, id.as_instance()) {
163                self.apply(cx, &mut ApplyFrom::UpdateFromDoc {file_id: *file_id}.into(), index, &file.expanded.nodes);
164            }
165        }
166    }
167}
168
169pub trait ToLiveValue {
170    fn to_live_value(&self) -> LiveValue;
171}
172
173pub trait LiveApplyValue {
174    fn apply_value(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize;
175}
176
177pub trait LiveApplyReset { 
178    fn apply_reset(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]);
179}
180
181pub trait LiveApply {
182    fn apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize;
183    
184    fn apply_over(&mut self, cx: &mut Cx, nodes: &[LiveNode]) {
185        self.apply(cx, &mut ApplyFrom::Over.into(), 0, nodes);
186    }
187}
188
189pub trait LiveRead{
190    fn live_read_to(&self, id:LiveId, out:&mut Vec<LiveNode>);
191    fn live_read(&self)->Vec<LiveNode>{
192        let mut out = Vec::new();
193        self.live_read_to(LiveId(0),&mut out);
194        out
195    }
196    
197}
198
199impl<T, const N:usize> LiveRead for [T;N]  where T: LiveRead {
200    fn live_read_to(&self, id:LiveId, out:&mut Vec<LiveNode>){
201        out.open_array(id);
202        for i in 0..N{
203            self[i].live_read_to(LiveId(i as u64), out);
204        }
205        out.close();
206    }
207} 
208
209pub struct Apply<'a,'b,'c> {
210    pub from: ApplyFrom,
211    pub scope: Option<&'c mut Scope<'a,'b>>,
212}
213
214impl <'a,'b,'c> Apply<'a,'b,'c>{
215    pub fn override_from<F, R>(&mut self, from:ApplyFrom, f: F) -> R where F: FnOnce(&mut Apply) -> R{
216        if let Some(scope) = &mut self.scope{
217            f(&mut Apply{
218                from: from,
219                scope: Some(*scope)
220            })
221        }
222        else{
223            f(&mut Apply{
224                from: from,
225                scope: None
226            })
227            
228        }
229    }
230}
231
232impl ApplyFrom{
233    pub fn with_scope<'a, 'b, 'c>(self, scope:&'c mut Scope<'a,'b>)->Apply<'a, 'b, 'c>{
234        Apply{
235            from: self,
236            scope: Some(scope)
237        }
238    }
239}
240
241#[derive(Debug, Clone, Copy)]
242pub enum ApplyFrom {
243    NewFromDoc {file_id: LiveFileId}, // newed from DSL
244    UpdateFromDoc {file_id: LiveFileId}, // live DSL substantially updated
245    New, // Bare new without file info
246    Animate, // from animate
247    AnimatorInit,
248    Over, // called from bare apply_live() call
249}
250
251impl<'a,'b, 'c> From<ApplyFrom> for Apply<'a,'b,'c> {
252    fn from(from: ApplyFrom) -> Self {
253        Self {
254            from,
255            scope: None,
256        }
257    }
258}
259
260impl ApplyFrom {
261    pub fn is_from_doc(&self) -> bool {
262        match self {
263            Self::NewFromDoc {..} => true,
264            Self::UpdateFromDoc {..} => true,
265            _ => false
266        }
267    }
268
269    pub fn is_new_from_doc(&self) -> bool {
270        match self {
271            Self::NewFromDoc {..} => true,
272            _ => false
273        }
274    }
275    
276    pub fn should_apply_reset(&self) -> bool {
277        match self {
278            Self::UpdateFromDoc{..}  => true,
279            _ => false
280        }
281    }
282    
283    pub fn is_update_from_doc(&self) -> bool {
284        match self {
285            Self::UpdateFromDoc {..} => true,
286            _ => false
287        }
288    }
289        
290    pub fn file_id(&self) -> Option<LiveFileId> {
291        match self {
292            Self::NewFromDoc {file_id} => Some(*file_id),
293            Self::UpdateFromDoc {file_id,..} => Some(*file_id),
294            _ => None
295        }
296    }
297    
298    pub fn to_live_ptr(&self, cx:&Cx, index:usize) -> Option<LivePtr> {
299        if let Some(file_id) = self.file_id(){
300            let live_ptr = cx.live_registry.borrow().file_id_index_to_live_ptr(file_id, index);
301            return Some(live_ptr)
302        }
303        None
304    }
305        
306        
307}
308
309
310impl<T> LiveHook for Option<T> where T: LiveApply + LiveNew + 'static {}
311impl<T> LiveApply for Option<T> where T: LiveApply + LiveNew + 'static {
312    fn apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
313        if let Some(v) = self {
314            v.apply(cx, apply, index, nodes)
315        }
316        else {
317            let mut inner = T::new(cx);
318            let index = inner.apply(cx, apply, index, nodes);
319            *self = Some(inner);
320            index
321        }
322    }
323} 
324
325impl<T> LiveNew for Option<T> where T: LiveApply + LiveNew + 'static{
326    fn new(_cx: &mut Cx) -> Self {
327        Self::None
328    }
329    fn new_apply(cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> Self {
330        let mut ret = Self::None;
331        ret.apply(cx, apply, index, nodes);
332        ret
333    }
334    
335    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
336        T::live_type_info(_cx)
337    }
338}
339
340
341impl<T> LiveHook for Vec<T> where T: LiveApply + LiveNew + 'static {}
342impl<T> LiveApply for Vec<T> where T: LiveApply + LiveNew + 'static {
343    fn apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
344        // we can only apply from an Array
345        self.clear();
346        if nodes[index].is_array(){
347            let mut index = index + 1;
348            loop{
349                if nodes[index].is_close(){
350                    index += 1;
351                    break;
352                }
353                let mut inner = T::new(cx);
354                index = inner.apply(cx, apply, index, nodes);
355                self.push(inner);
356            }
357            index
358        }
359        else{
360            cx.apply_error_expected_array(live_error_origin!(), index, nodes);
361            nodes.skip_node(index)
362        }
363    }
364} 
365
366impl<T> LiveNew for Vec<T> where T: LiveApply + LiveNew + 'static{
367    fn new(_cx: &mut Cx) -> Self {
368        Vec::new()
369    }
370    fn new_apply(cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> Self {
371        let mut ret = Vec::new();
372        ret.apply(cx, apply, index, nodes);
373        ret
374    }
375    
376    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
377        T::live_type_info(_cx)
378    }
379}
380
381
382impl<T, const N:usize> LiveHook for [T;N] where T: LiveApply + LiveNew + 'static{}
383impl<T, const N:usize> LiveApply for [T;N]  where T: LiveApply + LiveNew + 'static {
384    fn apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
385        // we can only apply from an Array
386        if nodes[index].is_array(){
387            let mut index = index + 1;
388            let mut count = 0;
389            loop{
390                if nodes[index].is_close(){
391                    index += 1;
392                    break;
393                }
394                if count < self.len(){
395                    index = self[count].apply(cx, apply, index, nodes);
396                    count += 1;
397                }
398                else{
399                   index = nodes.skip_node(index)
400                }
401            }
402            index
403        }
404        else{
405            cx.apply_error_expected_array(live_error_origin!(), index, nodes);
406            nodes.skip_node(index)
407        }
408    }
409} 
410
411impl<T, const N:usize> LiveNew for [T;N] where T: LiveApply + LiveNew + 'static{
412    fn new(cx: &mut Cx) -> Self {
413        std::array::from_fn(|_| T::new(cx))
414    }
415    
416    fn new_apply(cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> Self {
417        let mut ret = Self::new(cx);
418        ret.apply(cx, apply, index, nodes);
419        ret
420    }
421    
422    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
423        T::live_type_info(_cx)
424    }
425}
426
427
428
429