Skip to content

Commit dd724b1

Browse files
committed
Fix time calculations on non-chain starting lazy keyframes
This is seen in the pong example. The ball now moves properly.
1 parent 0e82b0d commit dd724b1

File tree

4 files changed

+90
-95
lines changed

4 files changed

+90
-95
lines changed

examples/pokedex/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub fn main() -> iced::Result {
4444
}
4545

4646
#[derive(Debug)]
47+
#[allow(clippy::large_enum_variant)]
4748
enum Pokedex {
4849
Loading,
4950
Loaded { pokemon: Pokemon },

examples/pong/src/main.rs

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,11 @@ impl Application for Pong {
123123
if !self.in_play {
124124
self.in_play = true;
125125
let vertical_bounce = self.rand_vertical_bounce();
126-
let _ = self.timeline.set_chain(vertical_bounce);
126+
let horizontal_bounce = self.rand_horizontal_bounce();
127+
let _ = self
128+
.timeline
129+
.set_chain(vertical_bounce)
130+
.set_chain(horizontal_bounce);
127131
}
128132
self.timeline.set_chain(animation).start();
129133
}
@@ -191,7 +195,7 @@ impl Pong {
191195
.link(keyframes::Space::lazy(Duration::ZERO))
192196
.link(
193197
keyframes::Space::new(Speed::per_secs(100.))
194-
.height(self.window.height as f32 - 100.),
198+
.height(self.window.height - 100.),
195199
),
196200
Direction::Up => cosmic_time::space::Chain::new(PADDLE_LEFT.clone())
197201
.link(keyframes::Space::lazy(Duration::ZERO))
@@ -227,25 +231,51 @@ impl Pong {
227231
}
228232

229233
fn rand_vertical_bounce(&mut self) -> cosmic_time::space::Chain {
230-
if random() {
234+
let speed = 100. * self.rng.gen_range(0.9..1.1);
235+
if self.rng.gen() {
231236
cosmic_time::space::Chain::new(BALL_Y.clone())
232237
.link(keyframes::Space::lazy(Duration::ZERO))
233238
.link(
234-
keyframes::Space::new(Speed::per_secs(105.))
239+
keyframes::Space::new(Speed::per_secs(speed))
235240
.height(self.window.height - self.window.paddle_width),
236241
)
237-
.link(keyframes::Space::new(Speed::per_secs(105.)).height(0.))
238-
.link(keyframes::Space::lazy(Speed::per_secs(105.)))
242+
.link(keyframes::Space::new(Speed::per_secs(speed)).height(0.))
243+
.link(keyframes::Space::lazy(Speed::per_secs(speed)))
239244
.loop_forever()
240245
} else {
241246
cosmic_time::space::Chain::new(BALL_Y.clone())
242247
.link(keyframes::Space::lazy(Duration::ZERO))
243-
.link(keyframes::Space::new(Speed::per_secs(105.)).height(0.))
248+
.link(keyframes::Space::new(Speed::per_secs(speed)).height(0.))
244249
.link(
245-
keyframes::Space::new(Speed::per_secs(105.))
250+
keyframes::Space::new(Speed::per_secs(speed))
246251
.height(self.window.height - self.window.paddle_width),
247252
)
248-
.link(keyframes::Space::lazy(Speed::per_secs(105.)))
253+
.link(keyframes::Space::lazy(Speed::per_secs(speed)))
254+
.loop_forever()
255+
}
256+
}
257+
258+
fn rand_horizontal_bounce(&mut self) -> cosmic_time::space::Chain {
259+
let speed = 100. * self.rng.gen_range(0.9..1.1);
260+
if self.rng.gen() {
261+
cosmic_time::space::Chain::new(BALL_X.clone())
262+
.link(keyframes::Space::lazy(Duration::ZERO))
263+
.link(
264+
keyframes::Space::new(Speed::per_secs(speed))
265+
.width(self.window.width - self.window.paddle_width),
266+
)
267+
.link(keyframes::Space::new(Speed::per_secs(speed)).width(0.))
268+
.link(keyframes::Space::lazy(Speed::per_secs(speed)))
269+
.loop_forever()
270+
} else {
271+
cosmic_time::space::Chain::new(BALL_X.clone())
272+
.link(keyframes::Space::lazy(Duration::ZERO))
273+
.link(keyframes::Space::new(Speed::per_secs(speed)).width(0.))
274+
.link(
275+
keyframes::Space::new(Speed::per_secs(speed))
276+
.width(self.window.width - self.window.paddle_width),
277+
)
278+
.link(keyframes::Space::lazy(Speed::per_secs(speed)))
249279
.loop_forever()
250280
}
251281
}

src/keyframes/space.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ where
6767
Vec<T>: From<Vec<Space>>,
6868
{
6969
fn from(chain: Chain) -> Self {
70-
println!("len is qeal to = {}", chain.links.len());
7170
crate::timeline::Chain::new(chain.id.into(), chain.repeat, chain.links.into())
7271
}
7372
}

src/timeline.rs

Lines changed: 50 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ impl<T: ExactSizeIterator<Item = Option<Frame>> + std::fmt::Debug> Chain<T> {
3535
pub fn new(id: widget::Id, repeat: Repeat, links: Vec<T>) -> Self {
3636
Chain { id, repeat, links }
3737
}
38-
39-
fn into_iter(self) -> impl Iterator<Item = T> {
40-
self.links.into_iter()
41-
}
4238
}
4339

4440
#[derive(Debug, Clone)]
@@ -87,7 +83,6 @@ impl Frame {
8783
}
8884

8985
pub fn to_subframe(self, time: Instant) -> SubFrame {
90-
println!("convert to subframe");
9186
let (value, ease) = match self {
9287
Frame::Eager(_index, _movement_type, value, ease) => (value, ease),
9388
_ => panic!("Call 'to_eager' first"),
@@ -102,18 +97,17 @@ impl Frame {
10297
.get(id, timeline_index)
10398
.map(|i| i.value)
10499
.unwrap_or(default);
105-
println!("lazy check {value} {movement_type:?}");
106100
Frame::Eager(chain_index, movement_type, value, ease)
107101
} else {
108102
*self
109103
}
110104
}
111105

112106
fn get_value(&self) -> f32 {
113-
match self {
114-
Frame::Eager(_, _, value, _) => *value,
115-
_ => panic!("call 'to_eager' first"),
116-
}
107+
match self {
108+
Frame::Eager(_, _, value, _) => *value,
109+
_ => panic!("call 'to_eager' first"),
110+
}
117111
}
118112

119113
pub fn get_duration(self, previous: &Self) -> Duration {
@@ -305,12 +299,11 @@ impl Timeline {
305299
let chain = chain.into();
306300
let id = chain.id;
307301
let repeat = chain.repeat;
308-
let chain: Vec<Vec<Option<Frame>>> = chain.into_iter().map(|m| m.collect()).collect();
302+
let chain: Vec<Vec<Option<Frame>>> = chain.links.into_iter().map(|m| m.collect()).collect();
309303

310304
let _ = self
311305
.pendings
312306
.insert(id, Pending::Chain(repeat, chain, pause));
313-
println!("{:#?}", self.pendings);
314307
self
315308
}
316309

@@ -333,7 +326,6 @@ impl Timeline {
333326
for (id, pending) in pendings.drain() {
334327
match pending {
335328
Pending::Chain(repeat, chain, pause) => {
336-
println!("parsing one animation");
337329
let mut end = now;
338330
// The time that the chain was `set_chain_paused` is not
339331
// necessaritly the same as the atomic pause time used here.
@@ -344,84 +336,57 @@ impl Timeline {
344336
pause
345337
};
346338

347-
let peekable = chain.into_iter().peekable();
339+
let cols = chain[0].len();
340+
let rows = chain.len();
341+
let mut peekable = chain.into_iter().peekable();
342+
let mut specific_chain = Vec::with_capacity(rows);
348343
while let Some(current) = peekable.next() {
349-
let time = end;
350-
if let Some(next) = peekable.peek() {
351-
let mut counter = 0;
352-
if let Some((c_frame, n_frame)) = current.iter().zip(next.iter()).find(|(c_frame, n_frame)| {
353-
counter += 1;
354-
c_frame.is_some() && n_frame.is_some()
355-
}) {
356-
let c = c_frame.expect("Previous check guarentees saftey");
357-
let n = n_frame.expect("Previous check guarentees saftey");
358-
c.to_eager(self, &id, counter);
359-
n.to_eager(self, &id, counter);
360-
let duration = n.get_duration(&c);
361-
end = end + duration;
362-
}
363-
}
364-
365-
current.iter_mut().enumerate().map(|(i, maybe_frame)| {
366-
if let Some(frame) = maybe_frame {
367-
frame.to_eager(self, &id, i);
368-
Some(frame.to_subframe(time))
369-
} else {
370-
None
344+
let time = end;
345+
if let Some(next) = peekable.peek() {
346+
let mut counter = 0;
347+
if let Some((c_frame, n_frame)) =
348+
current.iter().zip(next.iter()).find(|(c_frame, n_frame)| {
349+
counter += 1;
350+
c_frame.is_some() && n_frame.is_some()
351+
})
352+
{
353+
let mut c = c_frame.expect("Previous check guarentees saftey");
354+
let mut n = n_frame.expect("Previous check guarentees saftey");
355+
c.to_eager(self, &id, counter - 1);
356+
n.to_eager(self, &id, counter - 1);
357+
let duration = n.get_duration(&c);
358+
end += duration;
359+
}
371360
}
372-
}).collect();
373-
}
374361

375-
// TODO now transpose that bad boi
376-
377-
// Convert timeline::Chain into VECs of Subframes to optimize redraw loop.
378-
// Also converts Lazy and Speed Controlled keyframes.
379-
/*
380-
let mut value_acc: Option<f32> = None;
381-
let mut time_map: HashMap<usize, Instant> = HashMap::new();
382-
time_map.reserve(tracks.len());
383-
let tracks: Vec<Vec<SubFrame>> = tracks
384-
.iter_mut()
385-
.enumerate()
386-
.map(|(i, track)| {
387-
println!("track len = {}\n{track:?}", track.len());
388-
track
389-
.iter_mut()
390-
.enumerate()
391-
.map(|(j, frame)| {
392-
if j == 0 {
393-
value_acc = None;
394-
}
395-
396-
let index = frame.get_chain_index();
397-
println!("index = {index}");
398-
let current = time_map.get(&index);
362+
let specific_row = current.into_iter().enumerate().fold(
363+
Vec::with_capacity(cols),
364+
|mut acc, (i, maybe_frame)| {
365+
if let Some(mut frame) = maybe_frame {
399366
frame.to_eager(self, &id, i);
400-
401-
let subframe = if let Some(time) = current {
402-
frame.to_subframe(*time)
403-
} else {
404-
let previous = time_map.get(&index.saturating_sub(1));
405-
let duration = frame.get_duration(value_acc);
406-
let time = *previous.unwrap_or(&now) + duration;
407-
println!("time = {time:?}");
408-
409-
end = end.max(time);
410-
let _ = time_map.insert(index, time);
411-
412-
frame.to_subframe(time)
413-
};
414-
415-
value_acc = Some(subframe.value);
416-
subframe
417-
})
418-
.collect()
419-
})
420-
.collect();
421-
*/
367+
acc.push(Some(frame.to_subframe(time)))
368+
} else {
369+
acc.push(None)
370+
}
371+
acc
372+
},
373+
);
374+
specific_chain.push(specific_row);
375+
}
376+
let transposed = specific_chain.into_iter().fold(
377+
vec![Vec::new(); cols],
378+
|mut acc: Vec<Vec<SubFrame>>, row| {
379+
row.into_iter().enumerate().for_each(|(j, maybe_item)| {
380+
if let Some(item) = maybe_item {
381+
acc[j].push(item)
382+
}
383+
});
384+
acc
385+
},
386+
);
422387

423388
let meta = Meta::new(repeat, now, end, end - now, pause);
424-
let _ = self.tracks.insert(id, (meta, chain));
389+
let _ = self.tracks.insert(id, (meta, transposed));
425390
}
426391
Pending::Pause => {
427392
if let Some((meta, _track)) = self.tracks.get_mut(&id) {

0 commit comments

Comments
 (0)