//! 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; pub mod rgb; use core::borrow::Borrow; /// 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, PartialEq)] 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); } impl PixelIterator for I where I::Item: Borrow { #[inline] fn render_to(&mut self, lights: &mut T) { self.for_each(|pixel| lights.render(pixel.borrow())); } } pub fn murmurf(state: &mut u32) -> u32 { *state ^= *state >> 16; *state *= 0x85ebca6b; *state ^= *state >> 13; *state *= 0xc2b2ae35; *state ^= *state >> 16; return *state; }