numples 1.2.0

Yet another colourful sudoku playing game.
Documentation
use bevy::prelude::*;

const TWEEN_DURATION: f32 = 0.25;

#[derive(Clone, Debug, Component)]
pub enum Tween {
    Value {
        eta: f32,
        x: f32,
        y: f32,
        scale: f32,
        xf: f32,
        yf: f32,
        scalef: f32,
        remove_entity: bool,
    },

    Delete(f32),
}

impl Tween {

    pub fn value() -> ValueBuilder {
        ValueBuilder::default()
            .eta(TWEEN_DURATION)
            .scalef(1.0)
    }

    pub fn delete() -> Self {
        Self::Delete(TWEEN_DURATION)
    }

    pub fn eta(&self) -> f32 {
        match self {
            Self::Value{ eta, .. } => *eta,
            Self::Delete(eta) => *eta,
        }
    }

    pub fn update(&mut self, dt: f32) -> TweenDone {
        let v = 0f32.max(self.eta() - dt);
        let mut delete = [false];
        match self {
            Self::Value {
                eta,
                x,
                y,
                scale,
                xf,
                yf,
                scalef,
                remove_entity,
            } => {
                let f = (*eta - v) / *eta;
                *x += (*xf - *x) * f;
                *y += (*yf - *y) * f;
                *scale += (*scalef - *scale) * f;
                *eta = v;
                delete[0] = *remove_entity;
            }
            Self::Delete(eta) => {
                *eta = v;
                delete[0] = true;
            }
        }
        TweenDone(v == 0.0, delete[0])
    }

    pub fn apply(&self, transform: &mut Transform) {
        if let Self::Value { eta, x, y, scale, .. } = *self {
            let z = if eta == 0.0 { 1.0 } else { transform.scale.z };
            transform.translation.x = x;
            transform.translation.y = y;
            transform.scale = Vec3::splat(scale);
            transform.scale.z = z;  /* don’t mess with Z axis */
        }
    }
}

#[derive(Debug)]
pub struct TweenDone(bool, bool);

impl TweenDone {

    pub fn remove_component(&self) -> bool {
        self.0 && !self.1
    }

    pub fn remove_entity(&self) -> bool {
        self.0 && self.1
    }
}

#[derive(Debug, Default)]
pub struct ValueBuilder {
    eta: f32,
    x: f32,
    y: f32,
    scale: f32,
    xf: f32,
    yf: f32,
    scalef: f32,
    remove_entity: bool,
}

impl ValueBuilder {

    pub fn eta(mut self, eta: f32) -> Self {
        self.eta = eta;
        self
    }

    pub fn xy(mut self, x: f32, y: f32) -> Self {
        self.x = x;
        self.y = y;
        self
    }

    pub fn xyf(mut self, xf: f32, yf: f32) -> Self {
        self.xf = xf;
        self.yf = yf;
        self
    }

    pub fn scale(mut self, scale: f32) -> Self {
        self.scale = scale;
        self
    }

    pub fn scalef(mut self, scalef: f32) -> Self {
        self.scalef = scalef;
        self
    }

    pub fn remove_entity(mut self, remove_entity: bool) -> Self {
        self.remove_entity = remove_entity;
        self
    }
}

impl From<ValueBuilder> for Tween {

    fn from(builder: ValueBuilder) -> Self {
        let ValueBuilder {
            eta,
            x, y,
            scale,
            xf, yf,
            scalef,
            remove_entity,
        } = builder;
        Tween::Value { eta, x, y, scale, xf, yf, scalef, remove_entity }
    }
}