makepad_platform/
scope.rs

1use crate::makepad_live_id::*;
2use std::any::Any;
3use std::fmt::{Debug, Formatter};
4use smallvec::*;
5
6#[derive(Default, Clone)]
7pub struct HeapLiveIdPath{
8    pub data: SmallVec<[LiveId;16]>, 
9}
10
11impl HeapLiveIdPath{
12    pub fn last(&self)->LiveId{
13        *self.data.last().unwrap_or(&LiveId(0))
14    }
15    
16    pub fn from_end(&self, pos:usize)->LiveId{
17        *self.data.iter().rev().nth(pos).unwrap_or(&LiveId(0))
18    }
19    
20    pub fn push(&mut self, id:LiveId){
21        self.data.push(id);
22    }
23    pub fn pop(&mut self){
24        self.data.pop();
25    }
26}
27
28impl Debug for HeapLiveIdPath {
29    fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
30        for i in 0..self.data.len(){
31            if i!=0{
32                let _ = write!(f, ".");
33            }
34            let _ = write!(f, "{}", self.data[i]);
35        }
36        Ok(())
37    }
38}
39
40
41#[derive(Default)]
42pub struct Scope<'a,'b>{
43    pub path: HeapLiveIdPath,
44    pub data: ScopeDataMut<'a>,
45    pub props: ScopeDataRef<'b>,
46    pub index: usize
47}
48
49#[derive(Default)]
50pub struct ScopeDataRef<'a>(Option<&'a dyn Any>);
51
52#[derive(Default)]
53pub struct ScopeDataMut<'a>(Option<&'a mut dyn Any>);
54
55impl <'a> ScopeDataRef<'a>{
56    pub fn get<T: Any>(&self) -> Option<&T> {
57        self.0.as_ref().and_then(|r| r.downcast_ref())
58    }
59}
60
61impl <'a> ScopeDataMut<'a>{
62    pub fn get<T: Any>(&mut self) -> Option<&T> {
63        self.0.as_ref().and_then(|r| r.downcast_ref())
64    }
65                    
66    pub fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
67        self.0.as_mut().and_then(|r| r.downcast_mut())
68    }
69}
70
71impl<'a,'b> Scope<'a,'b>{
72    pub fn with_data<T: Any>(v: &'a mut T)->Self{
73        Self{
74            path:HeapLiveIdPath::default(),
75            data:ScopeDataMut(Some(v)),
76            props:ScopeDataRef(None),
77            index: 0
78        }
79    }
80        
81    pub fn with_data_props<T: Any + Sized, U: Any + Sized>(v: &'a mut T, w: &'b U)->Self{
82        Self{
83            path:HeapLiveIdPath::default(),
84            data:ScopeDataMut(Some(v)),
85            props:ScopeDataRef(Some(w)),
86            index: 0
87        }
88    }
89        
90    pub fn with_props<T: Any>(w: &'b T)->Self{
91        Self{
92            path:HeapLiveIdPath::default(),
93            data:ScopeDataMut(None),
94            props:ScopeDataRef(Some(w)),
95            index: 0
96        }
97    }
98    
99    pub fn with_data_index<T: Any>(v:&'a mut T, index:usize)->Self{
100        Self{
101            path:HeapLiveIdPath::default(),
102            data:ScopeDataMut(Some(v)),
103            props:ScopeDataRef(None),
104            index
105        }
106    }
107            
108    pub fn with_data_props_index<T: Any>(v:&'a mut T, w:&'b T, index:usize)->Self{
109        Self{
110            path:HeapLiveIdPath::default(),
111            data:ScopeDataMut(Some(v)),
112            props:ScopeDataRef(Some(w)),
113            index
114        }
115    }
116            
117    pub fn with_props_index<T: Any>( w:&'b T, index:usize)->Self{
118        Self{
119            path:HeapLiveIdPath::default(),
120            data:ScopeDataMut(None),
121            props:ScopeDataRef(Some(w)),
122            index
123        }
124    }
125    
126    pub fn empty()->Self{
127        Self{
128            path:HeapLiveIdPath::default(),
129            data:ScopeDataMut(None),
130            props:ScopeDataRef(None),
131            index: 0
132        }
133    }
134        
135    pub fn with_id<F, R>(&mut self, id:LiveId, f: F) -> R where F: FnOnce(&mut Scope) -> R{
136        self.path.push(id);
137        let r = f(self);
138        self.path.pop();
139        r
140    }
141    
142    pub fn override_props<T:Any, F, R>(&mut self, props:&'b T, f: F) -> R where F: FnOnce(&mut Scope) -> R{
143        let mut props = ScopeDataRef(Some(props));
144        std::mem::swap(&mut self.props, &mut props);
145        let r = f(self);
146        std::mem::swap(&mut self.props, &mut props);
147        r
148    }
149    
150    pub fn override_props_index<T:Any, F, R>(&mut self, props:&'b T, index:usize, f: F) -> R where F: FnOnce(&mut Scope) -> R{
151        let mut props = ScopeDataRef(Some(props));
152        let old_index = self.index;
153        self.index = index;
154        std::mem::swap(&mut self.props, &mut props);
155        let r = f(self);
156        std::mem::swap(&mut self.props, &mut props);
157        self.index = old_index;
158        r
159    }
160}