From 766f421a3196371914cce8bf5dc6f4029bfdb545 Mon Sep 17 00:00:00 2001 From: Tangent 128 Date: Sat, 9 Mar 2019 17:02:26 -0500 Subject: [PATCH] Document the lights crate better --- lights/src/gamma.rs | 3 +++ lights/src/lib.rs | 19 +++++++++++++++++++ lights/src/rgb.rs | 5 +++++ 3 files changed, 27 insertions(+) diff --git a/lights/src/gamma.rs b/lights/src/gamma.rs index 475c610..6cecfbf 100644 --- a/lights/src/gamma.rs +++ b/lights/src/gamma.rs @@ -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(pub T); impl Lights for GammaCorrector diff --git a/lights/src/lib.rs b/lights/src/lib.rs index 2665235..eb226ac 100644 --- a/lights/src/lib.rs +++ b/lights/src/lib.rs @@ -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 { + /// Display all pixel from this iterator onto the given strand. + /// Does *not* call [Lights::latch]. fn render_to(&mut self, lights: &mut T); } diff --git a/lights/src/rgb.rs b/lights/src/rgb.rs index 8f8aafc..c585986 100644 --- a/lights/src/rgb.rs +++ b/lights/src/rgb.rs @@ -46,11 +46,16 @@ impl core::ops::Mul 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)