Document the lights crate better

This commit is contained in:
Tangent 128 2019-03-09 17:02:26 -05:00
parent 4f08a72d70
commit 766f421a31
3 changed files with 27 additions and 0 deletions

View file

@ -25,6 +25,7 @@ static GAMMA_LOOKUP: &[u8] = &[
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255
];
/// Convert a perceptually-uniform RGB color into its "real" brightness for display.
#[inline]
pub fn correct(rgb: &Rgb) -> HardwareRgb {
HardwareRgb(
@ -34,6 +35,8 @@ pub fn correct(rgb: &Rgb) -> HardwareRgb {
)
}
/// Wraps a [Lights] implementation that takes [HardwareRgb] pixels,
/// gamma-correcting [Rgb] pixels
pub struct GammaCorrector<T>(pub T);
impl<T> Lights for GammaCorrector<T>

View file

@ -1,3 +1,8 @@
//! 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.
#![no_std]
pub mod gamma;
@ -11,14 +16,28 @@ use core::borrow::Borrow;
#[derive(Clone, Copy)]
pub struct HardwareRgb(pub u8, pub u8, pub u8);
/// Represents a string of lights which can be individually updated in linear order.
pub trait Lights {
/// 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.
type Pixel;
/// 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)
fn render(&mut self, pixel: &Self::Pixel);
/// Indicate that all pixels have been updated, and the next render() should start at the beginning again.
fn latch(&mut self);
}
/// Extension trait to fluently dump an iterator of pixels into a light strand.
pub trait PixelIterator<T: Lights> {
/// Display all pixel from this iterator onto the given strand.
/// Does *not* call [Lights::latch].
fn render_to(&mut self, lights: &mut T);
}

View file

@ -46,11 +46,16 @@ impl core::ops::Mul<u8> for Rgb
}
}
/// Construct an [Rgb] from a monochrome value.
#[inline]
pub fn gray(gray: u8) -> Rgb {
Rgb(gray, gray, gray)
}
/// Interpolate linearly between two colors.
///
/// The "mix" value is RGB to permit blending channels individually,
/// but most often you will probably use [gray] to generate the mix value.
#[inline]
pub fn blend(a: Rgb, b: Rgb, mix: Rgb) -> Rgb {
(a * Rgb(255 - mix.0, 255 - mix.1, 255 - mix.2)) + (b * mix)