use crate::{Clock, Frame};
use gpui_ce_motion::Motion;
use gpui_kit::{App, Window};
use std::{
hash::Hash,
ops::{Deref, DerefMut},
time::Duration,
};
#[derive(Debug)]
pub struct Motions<K> {
inner: gpui_ce_motion::Motions<K>,
clock: Clock,
}
impl<K> Default for Motions<K> {
fn default() -> Self {
Self::new()
}
}
impl<K> Motions<K> {
pub fn new() -> Self {
Self::with_capacity(0)
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
inner: gpui_ce_motion::Motions::with_capacity(capacity),
clock: Clock::default(),
}
}
}
impl<K> Deref for Motions<K> {
type Target = gpui_ce_motion::Motions<K>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<K> DerefMut for Motions<K> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<K: Eq + Hash> Motions<K> {
pub fn frame<const N: usize>(
&mut self,
declarations: [(K, Motion); N],
window: &mut Window,
cx: &App,
) -> [Frame; N] {
let now = self.clock.tick(cx);
let frames = self.sample(declarations, now, cx.reduce_motion());
if frames.iter().any(|frame| frame.is_animating()) {
window.request_animation_frame();
}
frames
}
pub fn frame_one(&mut self, key: K, motion: Motion, window: &mut Window, cx: &App) -> Frame {
let [frame] = self.frame([(key, motion)], window, cx);
frame
}
pub fn sample<const N: usize>(
&mut self,
declarations: [(K, Motion); N],
now: Duration,
reduced_motion: bool,
) -> [Frame; N] {
self.inner
.sample(declarations, now, reduced_motion)
.map(Into::into)
}
pub fn sample_one(
&mut self,
key: K,
motion: Motion,
now: Duration,
reduced_motion: bool,
) -> Frame {
self.inner
.sample_one(key, motion, now, reduced_motion)
.into()
}
}