use core::marker::PhantomData;
use crate::{
color::{ColorCorrection, FromColor},
driver::Driver as DriverTrait,
layout::LayoutForDim,
markers::{Blocking, Dim1d, Dim2d, Dim3d, Set, Unset},
pattern::Pattern as PatternTrait,
};
#[cfg(feature = "async")]
use crate::{driver::DriverAsync as DriverAsyncTrait, markers::Async};
pub struct Control<
const PIXEL_COUNT: usize,
const FRAME_BUFFER_SIZE: usize,
Dim,
Exec,
Layout,
Pattern,
Driver,
> where
Layout: LayoutForDim<Dim>,
Pattern: PatternTrait<Dim, Layout>,
{
dim: PhantomData<Dim>,
exec: PhantomData<Exec>,
layout: PhantomData<Layout>,
pattern: Pattern,
driver: Driver,
brightness: f32,
correction: ColorCorrection,
}
impl<
const PIXEL_COUNT: usize,
const FRAME_BUFFER_SIZE: usize,
Dim,
Exec,
Layout,
Pattern,
Driver,
> Control<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Exec, Layout, Pattern, Driver>
where
Layout: LayoutForDim<Dim>,
Pattern: PatternTrait<Dim, Layout>,
{
pub fn new(pattern: Pattern, driver: Driver) -> Self {
Self {
dim: PhantomData,
exec: PhantomData,
layout: PhantomData,
pattern,
driver,
brightness: 1.0,
correction: ColorCorrection::default(),
}
}
pub fn set_brightness(&mut self, brightness: f32) {
self.brightness = brightness;
}
pub fn set_color_correction(&mut self, correction: ColorCorrection) {
self.correction = correction;
}
}
impl<const PIXEL_COUNT: usize, const FRAME_BUFFER_SIZE: usize, Dim, Layout, Pattern, Driver>
Control<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Blocking, Layout, Pattern, Driver>
where
Layout: LayoutForDim<Dim>,
Pattern: PatternTrait<Dim, Layout>,
Driver: DriverTrait,
Driver::Color: FromColor<Pattern::Color>,
{
pub fn tick(&mut self, time_in_ms: u64) -> Result<(), Driver::Error> {
let pixels = self.pattern.tick(time_in_ms);
self.driver.show::<PIXEL_COUNT, FRAME_BUFFER_SIZE, _, _>(
pixels,
self.brightness,
self.correction,
)
}
}
#[cfg(feature = "async")]
impl<const PIXEL_COUNT: usize, const FRAME_BUFFER_SIZE: usize, Dim, Layout, Pattern, Driver>
Control<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Async, Layout, Pattern, Driver>
where
Layout: LayoutForDim<Dim>,
Pattern: PatternTrait<Dim, Layout>,
Driver: DriverAsyncTrait,
Driver::Color: FromColor<Pattern::Color>,
{
pub async fn tick(&mut self, time_in_ms: u64) -> Result<(), Driver::Error> {
let pixels = self.pattern.tick(time_in_ms);
self.driver
.show::<PIXEL_COUNT, FRAME_BUFFER_SIZE, _, _>(pixels, self.brightness, self.correction)
.await
}
}
pub struct ControlBuilder<
const PIXEL_COUNT: usize,
const FRAME_BUFFER_SIZE: usize,
Dim,
Exec,
Layout,
Pattern,
Driver,
IsFrameBufferSet,
> {
dim: PhantomData<Dim>,
exec: PhantomData<Exec>,
layout: PhantomData<Layout>,
pattern: Pattern,
driver: Driver,
is_frame_buffer_set: PhantomData<IsFrameBufferSet>,
}
impl ControlBuilder<0, 0, (), (), (), (), (), Unset> {
pub fn new_1d() -> ControlBuilder<0, 0, Dim1d, Blocking, (), (), (), Unset> {
ControlBuilder {
dim: PhantomData,
exec: PhantomData,
layout: PhantomData,
pattern: (),
driver: (),
is_frame_buffer_set: PhantomData,
}
}
}
#[cfg(feature = "async")]
impl ControlBuilder<0, 0, (), (), (), (), (), Unset> {
pub fn new_1d_async() -> ControlBuilder<0, 0, Dim1d, Async, (), (), (), Unset> {
ControlBuilder {
dim: PhantomData,
exec: PhantomData,
layout: PhantomData,
pattern: (),
driver: (),
is_frame_buffer_set: PhantomData,
}
}
}
impl ControlBuilder<0, 0, (), (), (), (), (), Unset> {
pub fn new_2d() -> ControlBuilder<0, 0, Dim2d, Blocking, (), (), (), Unset> {
ControlBuilder {
dim: PhantomData,
exec: PhantomData,
layout: PhantomData,
pattern: (),
driver: (),
is_frame_buffer_set: PhantomData,
}
}
}
#[cfg(feature = "async")]
impl ControlBuilder<0, 0, (), (), (), (), (), Unset> {
pub fn new_2d_async() -> ControlBuilder<0, 0, Dim2d, Async, (), (), (), Unset> {
ControlBuilder {
dim: PhantomData,
exec: PhantomData,
layout: PhantomData,
pattern: (),
driver: (),
is_frame_buffer_set: PhantomData,
}
}
}
impl ControlBuilder<0, 0, (), (), (), (), (), Unset> {
pub fn new_3d() -> ControlBuilder<0, 0, Dim3d, Blocking, (), (), (), Unset> {
ControlBuilder {
dim: PhantomData,
exec: PhantomData,
layout: PhantomData,
pattern: (),
driver: (),
is_frame_buffer_set: PhantomData,
}
}
}
#[cfg(feature = "async")]
impl ControlBuilder<0, 0, (), (), (), (), (), Unset> {
pub fn new_3d_async() -> ControlBuilder<0, 0, Dim3d, Async, (), (), (), Unset> {
ControlBuilder {
dim: PhantomData,
exec: PhantomData,
layout: PhantomData,
pattern: (),
driver: (),
is_frame_buffer_set: PhantomData,
}
}
}
impl<const FRAME_BUFFER_SIZE: usize, Dim, Exec, Pattern, Driver, IsFrameBufferSet>
ControlBuilder<0, FRAME_BUFFER_SIZE, Dim, Exec, (), Pattern, Driver, IsFrameBufferSet>
{
pub fn with_layout<Layout, const PIXEL_COUNT: usize>(
self,
) -> ControlBuilder<
PIXEL_COUNT,
FRAME_BUFFER_SIZE,
Dim,
Exec,
Layout,
Pattern,
Driver,
IsFrameBufferSet,
>
where
Layout: LayoutForDim<Dim>,
{
ControlBuilder {
dim: self.dim,
exec: self.exec,
layout: PhantomData,
pattern: self.pattern,
driver: self.driver,
is_frame_buffer_set: self.is_frame_buffer_set,
}
}
}
impl<
const PIXEL_COUNT: usize,
const FRAME_BUFFER_SIZE: usize,
Dim,
Exec,
Layout,
Driver,
IsFrameBufferSet,
>
ControlBuilder<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Exec, Layout, (), Driver, IsFrameBufferSet>
where
Layout: LayoutForDim<Dim>,
{
pub fn with_pattern<Pattern>(
self,
params: Pattern::Params,
) -> ControlBuilder<
PIXEL_COUNT,
FRAME_BUFFER_SIZE,
Dim,
Exec,
Layout,
Pattern,
Driver,
IsFrameBufferSet,
>
where
Pattern: PatternTrait<Dim, Layout>,
{
let pattern = Pattern::new(params);
ControlBuilder {
dim: self.dim,
exec: self.exec,
layout: self.layout,
pattern,
driver: self.driver,
is_frame_buffer_set: self.is_frame_buffer_set,
}
}
}
impl<const PIXEL_COUNT: usize, const FRAME_BUFFER_SIZE: usize, Dim, Layout, Pattern>
ControlBuilder<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Blocking, Layout, Pattern, (), Unset>
{
pub fn with_driver<Driver>(
self,
driver: Driver,
) -> ControlBuilder<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Blocking, Layout, Pattern, Driver, Unset>
where
Driver: DriverTrait,
{
ControlBuilder {
dim: self.dim,
exec: self.exec,
layout: self.layout,
pattern: self.pattern,
driver,
is_frame_buffer_set: self.is_frame_buffer_set,
}
}
}
#[cfg(feature = "async")]
impl<const PIXEL_COUNT: usize, const FRAME_BUFFER_SIZE: usize, Dim, Layout, Pattern>
ControlBuilder<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Async, Layout, Pattern, (), Unset>
{
pub fn with_driver<Driver>(
self,
driver: Driver,
) -> ControlBuilder<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Async, Layout, Pattern, Driver, Unset>
where
Driver: DriverAsyncTrait,
{
ControlBuilder {
dim: self.dim,
exec: self.exec,
layout: self.layout,
pattern: self.pattern,
driver,
is_frame_buffer_set: self.is_frame_buffer_set,
}
}
}
impl<const PIXEL_COUNT: usize, Dim, Layout, Pattern, Driver>
ControlBuilder<PIXEL_COUNT, 0, Dim, Blocking, Layout, Pattern, Driver, Unset>
{
pub fn with_frame_buffer_size<const FRAME_BUFFER_SIZE: usize>(
self,
) -> ControlBuilder<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Blocking, Layout, Pattern, Driver, Set>
where
Driver: DriverTrait,
{
ControlBuilder {
dim: self.dim,
exec: self.exec,
layout: self.layout,
pattern: self.pattern,
driver: self.driver,
is_frame_buffer_set: PhantomData,
}
}
}
#[cfg(feature = "async")]
impl<const PIXEL_COUNT: usize, Dim, Layout, Pattern, Driver>
ControlBuilder<PIXEL_COUNT, 0, Dim, Async, Layout, Pattern, Driver, Unset>
{
pub fn with_frame_buffer_size<const FRAME_BUFFER_SIZE: usize>(
self,
) -> ControlBuilder<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Async, Layout, Pattern, Driver, Set>
where
Driver: DriverAsyncTrait,
{
ControlBuilder {
dim: self.dim,
exec: self.exec,
layout: self.layout,
pattern: self.pattern,
driver: self.driver,
is_frame_buffer_set: PhantomData,
}
}
}
impl<const PIXEL_COUNT: usize, const FRAME_BUFFER_SIZE: usize, Dim, Layout, Pattern, Driver>
ControlBuilder<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Blocking, Layout, Pattern, Driver, Set>
where
Layout: LayoutForDim<Dim>,
Pattern: PatternTrait<Dim, Layout>,
Driver: DriverTrait,
Driver::Color: FromColor<Pattern::Color>,
{
pub fn build(
self,
) -> Control<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Blocking, Layout, Pattern, Driver> {
Control::new(self.pattern, self.driver)
}
}
#[cfg(feature = "async")]
impl<const PIXEL_COUNT: usize, const FRAME_BUFFER_SIZE: usize, Dim, Layout, Pattern, Driver>
ControlBuilder<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Async, Layout, Pattern, Driver, Set>
where
Layout: LayoutForDim<Dim>,
Pattern: PatternTrait<Dim, Layout>,
Driver: DriverAsyncTrait,
Driver::Color: FromColor<Pattern::Color>,
{
pub fn build(
self,
) -> Control<PIXEL_COUNT, FRAME_BUFFER_SIZE, Dim, Async, Layout, Pattern, Driver> {
Control::new(self.pattern, self.driver)
}
}