#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
pub struct IVec2 {
pub x: i32,
pub y: i32,
}
impl IVec2 {
pub const ZERO: Self = Self { x: 0, y: 0 };
#[inline]
pub const fn new(x: i32, y: i32) -> Self {
Self { x, y }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
pub struct Rect {
pub x: i32,
pub y: i32,
pub w: i32,
pub h: i32,
}
impl Rect {
#[inline]
pub const fn new(x: i32, y: i32, w: i32, h: i32) -> Self {
Self { x, y, w, h }
}
#[inline]
pub fn position(self) -> IVec2 {
IVec2::new(self.x, self.y)
}
#[inline]
pub fn size(self) -> IVec2 {
IVec2::new(self.w, self.h)
}
#[inline]
pub fn is_valid(self) -> bool {
self.w >= 0 && self.h >= 0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WindowRef(pub isize);
#[derive(Debug, Clone)]
pub struct WindowTarget {
pub window_ref: WindowRef,
pub final_position: IVec2,
pub final_size: IVec2,
}
impl WindowTarget {
pub fn new(window_ref: WindowRef, final_position: IVec2, final_size: IVec2) -> Self {
Self {
window_ref,
final_position,
final_size,
}
}
pub fn as_rect(&self) -> Rect {
Rect::new(
self.final_position.x,
self.final_position.y,
self.final_size.x,
self.final_size.y,
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AnimationHandle(pub(crate) u64);
#[derive(Debug, Clone, thiserror::Error)]
pub enum AnimationError {
#[error("backend error: {0}")]
Backend(String),
#[error("animation batch must contain at least one window")]
EmptyBatch,
#[error("animator worker thread is not running")]
WorkerDead,
}
pub type Result<T> = std::result::Result<T, AnimationError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ivec2_new_stores_components() {
let v = IVec2::new(3, -7);
assert_eq!(v.x, 3);
assert_eq!(v.y, -7);
}
#[test]
fn rect_position_and_size() {
let r = Rect::new(10, 20, 800, 600);
assert_eq!(r.position(), IVec2::new(10, 20));
assert_eq!(r.size(), IVec2::new(800, 600));
}
#[test]
fn rect_validity() {
assert!(Rect::new(0, 0, 100, 100).is_valid());
assert!(!Rect::new(0, 0, -1, 100).is_valid());
}
#[test]
fn window_target_as_rect() {
let t = WindowTarget::new(WindowRef(42), IVec2::new(50, 60), IVec2::new(400, 300));
assert_eq!(t.as_rect(), Rect::new(50, 60, 400, 300));
}
}