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 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}, UpdateFromDoc {file_id: LiveFileId}, New, Animate, AnimatorInit,
248 Over, }
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 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 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