2019-03-09 17:02:26 -05:00
|
|
|
//! Abstractions for working with individually-addressible LED light strands, such as WS2811 lights.
|
|
|
|
//!
|
|
|
|
//! An output driver implements the [Lights] trait, which you feed pixel values of a compatible type.
|
|
|
|
//! The [rgb] module contains some basic color-manipulation tools, and the [gamma] module supports
|
|
|
|
//! converting perceptual to physical color space for output.
|
2019-03-09 05:02:49 -05:00
|
|
|
#![no_std]
|
|
|
|
|
|
|
|
pub mod gamma;
|
|
|
|
pub mod rgb;
|
|
|
|
|
|
|
|
use core::borrow::Borrow;
|
|
|
|
|
2019-03-09 17:02:12 -05:00
|
|
|
/// An RGB value in physical color space, which should be passed on to an LED for display.
|
|
|
|
/// Not suitable for color operations, since its values won't be perceptually linear.
|
|
|
|
/// See the [rgb] module for the former, and the [gamma] module to convert into this.
|
|
|
|
#[derive(Clone, Copy)]
|
|
|
|
pub struct HardwareRgb(pub u8, pub u8, pub u8);
|
|
|
|
|
2019-03-09 17:02:26 -05:00
|
|
|
/// Represents a string of lights which can be individually updated in linear order.
|
2019-03-09 05:02:49 -05:00
|
|
|
pub trait Lights {
|
2019-03-09 17:02:26 -05:00
|
|
|
/// The type of value each light in the strand can take.
|
|
|
|
///
|
|
|
|
/// Probably either a [rgb::Rgb] (pre-gamma correction) or [HardwareRgb] (post-gamma correction),
|
|
|
|
/// but in theory monochrome LEDs might take a numeric type, or bools for a strand without even brightness control.
|
2019-03-09 05:02:49 -05:00
|
|
|
type Pixel;
|
|
|
|
|
2019-03-09 17:02:26 -05:00
|
|
|
/// Send a pixel value to the next light in the string.
|
|
|
|
///
|
|
|
|
/// Updating a string is likely a time-sensitive operation, so aim to keep this in a tight loop.
|
|
|
|
/// (WS2811 and similar lighting will latch after the data line is quiet long enough)
|
2019-03-09 05:02:49 -05:00
|
|
|
fn render(&mut self, pixel: &Self::Pixel);
|
2019-03-09 17:02:26 -05:00
|
|
|
|
|
|
|
/// Indicate that all pixels have been updated, and the next render() should start at the beginning again.
|
2019-03-09 05:02:49 -05:00
|
|
|
fn latch(&mut self);
|
|
|
|
}
|
|
|
|
|
2019-03-09 17:02:26 -05:00
|
|
|
/// Extension trait to fluently dump an iterator of pixels into a light strand.
|
2019-03-09 05:02:49 -05:00
|
|
|
pub trait PixelIterator<T: Lights> {
|
2019-03-09 17:02:26 -05:00
|
|
|
/// Display all pixel from this iterator onto the given strand.
|
|
|
|
/// Does *not* call [Lights::latch].
|
2019-03-09 05:02:49 -05:00
|
|
|
fn render_to(&mut self, lights: &mut T);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Lights, I: Iterator> PixelIterator<T> for I
|
|
|
|
where I::Item: Borrow<T::Pixel>
|
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
fn render_to(&mut self, lights: &mut T) {
|
|
|
|
self.for_each(|pixel| lights.render(pixel.borrow()));
|
|
|
|
}
|
|
|
|
}
|