tachyonfx 0.25.0

A ratatui library for creating shader-like effects in TUIs.
Documentation
use alloc::boxed::Box;
use core::fmt::Debug;

use ratatui_core::{buffer::Buffer, layout::Rect};

use crate::{
    features::acquire_ref, CellFilter, ColorSpace, Duration, Effect, EffectTimer, RefCount, Shader,
};

pub type InstanceId = u32;

#[derive(Clone, Debug)]
pub(crate) struct Unique {
    id_context: RefCount<UniqueContext>,
    instance_id: InstanceId,
    fx: Effect,
}

#[derive(Clone, Debug)]
pub(crate) struct UniqueContext {
    pub instance_id: InstanceId,
}

impl UniqueContext {
    pub(crate) fn new(instance_id: InstanceId) -> Self {
        Self { instance_id }
    }
}

impl Unique {
    pub(crate) fn new(id_context: RefCount<UniqueContext>, fx: Effect) -> Self {
        let instance_id = acquire_ref(&id_context).instance_id;
        Self { id_context, instance_id, fx }
    }
}

impl Shader for Unique {
    fn name(&self) -> &'static str {
        "unique"
    }

    fn process(&mut self, duration: Duration, buf: &mut Buffer, area: Rect) -> Option<Duration> {
        self.fx.process(duration, buf, area)
    }

    fn done(&self) -> bool {
        let iid = acquire_ref(&self.id_context).instance_id;
        self.instance_id != iid || self.fx.done()
    }

    fn clone_box(&self) -> Box<dyn Shader> {
        Box::new(self.clone())
    }

    fn area(&self) -> Option<Rect> {
        self.fx.area()
    }

    fn set_area(&mut self, area: Rect) {
        self.fx.set_area(area);
    }

    fn filter(&mut self, filter: CellFilter) {
        self.fx.filter(filter);
    }

    fn reverse(&mut self) {
        self.fx.reverse();
    }

    fn timer_mut(&mut self) -> Option<&mut EffectTimer> {
        None
    }

    fn timer(&self) -> Option<EffectTimer> {
        self.fx.timer()
    }

    fn cell_filter(&self) -> Option<&CellFilter> {
        self.fx.cell_filter()
    }

    fn set_color_space(&mut self, color_space: ColorSpace) {
        self.fx.set_color_space(color_space);
    }

    fn color_space(&self) -> ColorSpace {
        self.fx.color_space()
    }

    fn reset(&mut self) {
        self.fx.reset();
    }
}