makepad_platform/
scope.rs1use 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}