makepad_platform/
animator.rs

1
2use {
3    std::f64::consts::PI,
4    crate::{
5        makepad_live_compiler::{
6            LiveRef,
7            LiveNodeReader,
8            LiveNodeOrigin,
9            LiveValue,
10            LiveTypeInfo,
11            LiveTypeField,
12            LivePropType,
13            LiveFieldKind,
14            LiveModuleId,
15            LiveType,
16            LiveNode,
17            LiveIdAsProp,
18            LiveNodeSliceApi,  
19            LiveNodeVecApi
20        },
21        scope::Scope,
22        makepad_live_tokenizer::{LiveErrorOrigin, live_error_origin},
23        makepad_live_id::*,
24        makepad_derive_live::*,
25        makepad_math::*,
26        cursor::MouseCursor,
27        event::{Event, NextFrame},
28        cx::Cx,
29        live_traits::*,
30    },
31};
32
33pub trait AnimatorImpl {
34    
35    fn animator_cut(&mut self, cx: &mut Cx, state: &[LiveId; 2]){
36        self.animator_cut_with_scope(cx, state, &mut Scope::empty())
37    }
38    fn animator_play(&mut self, cx: &mut Cx, state: &[LiveId; 2]){
39        self.animator_play_with_scope(cx, state, &mut Scope::empty())
40    }
41    fn animator_cut_with_scope(&mut self, cx: &mut Cx, state: &[LiveId; 2], scope:&mut Scope);
42    fn animator_play_with_scope(&mut self, cx: &mut Cx, state: &[LiveId; 2], scope:&mut Scope);
43    fn animator_toggle_with_scope(&mut self, cx: &mut Cx, is_state_1: bool, animate: Animate, state1: &[LiveId; 2], state2: &[LiveId; 2], scope:&mut Scope) {
44        if is_state_1 {
45            if let Animate::Yes = animate {
46                self.animator_play_with_scope(cx, state1, scope)
47            }
48            else {
49                self.animator_cut_with_scope(cx, state1, scope)
50            }
51        }
52        else {
53            if let Animate::Yes = animate {
54                self.animator_play_with_scope(cx, state2, scope)
55            }
56            else {
57                self.animator_cut_with_scope(cx, state2, scope)
58            }
59        }
60    }
61    fn animator_toggle(&mut self, cx: &mut Cx, is_state_1: bool, animate: Animate, state1: &[LiveId; 2], state2: &[LiveId; 2]) {
62        self.animator_toggle_with_scope(cx, is_state_1, animate, state1, state2, &mut Scope::empty())
63    }
64    fn animator_in_state(&self, cx: &Cx, check_state_pair: &[LiveId; 2]) -> bool;
65    fn animator_apply_state(&mut self, cx: &mut Cx, scope:&mut Scope);
66    fn animator_after_apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]);
67    fn animator_handle_event(&mut self, cx: &mut Cx, event: &Event) -> AnimatorAction{
68        self.animator_handle_event_with_scope(cx, event, &mut Scope::empty())
69    }
70    fn animator_handle_event_with_scope(&mut self, cx: &mut Cx, event: &Event, scope:&mut Scope) -> AnimatorAction;
71}
72
73#[derive(Debug, Clone, Copy)]
74pub enum Animate {
75    Yes,
76    No
77}
78
79// deserialisable DSL structure
80#[derive(Debug, Clone, Live, LiveHook)]
81pub struct KeyFrame {
82    #[live(Ease::Linear)]
83    pub ease: Ease,
84    
85    #[live(1.0)]
86    pub time: f64,
87    
88    #[live(LiveValue::None)]
89    pub value: LiveValue,
90}
91impl LiveRegister for KeyFrame{}
92
93#[derive(Copy, Clone, Debug, PartialEq, Live, LiveHook)]
94pub enum Play {
95    #[pick {duration: 1.0}]
96    Forward {duration: f64},
97    
98    Snap,
99    
100    #[live {duration: 1.0, end: 1.0}]
101    Reverse {duration: f64, end: f64},
102    
103    #[live {duration: 1.0, end: 1.0}]
104    Loop {duration: f64, end: f64},
105    
106    #[live {duration: 1.0, end: 1.0}]
107    ReverseLoop {duration: f64, end: f64},
108    
109    #[live {duration: 1.0, end: 1.0}]
110    BounceLoop {duration: f64, end: f64},
111}
112//pub type StatePair = [LiveId; 2];
113
114impl Play {
115    /*
116    pub fn duration(&self) -> f64 {
117        match self {
118            Self::Forward {duration, ..} => *duration,
119            Self::Reverse {duration, ..} => *duration,
120            Self::Loop {duration, ..} => *duration,
121            Self::ReverseLoop {duration, ..} => *duration,
122            Self::BounceLoop {duration, ..} => *duration,
123        }
124    }*/
125    
126    pub fn get_ended_time(&self, time: f64) -> (bool, f64) {
127        match self {
128            Self::Snap => (true, 1.0),
129            Self::Forward {duration} => {
130                if *duration == 0.0 {return (true, 1.0)}
131                (time > *duration, time.min(*duration) / duration)
132            },
133            Self::Reverse {duration, end} => {
134                if *duration == 0.0 {return (true, 1.0)}
135                (time > *duration, end - (time.min(*duration) / duration))
136            },
137            Self::Loop {duration, end} => {
138                if *duration == 0.0 {return (true, 1.0)}
139                (false, (time / duration) % end)
140            },
141            Self::ReverseLoop {end, duration} => {
142                if *duration == 0.0 {return (true, 1.0)}
143                (false, end - (time / duration) % end)
144            },
145            Self::BounceLoop {end, duration} => {
146                if *duration == 0.0 {return (true, 1.0)}
147                let mut local_time = (time / duration) % (end * 2.0);
148                if local_time > *end {
149                    local_time = 2.0 * end - local_time;
150                };
151                (false, local_time)
152            },
153        }
154    }
155}
156
157
158#[derive(Clone, Copy, Debug, PartialEq, Live, LiveHook)]
159pub enum Ease {
160    #[pick] Linear,
161    #[live] None,
162    #[live(1.0)] Constant(f64),
163    #[live] InQuad,
164    #[live] OutQuad,
165    #[live] InOutQuad,
166    #[live] InCubic,
167    #[live] OutCubic,
168    #[live] InOutCubic,
169    #[live] InQuart,
170    #[live] OutQuart,
171    #[live] InOutQuart,
172    #[live] InQuint,
173    #[live] OutQuint,
174    #[live] InOutQuint,
175    #[live] InSine,
176    #[live] OutSine,
177    #[live] InOutSine,
178    #[live] InExp,
179    #[live] OutExp,
180    #[live] InOutExp,
181    #[live] InCirc,
182    #[live] OutCirc,
183    #[live] InOutCirc,
184    #[live] InElastic,
185    #[live] OutElastic,
186    #[live] InOutElastic,
187    #[live] InBack,
188    #[live] OutBack,
189    #[live] InOutBack,
190    #[live] InBounce,
191    #[live] OutBounce,
192    #[live] InOutBounce,
193    #[live {d1: 0.82, d2: 0.97, max: 100}] ExpDecay {d1: f64, d2: f64, max: usize},
194    
195    #[live {begin: 0.0, end: 1.0}] Pow {begin: f64, end: f64},
196    #[live {cp0: 0.0, cp1: 0.0, cp2: 1.0, cp3: 1.0}] Bezier {cp0: f64, cp1: f64, cp2: f64, cp3: f64}
197}
198
199impl Ease {
200    pub fn map(&self, t: f64) -> f64 {
201        match self {
202            Self::ExpDecay {d1, d2, max} => { // there must be a closed form for this
203                if t > 0.999 {
204                    return 1.0;
205                }
206
207                // first we count the number of steps we'd need to decay
208                let mut di = *d1;
209                let mut dt = 1.0;
210                let max_steps = (*max).min(1000);
211                let mut steps = 0;
212                // for most of the settings we use this takes max 15 steps or so
213                while dt > 0.001 && steps < max_steps {
214                    steps = steps + 1;
215                    dt = dt * di;
216                    di *= d2;
217                }
218                // then we know how to find the step, and lerp it
219                let step = t * (steps as f64);
220                let mut di = *d1;
221                let mut dt = 1.0;
222                let max_steps = max_steps as f64;
223                let mut steps = 0.0;
224                while dt > 0.001 && steps < max_steps {
225                    steps += 1.0;
226                    if steps >= step { // right step
227                        let fac = steps - step;
228                        return 1.0 - (dt * fac + (dt * di) * (1.0 - fac))
229                    }
230                    dt = dt * di;
231                    di *= d2;
232                }
233                1.0
234            }
235            Self::Linear => {
236                return t.max(0.0).min(1.0);
237            },
238            Self::Constant(t) => {
239                return t.max(0.0).min(1.0);
240            },
241            Self::None => {
242                return 1.0;
243            },
244            Self::Pow {begin, end} => {
245                if t < 0. {
246                    return 0.;
247                }
248                if t > 1. {
249                    return 1.;
250                }
251                let a = -1. / (begin * begin).max(1.0);
252                let b = 1. + 1. / (end * end).max(1.0);
253                let t2 = (((a - 1.) * -b) / (a * (1. - b))).powf(t);
254                return (-a * b + b * a * t2) / (a * t2 - b);
255            },
256            
257            Self::InQuad => {
258                return t * t;
259            },
260            Self::OutQuad => {
261                return t * (2.0 - t);
262            },
263            Self::InOutQuad => {
264                let t = t * 2.0;
265                if t < 1. {
266                    return 0.5 * t * t;
267                }
268                else {
269                    let t = t - 1.;
270                    return -0.5 * (t * (t - 2.) - 1.);
271                }
272            },
273            Self::InCubic => {
274                return t * t * t;
275            },
276            Self::OutCubic => {
277                let t2 = t - 1.0;
278                return t2 * t2 * t2 + 1.0;
279            },
280            Self::InOutCubic => {
281                let t = t * 2.0;
282                if t < 1. {
283                    return 0.5 * t * t * t;
284                }
285                else {
286                    let t = t - 2.;
287                    return 1. / 2. * (t * t * t + 2.);
288                }
289            },
290            Self::InQuart => {
291                return t * t * t * t
292            },
293            Self::OutQuart => {
294                let t = t - 1.;
295                return -(t * t * t * t - 1.);
296            },
297            Self::InOutQuart => {
298                let t = t * 2.0;
299                if t < 1. {
300                    return 0.5 * t * t * t * t;
301                }
302                else {
303                    let t = t - 2.;
304                    return -0.5 * (t * t * t * t - 2.);
305                }
306            },
307            Self::InQuint => {
308                return t * t * t * t * t;
309            },
310            Self::OutQuint => {
311                let t = t - 1.;
312                return t * t * t * t * t + 1.;
313            },
314            Self::InOutQuint => {
315                let t = t * 2.0;
316                if t < 1. {
317                    return 0.5 * t * t * t * t * t;
318                }
319                else {
320                    let t = t - 2.;
321                    return 0.5 * (t * t * t * t * t + 2.);
322                }
323            },
324            Self::InSine => {
325                return -(t * PI * 0.5).cos() + 1.;
326            },
327            Self::OutSine => {
328                return (t * PI * 0.5).sin();
329            },
330            Self::InOutSine => {
331                return -0.5 * ((t * PI).cos() - 1.);
332            },
333            Self::InExp => {
334                if t < 0.001 {
335                    return 0.;
336                }
337                else {
338                    return 2.0f64.powf(10. * (t - 1.));
339                }
340            },
341            Self::OutExp => {
342                if t > 0.999 {
343                    return 1.;
344                }
345                else {
346                    return -(2.0f64.powf(-10. * t)) + 1.;
347                }
348            },
349            Self::InOutExp => {
350                if t<0.001 {
351                    return 0.;
352                }
353                if t>0.999 {
354                    return 1.;
355                }
356                let t = t * 2.0;
357                if t < 1. {
358                    return 0.5 * 2.0f64.powf(10. * (t - 1.));
359                }
360                else {
361                    let t = t - 1.;
362                    return 0.5 * (-(2.0f64.powf(-10. * t)) + 2.);
363                }
364            },
365            Self::InCirc => {
366                return -((1. - t * t).sqrt() - 1.);
367            },
368            Self::OutCirc => {
369                let t = t - 1.;
370                return (1. - t * t).sqrt();
371            },
372            Self::InOutCirc => {
373                let t = t * 2.;
374                if t < 1. {
375                    return -0.5 * ((1. - t * t).sqrt() - 1.);
376                }
377                else {
378                    let t = t - 2.;
379                    return 0.5 * ((1. - t * t).sqrt() + 1.);
380                }
381            },
382            Self::InElastic => {
383                let p = 0.3;
384                let s = p / 4.0; // c = 1.0, b = 0.0, d = 1.0
385                if t < 0.001 {
386                    return 0.;
387                }
388                if t > 0.999 {
389                    return 1.;
390                }
391                let t = t - 1.0;
392                return -(2.0f64.powf(10.0 * t) * ((t - s) * (2.0 * PI) / p).sin());
393            },
394            Self::OutElastic => {
395                let p = 0.3;
396                let s = p / 4.0; // c = 1.0, b = 0.0, d = 1.0
397                
398                if t < 0.001 {
399                    return 0.;
400                }
401                if t > 0.999 {
402                    return 1.;
403                }
404                return 2.0f64.powf(-10.0 * t) * ((t - s) * (2.0 * PI) / p).sin() + 1.0;
405            },
406            Self::InOutElastic => {
407                let p = 0.3;
408                let s = p / 4.0; // c = 1.0, b = 0.0, d = 1.0
409                if t < 0.001 {
410                    return 0.;
411                }
412                if t > 0.999 {
413                    return 1.;
414                }
415                let t = t * 2.0;
416                if t < 1. {
417                    let t = t - 1.0;
418                    return -0.5 * (2.0f64.powf(10.0 * t) * ((t - s) * (2.0 * PI) / p).sin());
419                }
420                else {
421                    let t = t - 1.0;
422                    return 0.5 * 2.0f64.powf(-10.0 * t) * ((t - s) * (2.0 * PI) / p).sin() + 1.0;
423                }
424            },
425            Self::InBack => {
426                let s = 1.70158;
427                return t * t * ((s + 1.) * t - s);
428            },
429            Self::OutBack => {
430                let s = 1.70158;
431                let t = t - 1.;
432                return t * t * ((s + 1.) * t + s) + 1.;
433            },
434            Self::InOutBack => {
435                let s = 1.70158;
436                let t = t * 2.0;
437                if t < 1. {
438                    let s = s * 1.525;
439                    return 0.5 * (t * t * ((s + 1.) * t - s));
440                }
441                else {
442                    let t = t - 2.;
443                    return 0.5 * (t * t * ((s + 1.) * t + s) + 2.);
444                }
445            },
446            Self::InBounce => {
447                return 1.0 - Self::OutBounce.map(1.0 - t);
448            },
449            Self::OutBounce => {
450                if t < (1. / 2.75) {
451                    return 7.5625 * t * t;
452                }
453                if t < (2. / 2.75) {
454                    let t = t - (1.5 / 2.75);
455                    return 7.5625 * t * t + 0.75;
456                }
457                if t < (2.5 / 2.75) {
458                    let t = t - (2.25 / 2.75);
459                    return 7.5625 * t * t + 0.9375;
460                }
461                let t = t - (2.625 / 2.75);
462                return 7.5625 * t * t + 0.984375;
463            },
464            Self::InOutBounce => {
465                if t <0.5 {
466                    return Self::InBounce.map(t * 2.) * 0.5;
467                }
468                else {
469                    return Self::OutBounce.map(t * 2. - 1.) * 0.5 + 0.5;
470                }
471            },
472            Self::Bezier {cp0, cp1, cp2, cp3} => {
473                if t < 0. {
474                    return 0.;
475                }
476                if t > 1. {
477                    return 1.;
478                }
479                
480                if (cp0 - cp1).abs() < 0.001 && (cp2 - cp3).abs() < 0.001 {
481                    return t;
482                }
483                
484                let epsilon = 1.0 / 200.0 * t;
485                let cx = 3.0 * cp0;
486                let bx = 3.0 * (cp2 - cp0) - cx;
487                let ax = 1.0 - cx - bx;
488                let cy = 3.0 * cp1;
489                let by = 3.0 * (cp3 - cp1) - cy;
490                let ay = 1.0 - cy - by;
491                let mut u = t;
492                
493                for _i in 0..6 {
494                    let x = ((ax * u + bx) * u + cx) * u - t;
495                    if x.abs() < epsilon {
496                        return ((ay * u + by) * u + cy) * u;
497                    }
498                    let d = (3.0 * ax * u + 2.0 * bx) * u + cx;
499                    if d.abs() < 1e-6 {
500                        break;
501                    }
502                    u = u - x / d;
503                };
504                
505                if t > 1. {
506                    return (ay + by) + cy;
507                }
508                if t < 0. {
509                    return 0.0;
510                }
511                
512                let mut w = 0.0;
513                let mut v = 1.0;
514                u = t;
515                for _i in 0..8 {
516                    let x = ((ax * u + bx) * u + cx) * u;
517                    if (x - t).abs() < epsilon {
518                        return ((ay * u + by) * u + cy) * u;
519                    }
520                    
521                    if t > x {
522                        w = u;
523                    }
524                    else {
525                        v = u;
526                    }
527                    u = (v - w) * 0.5 + w;
528                }
529                
530                return ((ay * u + by) * u + cy) * u;
531            }
532        }
533    }
534}
535
536#[derive(Default)]
537pub struct Animator {
538    pub ignore_missing: bool,
539    pub live_ptr: LiveRef,
540    pub state: Option<Vec<LiveNode >>,
541    pub next_frame: NextFrame,
542}
543
544#[derive(Copy, Clone)]
545pub enum AnimatorAction {
546    Animating {redraw: bool},
547    None
548}
549
550impl LiveHook for Animator {}
551impl LiveNew for Animator {
552    fn new(_cx: &mut Cx) -> Self {Self::default()}
553    
554    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
555        LiveTypeInfo {
556            module_id: LiveModuleId::from_str(&module_path!()).unwrap(),
557            live_type: LiveType::of::<Self>(),
558            live_ignore: true,
559            fields: Vec::new(),
560            type_name: id_lut!(States)
561        }
562    }
563}
564impl LiveApply for Animator {
565    fn apply(&mut self, cx: &mut Cx, apply: &mut Apply, start_index: usize, nodes: &[LiveNode]) -> usize {
566
567        if let Some(file_id) = apply.from.file_id() {
568            self.live_ptr = Some(cx.live_registry.borrow().file_id_index_to_live_ptr(file_id, start_index));
569        }
570        if !nodes[start_index].value.is_structy_type() {
571            cx.apply_error_wrong_type_for_struct(live_error_origin!(), start_index, nodes, live_id!(States));
572            return nodes.skip_node(start_index);
573        }
574        // this just checks it only has instance subprops
575        let mut index = start_index + 1;
576        loop {
577            if nodes[index].value.is_close() {
578                index += 1;
579                break;
580            }
581            if nodes[index].id == live_id!(ignore_missing){
582                self.ignore_missing = nodes[index].value.as_bool().unwrap_or(false);
583            }
584            else if !nodes[index].origin.has_prop_type(LivePropType::Instance) {
585                cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
586            }
587            index = nodes.skip_node(index);
588        }
589        return index;
590    }
591}
592
593impl AnimatorAction {
594    pub fn must_redraw(&self) -> bool {
595        match self {
596            Self::Animating {redraw} => *redraw,
597            _ => false
598        }
599    }
600    pub fn is_animating(&self) -> bool {
601        match self {
602            Self::Animating {..} => true,
603            _ => false
604        }
605    }
606}
607impl Animator {
608    
609    pub fn swap_out_state(&mut self) -> Option<Vec<LiveNode>> {
610        self.state.take()
611    }
612    
613    pub fn swap_in_state(&mut self, state: Vec<LiveNode>) {
614        self.state = Some(state);
615    }
616    
617    pub fn need_init(&self) -> bool {
618        self.state.is_none()
619    }
620    
621    pub fn handle_event(&mut self, cx: &mut Cx, event: &Event) -> AnimatorAction {
622        
623        if let Event::NextFrame(nf) = event {
624            if !nf.set.contains(&self.next_frame) {
625                return AnimatorAction::None
626            }
627            if self.state.is_none() {
628                return AnimatorAction::None
629            }
630            let state_nodes = self.state.as_mut().unwrap();
631            
632            let mut state_index = state_nodes.child_by_name(0, live_id!(state).as_field()).unwrap();
633            let mut stack_depth = 0;
634            let mut ended = true;
635            let mut redraw = false;
636            while state_index < state_nodes.len() {
637                let state_node = &state_nodes[state_index];
638                if state_node.is_array() {
639                    // ok so. lets compute our value and store it in the last slot
640                    let (play_ended, play_redraw) = Self::update_timeline_value(cx, state_index, state_nodes, nf.time);
641                    if !play_ended {
642                        ended = false;
643                    }
644                    if play_redraw {
645                        redraw = true;
646                    }
647                    state_index = state_nodes.skip_node(state_index);
648                }
649                else { // we have to create a timeline ourselves
650                    if state_node.value.is_open() {
651                        stack_depth += 1;
652                        state_index += 1;
653                    }
654                    else if state_node.value.is_close() {
655                        stack_depth -= 1;
656                        state_index += 1;
657                        if stack_depth == 0 {
658                            break;
659                        }
660                    }
661                    else {
662                        state_index = state_nodes.skip_node(state_index);
663                    }
664                }
665            }
666            //println!("{}", state_nodes.to_string(0,100));
667            if !ended {
668                self.next_frame = cx.new_next_frame();
669            }
670            
671            return AnimatorAction::Animating {redraw}
672        }
673        AnimatorAction::None
674    }
675    
676    // this find the last keyframe value from an array node
677    pub fn update_timeline_value(cx: &mut Cx, index: usize, nodes: &mut [LiveNode], ext_time: f64) -> (bool, bool) {
678        // OK so. we have an array with keyframes
679        if nodes[index].is_array() {
680            let mut node_iter = nodes.first_child(index);
681            
682            // compute the animation time from the id
683            let (ended, time, redraw, track_id) = if let Some(id_index) = node_iter {
684                if let LiveValue::Id(track_id) = nodes[id_index].value {
685                    // ok so now we have to find our id in tracks
686                    let track_index = nodes.child_by_path(0, &[live_id!(tracks).as_field(), track_id.as_field()]).unwrap();
687                    
688                    let time_index = if let Some(time_index) = nodes.child_by_name(track_index, live_id!(time).as_field()) {time_index}
689                    else {
690                        return (true, false);
691                    };
692                    
693                    let start_time = match &nodes[time_index].value {
694                        LiveValue::Id(v) => {
695                            assert!(*v == live_id!(void));
696                            nodes[time_index].value = LiveValue::Float64(ext_time);
697                            ext_time
698                        }
699                        LiveValue::Float64(time) => {
700                            *time
701                        }
702                        _ => panic!()
703                    };
704                    
705                    let play = if let Some(play_index) = nodes.child_by_name(track_index, live_id!(play).as_field()) {
706                        Play::new_apply(cx, &mut ApplyFrom::New.into(), play_index, nodes)
707                    }
708                    else {
709                        Play::new(cx)
710                    };
711                    node_iter = nodes.next_child(id_index);
712                    
713                    let (ended, time) = play.get_ended_time(ext_time - start_time);
714                    
715                    if ended { // mark ended step 1
716                        if let Some(index) = nodes.child_by_name(track_index, live_id!(ended).as_field()) {
717                            nodes[index].value = LiveValue::Int64(cx.event_id as i64);
718                        }
719                    }
720                    
721                    let redraw = if let Some(index) = nodes.child_by_name(track_index, live_id!(redraw).as_field()) {
722                        if let LiveValue::Bool(redraw) = &nodes[index].value {
723                            *redraw
724                        }else {false}
725                    }else {false};
726                    
727                    (ended, time, redraw, track_id)
728                }
729                else {panic!()}
730            }
731            else {panic!()};
732            
733            let default_ease = if let Some(ease_index) = nodes.child_by_path(0, &[live_id!(tracks).as_field(), track_id.as_field(), live_id!(ease).as_field()]) {
734                Ease::new_apply(cx, &mut ApplyFrom::New.into(), ease_index, nodes)
735            }
736            else {
737                Ease::Linear
738            };
739            
740            let mut prev_kf: Option<KeyFrame> = None;
741            let mut last_child_index = node_iter.unwrap();
742            while let Some(node_index) = node_iter {
743                if nodes[node_index + 1].is_close() { // at last slot
744                    last_child_index = node_index;
745                    break;
746                }
747                let next_kf = if nodes[node_index].is_value_type() { // we hit a bare value node
748                    if prev_kf.is_some() {
749                        KeyFrame {
750                            ease: default_ease.clone(),
751                            time: 1.0,
752                            value: nodes[node_index].value.clone()
753                        }
754                    }
755                    else {
756                        KeyFrame {
757                            ease: default_ease.clone(),
758                            time: 0.0,
759                            value: nodes[node_index].value.clone()
760                        }
761                    }
762                }
763                else { // try to deserialize a keyframe
764                    let mut kf = KeyFrame::new_apply(cx, &mut ApplyFrom::New.into(), node_index, nodes);
765                    if nodes.child_by_name(node_index, live_id!(ease).as_field()).is_none() {
766                        kf.ease = default_ease.clone();
767                    }
768                    kf
769                };
770                
771                if let Some(prev_kf) = prev_kf {
772                    if time >= prev_kf.time && time <= next_kf.time {
773                        let normalised_time = (time - prev_kf.time) / (next_kf.time - prev_kf.time);
774                        let mix = next_kf.ease.map(normalised_time);
775                        // find last one
776                        while let Some(node_index) = node_iter {
777                            last_child_index = node_index;
778                            node_iter = nodes.next_child(node_index);
779                        }
780                        
781                        let a = &prev_kf.value;
782                        let b = &next_kf.value;
783                        
784                        let new_val = match a {
785                            LiveValue::Int64(va) => match b {
786                                LiveValue::Int64(vb) => {
787                                    LiveValue::Float64(((vb - va) as f64) * mix + *va as f64)
788                                }
789                                LiveValue::Float64(vb) => {
790                                    LiveValue::Float64(((vb - *va as f64) as f64) * mix + *va as f64)
791                                }
792                                _ => LiveValue::None
793                            }
794                            LiveValue::Float64(va) => match b {
795                                LiveValue::Int64(vb) => {
796                                    LiveValue::Float64(((*vb as f64 - va) as f64) * mix + *va as f64)
797                                }
798                                LiveValue::Float64(vb) => {
799                                    LiveValue::Float64(((vb - va)) * mix + *va)
800                                }
801                                _ => LiveValue::None
802                            }
803                            LiveValue::Color(va) => match b {
804                                LiveValue::Color(vb) => {
805                                    LiveValue::Color(Vec4::from_lerp(Vec4::from_u32(*va), Vec4::from_u32(*vb), mix as f32).to_u32())
806                                }
807                                _ => LiveValue::None
808                            }
809                            LiveValue::Vec2(va) => match b {
810                                LiveValue::Vec2(vb) => {
811                                    LiveValue::Vec2(Vec2::from_lerp(*va, *vb, mix as f32))
812                                }
813                                _ => LiveValue::None
814                            }
815                            LiveValue::Vec3(va) => match b {
816                                LiveValue::Vec3(vb) => {
817                                    LiveValue::Vec3(Vec3::from_lerp(*va, *vb, mix as f32))
818                                }
819                                _ => LiveValue::None
820                            }
821                            LiveValue::Id(_) => match b {
822                                LiveValue::Id(vb) => {
823                                    LiveValue::Id(*vb)
824                                }
825                                _ => LiveValue::None
826                            }
827                            _ => LiveValue::None
828                        };
829                        if let LiveValue::None = &new_val {
830                            cx.apply_key_frame_cannot_be_interpolated(live_error_origin!(), index, nodes, a, b);
831                            return (ended, redraw)
832                        }
833                        nodes[last_child_index].value = new_val;
834                        
835                        return (ended, redraw)
836                    }
837                }
838                prev_kf = Some(next_kf);
839                last_child_index = node_index;
840                node_iter = nodes.next_child(node_index);
841            }
842            if let Some(prev_kf) = prev_kf {
843                nodes[last_child_index].value = prev_kf.value
844            }
845            return (ended, redraw)
846        }
847        (false, false)
848    }
849    
850    
851    pub fn last_keyframe_value_from_array(index: usize, nodes: &[LiveNode]) -> Option<usize> {
852        if let Some(index) = nodes.last_child(index) {
853            if nodes[index].value.is_object() {
854                return nodes.child_by_name(index, live_id!(value).as_field());
855            }
856            else {
857                return Some(index)
858            }
859        }
860        return None
861    }
862    
863    pub fn first_keyframe_time_from_array(reader: &LiveNodeReader) -> f64 {
864        if let Some(reader) = reader.first_child() {
865            if reader.is_object() {
866                if let Some(reader) = reader.child_by_name(live_id!(time).as_field()) {
867                    return match &reader.value {
868                        LiveValue::Float64(v) => *v,
869                        LiveValue::Int64(v) => *v as f64,
870                        _ => 1.0
871                    }
872                }
873            }
874        }
875        return 1.0
876    }
877    
878    pub fn is_track_animating(&self, cx: &mut Cx, track_id: &[LiveId;1]) -> bool {
879        if let Some(state) = self.state.as_ref() {
880            if let Some(LiveValue::Int64(ended)) = state.child_value_by_path(0, &[live_id!(tracks).as_field(), track_id[0].as_field(), live_id!(ended).as_field()]) {
881                if *ended == 0 || *ended == cx.event_id as i64 {
882                    return true
883                }
884            }
885        }
886        false
887    }
888    
889    pub fn animator_in_state(&self, cx: &Cx, check_state_pair: &[LiveId; 2]) -> bool {
890        // if we aren't initialized, look if our state id is a default
891        if self.need_init() {
892            if let Some(live_ptr) = self.live_ptr {
893                let live_registry_rc = cx.live_registry.clone();
894                let live_registry = live_registry_rc.borrow();
895                if live_registry.generation_valid(live_ptr) {
896                    let (nodes, index) = live_registry.ptr_to_nodes_index(live_ptr);
897                    if let Some(LiveValue::Id(default_id)) = nodes.child_value_by_path(index, &[check_state_pair[0].as_instance(), live_id!(default).as_field()]) {
898                        return *default_id == check_state_pair[1];
899                    }
900                }
901            }
902        }
903        else {
904            let state = self.state.as_ref().unwrap();
905            if let Some(LiveValue::Id(id)) = &state.child_value_by_path(0, &[live_id!(tracks).as_field(), check_state_pair[0].as_field(), live_id!(state_id).as_field()]) {
906                return *id == check_state_pair[1];
907            }
908        }
909        false
910    }
911    
912    pub fn cut_to_live(&mut self, cx: &mut Cx, state_id: &[LiveId; 2]) {
913        if let Some(live_ptr) = self.live_ptr {
914            let live_registry_rc = cx.live_registry.clone();
915            let live_registry = live_registry_rc.borrow();
916            if live_registry.generation_valid(live_ptr) {
917                // ok now we have to find
918                let (nodes, index) = live_registry.ptr_to_nodes_index(live_ptr);
919                
920                self.init_as_needed(cx, index, nodes);
921                
922                if let Some(index) = nodes.child_by_path(index, &[state_id[0].as_instance(), state_id[1].as_instance()]) {
923                    self.cut_to(cx, state_id, index, nodes);
924                }
925                else {
926                    error!("cut_to_live {}.{} not found", state_id[0], state_id[1]);
927                }
928            }
929            else {
930                error!("cut_to_live generation invalid")
931            }
932        }
933    }
934    
935    // hard cut / initialisate the state to a certain state
936    pub fn cut_to(&mut self, cx: &mut Cx, state_pair: &[LiveId; 2], index: usize, nodes: &[LiveNode]) {
937        
938        if let Some(index) = nodes.child_by_name(index, live_id!(cursor).as_field()) {
939            let cursor = MouseCursor::new_apply(cx, &mut ApplyFrom::New.into(), index, nodes);
940            cx.set_cursor(cursor);
941        }
942        // if we dont have a state object, lets create a template
943        let mut state = self.swap_out_state().unwrap_or(Vec::new());
944        // ok lets fetch the track
945        let track = state_pair[0];
946        
947        if state.len() == 0 {
948            state.push_live(live!{
949                tracks: {},
950                state: {}
951            });
952        }
953        
954        state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field()], live_object!{
955            [track]: {state_id: (state_pair[1]), ended: 1}
956        });
957        
958        let mut path = Vec::new();
959        path.push(live_id!(state).as_field());
960        
961        let mut reader = if let Some(reader) = LiveNodeReader::new(index, nodes).child_by_name(live_id!(apply).as_field()) {
962            reader
963        }
964        else {
965            cx.apply_animate_missing_apply_block(live_error_origin!(), index, nodes);
966            self.swap_in_state(state);
967            return
968        };
969        
970        reader.walk();
971        while !reader.is_eot() {
972            if reader.is_array() {
973                path.push(reader.prop());
974                if let Some(last_value) = Self::last_keyframe_value_from_array(reader.index(), reader.nodes()) {
975                    state.replace_or_insert_first_node_by_path(0, &path, live_array!{
976                        [(track), (reader.nodes()[last_value].value.clone())]
977                    });
978                }
979                path.pop();
980                reader.skip();
981            }
982            else {
983                if reader.is_expr() {
984                    path.push(reader.prop());
985                    state.replace_or_insert_last_node_by_path(0, &path, reader.node_slice());
986                    path.pop();
987                    reader.skip();
988                    continue;
989                }
990                else if reader.is_open() {
991                    path.push(reader.prop());
992                    if reader.is_enum() {
993                        state.replace_or_insert_last_node_by_path(0, &path, reader.node_slice());
994                    }
995                }
996                else if reader.is_close() {
997                    path.pop();
998                }
999                else {
1000                    path.push(reader.prop());
1001                    state.replace_or_insert_first_node_by_path(0, &path, live_array!{
1002                        [(track), (reader.value.clone())]
1003                    });
1004                    path.pop();
1005                }
1006                reader.walk();
1007            }
1008        }
1009        self.swap_in_state(state);
1010        // animate once
1011        //self.next_frame = cx.new_next_frame();
1012    }
1013    
1014    pub fn init_as_needed(&mut self, cx: &mut Cx, index: usize, nodes: &[LiveNode]) {
1015        if self.need_init() {
1016            let mut index = index + 1;
1017            while !nodes[index].is_close() {
1018                let track_id = nodes[index].id;
1019                if let Some(LiveValue::Id(state_id)) = nodes.child_value_by_path(index, &[live_id!(default).as_field()]) {
1020                    if let Some(index) = nodes.child_by_name(index, state_id.as_instance()) {
1021                        self.cut_to(cx, &[track_id, *state_id], index, nodes);
1022                    }
1023                }
1024                index = nodes.skip_node(index);
1025            }
1026        }
1027    }
1028    
1029    pub fn animate_to_live(&mut self, cx: &mut Cx, state_pair: &[LiveId; 2]) {
1030        if let Some(live_ptr) = self.live_ptr {
1031            let live_registry_rc = cx.live_registry.clone();
1032            let live_registry = live_registry_rc.borrow();
1033            if live_registry.generation_valid(live_ptr) {
1034                let (nodes, index) = live_registry.ptr_to_nodes_index(live_ptr);
1035                
1036                self.init_as_needed(cx, index, nodes);
1037                
1038                if let Some(index) = nodes.child_by_path(index, &[state_pair[0].as_instance(), state_pair[1].as_instance()]) {
1039                    self.animate_to(cx, state_pair, index, nodes)
1040                }
1041                else if !self.ignore_missing{
1042                    error!("animate_to_live {}.{} not found", state_pair[0], state_pair[1])
1043                }
1044            }
1045            else {
1046                error!("animate_to_live generation invalid");
1047            }
1048        }
1049    }
1050    
1051    pub fn animate_to(&mut self, cx: &mut Cx, state_pair: &[LiveId; 2], index: usize, nodes: &[LiveNode]) {
1052        
1053        if let Some(index) = nodes.child_by_name(index, live_id!(cursor).as_field()) {
1054            let cursor = MouseCursor::new_apply(cx, &mut ApplyFrom::New.into(), index, nodes);
1055            cx.set_cursor(cursor);
1056        }
1057        
1058        let mut state = self.swap_out_state().unwrap_or(Vec::new());
1059        if state.len() == 0 { // call cut first
1060            //self.cut_to(cx, state_id, index, nodes);
1061            //return
1062            panic!();
1063        }
1064        
1065        let track = state_pair[0];
1066        
1067        // ok we have to look up into state/tracks for our state_id what state we are in right now
1068        let from_id = if let Some(LiveValue::Id(id)) = state.child_value_by_path(0, &[live_id!(tracks).as_field(), track.as_field(), live_id!(state_id).as_field()]) {
1069            *id
1070        }
1071        else {
1072            cx.apply_error_animate_to_unknown_track(live_error_origin!(), index, nodes, track, state_pair[1]);
1073            return
1074        };
1075        
1076        let mut path = Vec::new();
1077        
1078        state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field()], live_object!{
1079            [track]: {state_id: (state_pair[1]), ended: 0, time: void},
1080        });
1081        
1082        // copy in from track
1083        if let Some(index) = nodes.child_by_name(index, live_id!(from).as_field()) {
1084            if let Some(index) = nodes.child_by_name(index, from_id.as_field()) {
1085                state.replace_or_insert_last_node_by_path(
1086                    0,
1087                    &[live_id!(tracks).as_field(), track.as_field(), live_id!(play).as_field()],
1088                    nodes.node_slice(index)
1089                );
1090            }
1091            else if let Some(index) = nodes.child_by_name(index, live_id!(all).as_field()) {
1092                state.replace_or_insert_last_node_by_path(
1093                    0,
1094                    &[live_id!(tracks).as_field(), track.as_field(), live_id!(play).as_field()],
1095                    nodes.node_slice(index)
1096                );
1097            }
1098        }
1099        
1100        // copy ease default if we have one
1101        if let Some(index) = nodes.child_by_name(index, live_id!(ease).as_field()) {
1102            state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field(), live_id!(ease).as_field()], nodes.node_slice(index));
1103        }
1104        
1105        if let Some(index) = nodes.child_by_name(index, live_id!(redraw).as_field()) {
1106            state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field(), live_id!(redraw).as_field()], nodes.node_slice(index));
1107        }
1108        
1109        path.push(live_id!(state).as_field());
1110        
1111        let mut reader = if let Some(reader) = LiveNodeReader::new(index, nodes).child_by_name(live_id!(apply).as_field()) {
1112            reader
1113        }
1114        else {
1115            cx.apply_animate_missing_apply_block(live_error_origin!(), index, nodes);
1116            return
1117        };
1118        reader.walk();
1119        while !reader.is_eot() {
1120            
1121            if reader.is_array() {
1122                path.push(reader.prop());
1123                let (first_index, last_index) = if let Some(state_child) = state.child_by_path(0, &path) {
1124                    if let Some(last_index) = state.last_child(state_child) {
1125                        (state_child + 1, last_index)
1126                    }
1127                    else {panic!()}
1128                }
1129                else {
1130                    cx.apply_error_animation_missing_state(live_error_origin!(), index, nodes, track, state_pair[1], &path);
1131                    path.pop();
1132                    reader.skip();
1133                    continue;
1134                };
1135                // verify we do the right track
1136                if let LiveValue::Id(check_id) = &state[first_index].value {
1137                    if *check_id != track {
1138                        cx.apply_error_wrong_animation_track_used(live_error_origin!(), index, nodes, path.last().unwrap().0, *check_id, track);
1139                        path.pop();
1140                        reader.skip();
1141                        continue;
1142                    }
1143                }
1144                else {
1145                    panic!()
1146                }
1147                let first_time = Self::first_keyframe_time_from_array(&reader);
1148                
1149                let mut timeline = Vec::new();
1150                timeline.open_array(LiveId(0));
1151                timeline.push_id(LiveId(0), track);
1152                if first_time != 0.0 { // insert first key from the last value
1153                    timeline.push_live(state.node_slice(last_index));
1154                }
1155                timeline.push_live(reader.children_slice());
1156                timeline.push_live(state.node_slice(last_index));
1157                timeline.close();
1158                state.replace_or_insert_last_node_by_path(0, &path, &timeline);
1159                
1160                path.pop();
1161                reader.skip();
1162            }
1163            else {
1164                if reader.is_expr() {
1165                    path.push(reader.prop());
1166                    state.replace_or_insert_last_node_by_path(0, &path, reader.node_slice());
1167                    path.pop();
1168                    reader.skip();
1169                    continue;
1170                }
1171                if reader.is_open() {
1172                    path.push(reader.prop());
1173                }
1174                else if reader.is_close() {
1175                    path.pop();
1176                }
1177                else {
1178                    path.push(reader.prop());
1179                    
1180                    let (first_index, last_index) = if let Some(state_child) = state.child_by_path(0, &path) {
1181                        if let Some(last_index) = state.last_child(state_child) {
1182                            (state_child + 1, last_index)
1183                        }
1184                        else {panic!()}
1185                    }
1186                    else {
1187                        // ok so if its missing state, shall we just do an array with 1 value?
1188                        
1189                        cx.apply_error_animation_missing_state(live_error_origin!(), index, nodes, track, state_pair[1], &path);
1190                        path.pop();
1191                        reader.skip();
1192                        continue;
1193                    };
1194                    // verify
1195                    if let LiveValue::Id(check_id) = &state[first_index].value {
1196                        if *check_id != track {
1197                            cx.apply_error_wrong_animation_track_used(live_error_origin!(), index, nodes, path.last().unwrap().0, *check_id, track);
1198                            path.pop();
1199                            reader.skip();
1200                            continue;
1201                        }
1202                    }
1203                    else {
1204                        panic!()
1205                    }
1206                    let mut timeline = Vec::new();
1207                    timeline.open_array(LiveId(0));
1208                    timeline.push_live(live_array!{(track)});
1209                    timeline.push_live(state.node_slice(last_index));
1210                    timeline.push_live(reader.node_slice());
1211                    //timeline.last_mut().unwrap().id = live_id!(0); // clean up property id
1212                    timeline.push_live(state.node_slice(last_index));
1213                    timeline.close();
1214                    state.replace_or_insert_last_node_by_path(0, &path, &timeline);
1215                    path.pop();
1216                }
1217                reader.walk();
1218            }
1219        }
1220        
1221        self.swap_in_state(state);
1222        
1223        self.next_frame = cx.new_next_frame();
1224    }
1225    
1226}