use super::Motion;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MotionId {
slot: usize,
generation: u64,
}
impl MotionId {
pub(super) const fn new(slot: usize, generation: u64) -> Self {
Self { slot, generation }
}
#[must_use]
pub const fn slot(self) -> usize {
self.slot
}
#[must_use]
pub const fn generation(self) -> u64 {
self.generation
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PlaybackId {
motion: MotionId,
revision: u64,
}
impl PlaybackId {
pub(super) const fn new(motion: MotionId, revision: u64) -> Self {
Self { motion, revision }
}
#[must_use]
pub const fn motion(self) -> MotionId {
self.motion
}
#[must_use]
pub const fn revision(self) -> u64 {
self.revision
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum InterruptionReason {
Replaced,
Retargeted,
Removed,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum RemovalReason {
Explicit,
Settled,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum MotionEventKind {
Completed,
Canceled,
Interrupted(InterruptionReason),
Removed(RemovalReason),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MotionEvent {
motion: MotionId,
playback: PlaybackId,
kind: MotionEventKind,
}
impl MotionEvent {
pub(super) const fn new(playback: PlaybackId, kind: MotionEventKind) -> Self {
Self {
motion: playback.motion(),
playback,
kind,
}
}
#[must_use]
pub const fn motion(self) -> MotionId {
self.motion
}
#[must_use]
pub const fn playback(self) -> PlaybackId {
self.playback
}
#[must_use]
pub const fn kind(self) -> MotionEventKind {
self.kind
}
#[must_use]
pub fn is_for(self, target: impl MotionEventTarget) -> bool {
target.matches(self)
}
#[must_use]
pub fn is_completed_for(self, target: impl MotionEventTarget) -> bool {
self.kind == MotionEventKind::Completed && target.matches(self)
}
#[must_use]
pub fn is_canceled_for(self, target: impl MotionEventTarget) -> bool {
self.kind == MotionEventKind::Canceled && target.matches(self)
}
}
mod private {
pub trait Sealed {}
impl<T> Sealed for super::Motion<T> {}
impl Sealed for super::MotionId {}
impl Sealed for super::PlaybackId {}
}
pub trait MotionEventTarget: private::Sealed {
#[doc(hidden)]
fn matches(self, event: MotionEvent) -> bool;
}
impl<T> MotionEventTarget for Motion<T> {
fn matches(self, event: MotionEvent) -> bool {
self.id() == event.motion
}
}
impl MotionEventTarget for MotionId {
fn matches(self, event: MotionEvent) -> bool {
self == event.motion
}
}
impl MotionEventTarget for PlaybackId {
fn matches(self, event: MotionEvent) -> bool {
self == event.playback
}
}