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