From 3a08436f0f67b80a86ee1e60c8f7580238de0a2e Mon Sep 17 00:00:00 2001 From: David Cosby Date: Mon, 11 Nov 2024 15:19:50 -0700 Subject: [PATCH 1/2] swapped out Rgb for a generic color definition. Untested. --- Cargo.toml | 9 +- benches/comet.rs | 4 +- benches/ripples.rs | 4 +- examples/calibration.rs | 18 +- examples/comet.rs | 2 +- examples/drivers/comet.rs | 11 +- examples/drivers/ripples.rs | 13 +- examples/drivers/scan.rs | 17 +- examples/drivers/warpspeed.rs | 11 +- examples/resources/tui.rs | 17 +- examples/ripples.rs | 5 +- examples/scan.rs | 2 +- examples/warpspeed.rs | 7 +- src/color.rs | 465 +--------------------------- src/driver/mod.rs | 64 ++-- src/led.rs | 35 +-- src/spatial_led/directional.rs | 20 +- src/spatial_led/filter.rs | 16 +- src/spatial_led/indexical.rs | 24 +- src/spatial_led/maps_and_filters.rs | 28 +- src/spatial_led/meta.rs | 70 +---- src/spatial_led/mod.rs | 6 +- src/spatial_led/positional.rs | 44 +-- src/spatial_led/segmental.rs | 36 +-- 24 files changed, 205 insertions(+), 723 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a7a2557..1fb52fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,14 +14,9 @@ exclude = ["*.gif", "*.cast"] default = ["drivers", "scheduler"] drivers = ["compact_str", "sled_driver_macros"] scheduler = ["spin_sleep"] -named_colors = [] [dependencies] glam = { version = "0.29" } -palette = { version = "0.7", default-features = false, features = [ - "std", - "approx", -] } smallvec = "1.13" compact_str = { version = "0.8", optional = true } sled_driver_macros = { version = "0.1.2", optional = true } @@ -31,6 +26,10 @@ spin_sleep = { version = "1.2", optional = true } criterion = { version = "0.5", default-features = false, features = [ "cargo_bench_support", ] } +palette = { version = "0.7", default-features = false, features = [ + "std", + "approx", +] } ratatui = { version = "0.29", features = ["crossterm"] } crossterm = { version = "0.28" } rand = { version = "0.8", default-features = false, features = [ diff --git a/benches/comet.rs b/benches/comet.rs index 4ea13e2..5856bcb 100644 --- a/benches/comet.rs +++ b/benches/comet.rs @@ -13,14 +13,14 @@ fn trail(c: &mut Criterion) { let simulated_hz = 144.0; let total_steps = (simulated_duration * simulated_hz) as usize; let timestep = Duration::from_secs_f32(1.0 / simulated_hz); - let mut r = 0; + let mut r = 0.0; c.bench_function("comet", |b| { b.iter(|| { for _ in 0..total_steps { driver.step_by(timestep); - let mut colors = driver.colors_coerced::(); + let mut colors = driver.colors(); r = colors.next().unwrap().red; } }); diff --git a/benches/ripples.rs b/benches/ripples.rs index 3aaf4b9..55b914f 100644 --- a/benches/ripples.rs +++ b/benches/ripples.rs @@ -13,13 +13,13 @@ fn ripples(c: &mut Criterion) { let simulated_hz = 144.0; let total_steps = (simulated_duration * simulated_hz) as usize; let timestep = Duration::from_secs_f32(1.0 / simulated_hz); - let mut r = 0; + let mut r = 0.0; c.bench_function("ripples", |b| { b.iter(|| { for _ in 0..total_steps { driver.step_by(timestep); - let mut colors = driver.colors_coerced::(); + let mut colors = driver.colors(); r = colors.next().unwrap().red; } }); diff --git a/examples/calibration.rs b/examples/calibration.rs index a435a63..7c83c01 100644 --- a/examples/calibration.rs +++ b/examples/calibration.rs @@ -1,20 +1,22 @@ mod resources; use glam::Vec2; +use palette::rgb::Srgb; use resources::tui::SledTerminalDisplay; -use spatial_led::{color::Rgb, Sled, SledError}; +use spatial_led::{Sled, SledError}; + fn main() -> Result<(), SledError> { let mut sled = Sled::new("./examples/resources/complex_room.yap")?; let mut display = SledTerminalDisplay::start("Calibration", sled.domain()); - sled.set_all(Rgb::new(0.1, 0.1, 0.1)); - sled.set_vertices(Rgb::new(0.75, 0.75, 0.75)); - sled.set_at_dir(Vec2::new(1.0, 0.0), Rgb::new(1.0, 0.0, 0.0)); - sled.set_at_dir(Vec2::new(-1.0, 0.0), Rgb::new(0.5, 0.0, 0.0)); - sled.set_at_dir(Vec2::new(0.0, 1.0), Rgb::new(0.0, 1.0, 0.0)); - sled.set_at_dir(Vec2::new(0.0, -1.0), Rgb::new(0.0, 0.5, 0.0)); + sled.set_all(Srgb::new(0.1, 0.1, 0.1)); + sled.set_vertices(Srgb::new(0.75, 0.75, 0.75)); + sled.set_at_dir(Vec2::new(1.0, 0.0), Srgb::new(1.0, 0.0, 0.0)); + sled.set_at_dir(Vec2::new(-1.0, 0.0), Srgb::new(0.5, 0.0, 0.0)); + sled.set_at_dir(Vec2::new(0.0, 1.0), Srgb::new(0.0, 1.0, 0.0)); + sled.set_at_dir(Vec2::new(0.0, -1.0), Srgb::new(0.0, 0.5, 0.0)); - display.set_leds(sled.colors_and_positions_coerced()); + display.set_leds(sled.colors_and_positions()); display.refresh().unwrap(); Ok(()) } diff --git a/examples/comet.rs b/examples/comet.rs index 5bd2d62..00c06e3 100644 --- a/examples/comet.rs +++ b/examples/comet.rs @@ -15,7 +15,7 @@ fn main() { let mut scheduler = Scheduler::new(500.0); scheduler.loop_until_err(|| { driver.step(); - display.set_leds(driver.colors_and_positions_coerced()); + display.set_leds(driver.colors_and_positions()); display.refresh()?; Ok(()) }); diff --git a/examples/drivers/comet.rs b/examples/drivers/comet.rs index 6338629..640e448 100644 --- a/examples/drivers/comet.rs +++ b/examples/drivers/comet.rs @@ -1,7 +1,8 @@ -use spatial_led::driver_macros::*; use spatial_led::driver::{Driver, TimeInfo}; -use spatial_led::SledResult; -use spatial_led::{color::Rgb, Sled}; +use spatial_led::driver_macros::*; +use spatial_led::{Sled, SledResult}; + +use palette::rgb::Rgb; use std::f32::consts::TAU; const INV_TAU: f32 = 1.0 / TAU; @@ -17,14 +18,14 @@ const BLUE: Rgb = Rgb::new(0.4, 0.51, 0.93); const TRAIL_RADIUS: f32 = 1.2; #[allow(dead_code)] -pub fn build_driver() -> Driver { +pub fn build_driver() -> Driver { let mut driver = Driver::new(); driver.set_draw_commands(draw); driver } #[draw_commands] -fn draw(sled: &mut Sled, time_info: &TimeInfo) -> SledResult { +fn draw(sled: &mut Sled, time_info: &TimeInfo) -> SledResult { let elapsed = time_info.elapsed.as_secs_f32(); let inner_time_scale = elapsed / GREEN_RADIUS; diff --git a/examples/drivers/ripples.rs b/examples/drivers/ripples.rs index 449c62c..9d5a28c 100644 --- a/examples/drivers/ripples.rs +++ b/examples/drivers/ripples.rs @@ -2,7 +2,8 @@ use spatial_led::driver_macros::*; use rand::Rng; use spatial_led::driver::{BufferContainer, Driver, TimeInfo}; use spatial_led::SledResult; -use spatial_led::{color::Rgb, Sled, Vec2}; +use spatial_led::{Sled, Vec2}; +use palette::rgb::Rgb; use std::ops::Range; const MAX_RIPPLES: usize = 12; @@ -11,7 +12,7 @@ const FEATHERING: f32 = 0.15; const INV_F: f32 = 1.0 / FEATHERING; #[allow(dead_code)] -pub fn build_driver() -> Driver { +pub fn build_driver() -> Driver { let mut driver = Driver::new(); driver.set_startup_commands(startup); @@ -21,7 +22,7 @@ pub fn build_driver() -> Driver { } #[startup_commands] -fn startup(sled: &mut Sled, buffers: &mut BufferContainer) -> SledResult { +fn startup(sled: &mut Sled, buffers: &mut BufferContainer) -> SledResult { let sled_bounds = sled.domain(); let radii = buffers.create_buffer("radii"); @@ -52,7 +53,7 @@ fn startup(sled: &mut Sled, buffers: &mut BufferContainer) -> SledResult { } #[compute_commands] -fn compute(sled: &Sled, buffers: &mut BufferContainer, time_info: &TimeInfo) -> SledResult { +fn compute(sled: &Sled, buffers: &mut BufferContainer, time_info: &TimeInfo) -> SledResult { let delta = time_info.delta.as_secs_f32(); let bounds = sled.domain(); for i in 0..MAX_RIPPLES { @@ -86,7 +87,7 @@ fn rand_init_radius() -> f32 { } #[draw_commands] -fn draw(sled: &mut Sled, buffers: &BufferContainer) -> SledResult { +fn draw(sled: &mut Sled, buffers: &BufferContainer) -> SledResult { sled.set_all(Rgb::new(0.0, 0.0, 0.0)); let colors = buffers.get_buffer("colors")?; let positions = buffers.get_buffer("positions")?; @@ -105,7 +106,7 @@ fn draw(sled: &mut Sled, buffers: &BufferContainer) -> SledResult { Ok(()) } -fn draw_ripple_at(sled: &mut Sled, pos: Vec2, radius: f32, color: Rgb) { +fn draw_ripple_at(sled: &mut Sled, pos: Vec2, radius: f32, color: Rgb) { let inv_radius = 1.0 / radius; sled.modulate_within_dist_from(radius + FEATHERING, pos, |led| { let r = led.position().distance(pos); diff --git a/examples/drivers/scan.rs b/examples/drivers/scan.rs index 4a1ce7b..fcbfcbb 100644 --- a/examples/drivers/scan.rs +++ b/examples/drivers/scan.rs @@ -1,4 +1,5 @@ use palette::chromatic_adaptation::AdaptInto; +use palette::rgb::Rgb; use rand::Rng; use std::f32::consts::{PI, TAU}; use std::time::Duration; @@ -7,12 +8,12 @@ use glam::Vec2; use spatial_led::driver::{Driver, TimeInfo}; use spatial_led::driver_macros::*; use spatial_led::BufferContainer; -use spatial_led::{color::Rgb, Sled, SledResult}; +use spatial_led::{Sled, SledResult}; const SCAN_DURATION: f32 = 4.0; #[allow(dead_code)] -pub fn build_driver() -> Driver { +pub fn build_driver() -> Driver { let mut driver = Driver::new(); driver.set_startup_commands(startup); driver.set_compute_commands(compute); @@ -21,7 +22,7 @@ pub fn build_driver() -> Driver { driver } -fn rand_endpoints(sled: &Sled) -> (Vec2, Vec2) { +fn rand_endpoints(sled: &Sled) -> (Vec2, Vec2) { let domain = sled.domain(); let r = (domain.end - domain.start).length() * 0.6; let c = sled.center_point(); @@ -35,7 +36,7 @@ fn rand_endpoints(sled: &Sled) -> (Vec2, Vec2) { (start, end) } -fn start_new_scan(sled: &Sled, buffers: &mut BufferContainer, now: Duration) { +fn start_new_scan(sled: &Sled, buffers: &mut BufferContainer, now: Duration) { let t_buffer = buffers.create_buffer::("times"); t_buffer.push(now); @@ -50,13 +51,13 @@ fn start_new_scan(sled: &Sled, buffers: &mut BufferContainer, now: Duration) { } #[startup_commands] -fn startup(sled: &mut Sled, buffers: &mut BufferContainer) -> SledResult { +fn startup(sled: &mut Sled, buffers: &mut BufferContainer) -> SledResult { start_new_scan(sled, buffers, Duration::from_secs(0)); Ok(()) } #[compute_commands] -fn compute(sled: &Sled, buffers: &mut BufferContainer, time_info: &TimeInfo) -> SledResult { +fn compute(sled: &Sled, buffers: &mut BufferContainer, time_info: &TimeInfo) -> SledResult { let t_buffer = buffers.get_buffer::("times")?; let now = time_info.elapsed; let end_t = t_buffer[1]; @@ -76,7 +77,7 @@ fn compute(sled: &Sled, buffers: &mut BufferContainer, time_info: &TimeInfo) -> } #[draw_commands] -fn draw(sled: &mut Sled, buffers: &BufferContainer, time_info: &TimeInfo) -> SledResult { +fn draw(sled: &mut Sled, buffers: &BufferContainer, time_info: &TimeInfo) -> SledResult { // gradual fade to black let theta = ((time_info.elapsed.as_secs_f32() / 12.5).cos() + 1.0) * 180.0; sled.map(|led| led.color * (1.0 - time_info.delta.as_secs_f32() * 2.0)); @@ -86,7 +87,7 @@ fn draw(sled: &mut Sled, buffers: &BufferContainer, time_info: &TimeInfo) -> Sle let scan_direction = v_buffer[3]; // println!("{}", scan_center); - let c: Rgb = spatial_led::color::oklch::Oklch::new(0.99, 0.3, theta).adapt_into(); + let c: Rgb = palette::oklch::Oklch::new(0.99, 0.3, theta).adapt_into(); sled.set_at_dir_from(scan_direction.perp(), scan_center, c); sled.set_at_dir_from(-scan_direction.perp(), scan_center, c); diff --git a/examples/drivers/warpspeed.rs b/examples/drivers/warpspeed.rs index 03f9405..7b853b4 100644 --- a/examples/drivers/warpspeed.rs +++ b/examples/drivers/warpspeed.rs @@ -2,14 +2,15 @@ use spatial_led::driver_macros::*; use rand::Rng; use spatial_led::driver::{BufferContainer, Driver, TimeInfo}; use spatial_led::SledResult; -use spatial_led::{color::Rgb, Sled, Vec2}; +use spatial_led::{Sled, Vec2}; +use palette::rgb::Rgb; const NUM_STARS: usize = 5000; const VELOCITY: f32 = 6.0; const DIRECTION: Vec2 = Vec2::new(0.7071, -0.7071); #[allow(dead_code)] -pub fn build_driver() -> Driver { +pub fn build_driver() -> Driver { let mut driver = Driver::new(); driver.set_startup_commands(startup); @@ -20,7 +21,7 @@ pub fn build_driver() -> Driver { } #[startup_commands] -fn startup(sled: &mut Sled, buffers: &mut BufferContainer) -> SledResult { +fn startup(sled: &mut Sled, buffers: &mut BufferContainer) -> SledResult { let stars = buffers.create_buffer::("stars"); let center = sled.center_point(); let mut rng = rand::thread_rng(); @@ -58,7 +59,7 @@ fn startup(sled: &mut Sled, buffers: &mut BufferContainer) -> SledResult { } #[compute_commands] -fn compute(sled: &Sled, buffers: &mut BufferContainer, time_info: &TimeInfo) -> SledResult { +fn compute(sled: &Sled, buffers: &mut BufferContainer, time_info: &TimeInfo) -> SledResult { let mut rng = rand::thread_rng(); let delta = time_info.delta.as_secs_f32(); let stars = buffers.get_buffer_mut::("stars")?; @@ -89,7 +90,7 @@ fn compute(sled: &Sled, buffers: &mut BufferContainer, time_info: &TimeInfo) -> } #[draw_commands] -fn draw(sled: &mut Sled, buffers: &BufferContainer, time_info: &TimeInfo) -> SledResult { +fn draw(sled: &mut Sled, buffers: &BufferContainer, time_info: &TimeInfo) -> SledResult { let stars = buffers.get_buffer::("stars")?; let center = sled.center_point(); let delta = time_info.delta.as_secs_f32(); diff --git a/examples/resources/tui.rs b/examples/resources/tui.rs index d7a9d9d..c8042c6 100644 --- a/examples/resources/tui.rs +++ b/examples/resources/tui.rs @@ -12,7 +12,8 @@ use ratatui::{ }, }; -use spatial_led::{color::Srgb, Sled, Vec2}; +use palette::rgb::Srgb; +use spatial_led::{Sled, Vec2}; use std::{ io::{self, stdout, Error, ErrorKind, Stdout}, @@ -21,7 +22,7 @@ use std::{ pub struct SledTerminalDisplay { title: String, - leds: Vec<(Srgb, Vec2)>, + leds: Vec<(Srgb, Vec2)>, on_quit: Box, quit: bool, x_bounds: [f64; 2], @@ -59,7 +60,7 @@ impl SledTerminalDisplay { self.title = title; } - pub fn set_leds(&mut self, leds: impl Iterator, Vec2)>) { + pub fn set_leds(&mut self, leds: impl Iterator) { // not ideal, look for a workaround later self.leds = leds.collect() } @@ -109,13 +110,17 @@ impl Drop for SledTerminalDisplay { } } -fn draw_led(ctx: &mut Context, led: &(Srgb, Vec2)) { +fn draw_led(ctx: &mut Context, led: &(Srgb, Vec2)) { let (col, pos) = led; ctx.draw(&Circle { x: pos.x as f64, y: pos.y as f64, radius: 0.0, - color: Color::Rgb(col.red, col.green, col.blue), + color: Color::Rgb( + (col.red / 255.0) as u8, + (col.green / 255.0) as u8, + (col.blue / 255.0) as u8, + ), }); } @@ -136,7 +141,7 @@ fn main() -> io::Result<()> { let sled = Sled::new("./examples/resources/config.yap").unwrap(); let mut display = SledTerminalDisplay::start("Sled Visualizer", sled.domain()); - display.set_leds(sled.colors_and_positions_coerced()); + display.set_leds(sled.colors_and_positions()); display.refresh()?; Ok(()) diff --git a/examples/ripples.rs b/examples/ripples.rs index 6be14f5..ae84827 100644 --- a/examples/ripples.rs +++ b/examples/ripples.rs @@ -2,12 +2,13 @@ mod drivers; use drivers::ripples; mod resources; +use palette::rgb::Rgb; use resources::tui::SledTerminalDisplay; use spatial_led::{scheduler::Scheduler, Sled}; fn main() { - let sled = Sled::new("./examples/resources/complex_room.yap").unwrap(); + let sled = Sled::::new("./examples/resources/complex_room.yap").unwrap(); let mut display = SledTerminalDisplay::start("Ripples", sled.domain()); let mut driver = ripples::build_driver(); driver.mount(sled); @@ -15,7 +16,7 @@ fn main() { let mut scheduler = Scheduler::new(500.0); scheduler.loop_until_err(|| { driver.step(); - display.set_leds(driver.colors_and_positions_coerced()); + display.set_leds(driver.colors_and_positions()); display.refresh()?; Ok(()) }); diff --git a/examples/scan.rs b/examples/scan.rs index 988fe5e..7e08afe 100644 --- a/examples/scan.rs +++ b/examples/scan.rs @@ -15,7 +15,7 @@ fn main() { let mut scheduler = Scheduler::new(500.0); scheduler.loop_until_err(|| { driver.step(); - display.set_leds(driver.colors_and_positions_coerced()); + display.set_leds(driver.colors_and_positions()); display.refresh()?; Ok(()) }); diff --git a/examples/warpspeed.rs b/examples/warpspeed.rs index ac0eb6d..2377f72 100644 --- a/examples/warpspeed.rs +++ b/examples/warpspeed.rs @@ -4,10 +4,11 @@ use drivers::warpspeed; mod resources; use resources::tui::SledTerminalDisplay; -use spatial_led::{color::Rgb, scheduler::Scheduler, Sled}; +use spatial_led::{scheduler::Scheduler, Sled}; +use palette::rgb::Rgb; fn main() { - let sled = Sled::new("./examples/resources/complex_room.yap").unwrap(); + let sled = Sled::::new("./examples/resources/complex_room.yap").unwrap(); let mut display = SledTerminalDisplay::start("Warpspeed", sled.domain()); let mut driver = warpspeed::build_driver(); driver.mount(sled); @@ -22,7 +23,7 @@ fn main() { let mut scheduler = Scheduler::new(500.0); scheduler.loop_until_err(|| { driver.step(); - display.set_leds(driver.colors_and_positions_coerced()); + display.set_leds(driver.colors_and_positions()); display.refresh().unwrap(); Ok(()) }); diff --git a/src/color.rs b/src/color.rs index 9a1831a..2214b03 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,464 +1,5 @@ -/// Exposes [palette](https://crates.io/crates/palette)'s color management tools and brings the Rgb struct forward so as to be easier to import/qualify in Sled projects. -pub use palette::rgb::Rgb; -pub use palette::*; +use std::fmt::Debug; -#[cfg(feature = "named_colors")] -pub mod consts { - //! A collection of named color constants. Can be toggled with the `named_colors` Cargo feature. - //! - //! Adapted from palette's [named](https://docs.rs/palette/0.7.3/palette/named/index.html) module - //! but expressed as 32-bit rgb instead of 8-bit for better compatability with sled. - //! - //! Colors are taken from the [SVG keyword - //! colors](https://www.w3.org/TR/SVG11/types.html#ColorKeywords) (same as in - //! CSS3) and they can be used as if they were pixel values: - //! - //! ```rust, ignore - //! use spatial_led::color::consts; - //! // -snip- - //! sled.set_all(consts::BLACK); - //! ``` +pub trait ColorType: Debug + Default + Copy {} - use super::Rgb; - const D: f32 = 1.0 / 255.0; - ///
- pub const ALICEBLUE: Rgb = Rgb::new(240.0 * D, 248.0 * D, 255.0 * D); - - ///
- pub const ANTIQUEWHITE: Rgb = Rgb::new(250.0 * D, 235.0 * D, 215.0 * D); - - ///
- pub const AQUA: Rgb = Rgb::new(0.0 * D, 255.0 * D, 255.0 * D); - - ///
- pub const AQUAMARINE: Rgb = Rgb::new(127.0 * D, 255.0 * D, 212.0 * D); - - ///
- pub const AZURE: Rgb = Rgb::new(240.0 * D, 255.0 * D, 255.0 * D); - - ///
- pub const BEIGE: Rgb = Rgb::new(245.0 * D, 245.0 * D, 220.0 * D); - - ///
- pub const BISQUE: Rgb = Rgb::new(255.0 * D, 228.0 * D, 196.0 * D); - - ///
- pub const BLACK: Rgb = Rgb::new(0.0 * D, 0.0 * D, 0.0 * D); - - ///
- pub const BLANCHEDALMOND: Rgb = Rgb::new(255.0 * D, 235.0 * D, 205.0 * D); - - ///
- pub const BLUE: Rgb = Rgb::new(0.0 * D, 0.0 * D, 255.0 * D); - - ///
- pub const BLUEVIOLET: Rgb = Rgb::new(138.0 * D, 43.0 * D, 226.0 * D); - - ///
- pub const BROWN: Rgb = Rgb::new(165.0 * D, 42.0 * D, 42.0 * D); - - ///
- pub const BURLYWOOD: Rgb = Rgb::new(222.0 * D, 184.0 * D, 135.0 * D); - - ///
- pub const CADETBLUE: Rgb = Rgb::new(95.0 * D, 158.0 * D, 160.0 * D); - - ///
- pub const CHARTREUSE: Rgb = Rgb::new(127.0 * D, 255.0 * D, 0.0 * D); - - ///
- pub const CHOCOLATE: Rgb = Rgb::new(210.0 * D, 105.0 * D, 30.0 * D); - - ///
- pub const CORAL: Rgb = Rgb::new(255.0 * D, 127.0 * D, 80.0 * D); - - ///
- pub const CORNFLOWERBLUE: Rgb = Rgb::new(100.0 * D, 149.0 * D, 237.0 * D); - - ///
- pub const CORNSILK: Rgb = Rgb::new(255.0 * D, 248.0 * D, 220.0 * D); - - ///
- pub const CRIMSON: Rgb = Rgb::new(220.0 * D, 20.0 * D, 60.0 * D); - - ///
- pub const CYAN: Rgb = Rgb::new(0.0 * D, 255.0 * D, 255.0 * D); - - ///
- pub const DARKBLUE: Rgb = Rgb::new(0.0 * D, 0.0 * D, 139.0 * D); - - ///
- pub const DARKCYAN: Rgb = Rgb::new(0.0 * D, 139.0 * D, 139.0 * D); - - ///
- pub const DARKGOLDENROD: Rgb = Rgb::new(184.0 * D, 134.0 * D, 11.0 * D); - - ///
- pub const DARKGRAY: Rgb = Rgb::new(169.0 * D, 169.0 * D, 169.0 * D); - - ///
- pub const DARKGREEN: Rgb = Rgb::new(0.0 * D, 100.0 * D, 0.0 * D); - - ///
- pub const DARKGREY: Rgb = Rgb::new(169.0 * D, 169.0 * D, 169.0 * D); - - ///
- pub const DARKKHAKI: Rgb = Rgb::new(189.0 * D, 183.0 * D, 107.0 * D); - - ///
- pub const DARKMAGENTA: Rgb = Rgb::new(139.0 * D, 0.0 * D, 139.0 * D); - - ///
- pub const DARKOLIVEGREEN: Rgb = Rgb::new(85.0 * D, 107.0 * D, 47.0 * D); - - ///
- pub const DARKORANGE: Rgb = Rgb::new(255.0 * D, 140.0 * D, 0.0 * D); - - ///
- pub const DARKORCHID: Rgb = Rgb::new(153.0 * D, 50.0 * D, 204.0 * D); - - ///
- pub const DARKRED: Rgb = Rgb::new(139.0 * D, 0.0 * D, 0.0 * D); - - ///
- pub const DARKSALMON: Rgb = Rgb::new(233.0 * D, 150.0 * D, 122.0 * D); - - ///
- pub const DARKSEAGREEN: Rgb = Rgb::new(143.0 * D, 188.0 * D, 143.0 * D); - - ///
- pub const DARKSLATEBLUE: Rgb = Rgb::new(72.0 * D, 61.0 * D, 139.0 * D); - - ///
- pub const DARKSLATEGRAY: Rgb = Rgb::new(47.0 * D, 79.0 * D, 79.0 * D); - - ///
- pub const DARKSLATEGREY: Rgb = Rgb::new(47.0 * D, 79.0 * D, 79.0 * D); - - ///
- pub const DARKTURQUOISE: Rgb = Rgb::new(0.0 * D, 206.0 * D, 209.0 * D); - - ///
- pub const DARKVIOLET: Rgb = Rgb::new(148.0 * D, 0.0 * D, 211.0 * D); - - ///
- pub const DEEPPINK: Rgb = Rgb::new(255.0 * D, 20.0 * D, 147.0 * D); - - ///
- pub const DEEPSKYBLUE: Rgb = Rgb::new(0.0 * D, 191.0 * D, 255.0 * D); - - ///
- pub const DIMGRAY: Rgb = Rgb::new(105.0 * D, 105.0 * D, 105.0 * D); - - ///
- pub const DIMGREY: Rgb = Rgb::new(105.0 * D, 105.0 * D, 105.0 * D); - - ///
- pub const DODGERBLUE: Rgb = Rgb::new(30.0 * D, 144.0 * D, 255.0 * D); - - ///
- pub const FIREBRICK: Rgb = Rgb::new(178.0 * D, 34.0 * D, 34.0 * D); - - ///
- pub const FLORALWHITE: Rgb = Rgb::new(255.0 * D, 250.0 * D, 240.0 * D); - - ///
- pub const FORESTGREEN: Rgb = Rgb::new(34.0 * D, 139.0 * D, 34.0 * D); - - ///
- pub const FUCHSIA: Rgb = Rgb::new(255.0 * D, 0.0 * D, 255.0 * D); - - ///
- pub const GAINSBORO: Rgb = Rgb::new(220.0 * D, 220.0 * D, 220.0 * D); - - ///
- pub const GHOSTWHITE: Rgb = Rgb::new(248.0 * D, 248.0 * D, 255.0 * D); - - ///
- pub const GOLD: Rgb = Rgb::new(255.0 * D, 215.0 * D, 0.0 * D); - - ///
- pub const GOLDENROD: Rgb = Rgb::new(218.0 * D, 165.0 * D, 32.0 * D); - - ///
- pub const GRAY: Rgb = Rgb::new(128.0 * D, 128.0 * D, 128.0 * D); - - ///
- pub const GREY: Rgb = Rgb::new(128.0 * D, 128.0 * D, 128.0 * D); - - ///
- pub const GREEN: Rgb = Rgb::new(0.0 * D, 128.0 * D, 0.0 * D); - - ///
- pub const GREENYELLOW: Rgb = Rgb::new(173.0 * D, 255.0 * D, 47.0 * D); - - ///
- pub const HONEYDEW: Rgb = Rgb::new(240.0 * D, 255.0 * D, 240.0 * D); - - ///
- pub const HOTPINK: Rgb = Rgb::new(255.0 * D, 105.0 * D, 180.0 * D); - - ///
- pub const INDIANRED: Rgb = Rgb::new(205.0 * D, 92.0 * D, 92.0 * D); - - ///
- pub const INDIGO: Rgb = Rgb::new(75.0 * D, 0.0 * D, 130.0 * D); - - ///
- pub const IVORY: Rgb = Rgb::new(255.0 * D, 255.0 * D, 240.0 * D); - - ///
- pub const KHAKI: Rgb = Rgb::new(240.0 * D, 230.0 * D, 140.0 * D); - - ///
- pub const LAVENDER: Rgb = Rgb::new(230.0 * D, 230.0 * D, 250.0 * D); - - ///
- pub const LAVENDERBLUSH: Rgb = Rgb::new(255.0 * D, 240.0 * D, 245.0 * D); - - ///
- pub const LAWNGREEN: Rgb = Rgb::new(124.0 * D, 252.0 * D, 0.0 * D); - - ///
- pub const LEMONCHIFFON: Rgb = Rgb::new(255.0 * D, 250.0 * D, 205.0 * D); - - ///
- pub const LIGHTBLUE: Rgb = Rgb::new(173.0 * D, 216.0 * D, 230.0 * D); - - ///
- pub const LIGHTCORAL: Rgb = Rgb::new(240.0 * D, 128.0 * D, 128.0 * D); - - ///
- pub const LIGHTCYAN: Rgb = Rgb::new(224.0 * D, 255.0 * D, 255.0 * D); - - ///
- pub const LIGHTGOLDENRODYELLOW: Rgb = Rgb::new(250.0 * D, 250.0 * D, 210.0 * D); - - ///
- pub const LIGHTGRAY: Rgb = Rgb::new(211.0 * D, 211.0 * D, 211.0 * D); - - ///
- pub const LIGHTGREEN: Rgb = Rgb::new(144.0 * D, 238.0 * D, 144.0 * D); - - ///
- pub const LIGHTGREY: Rgb = Rgb::new(211.0 * D, 211.0 * D, 211.0 * D); - - ///
- pub const LIGHTPINK: Rgb = Rgb::new(255.0 * D, 182.0 * D, 193.0 * D); - - ///
- pub const LIGHTSALMON: Rgb = Rgb::new(255.0 * D, 160.0 * D, 122.0 * D); - - ///
- pub const LIGHTSEAGREEN: Rgb = Rgb::new(32.0 * D, 178.0 * D, 170.0 * D); - - ///
- pub const LIGHTSKYBLUE: Rgb = Rgb::new(135.0 * D, 206.0 * D, 250.0 * D); - - ///
- pub const LIGHTSLATEGRAY: Rgb = Rgb::new(119.0 * D, 136.0 * D, 153.0 * D); - - ///
- pub const LIGHTSLATEGREY: Rgb = Rgb::new(119.0 * D, 136.0 * D, 153.0 * D); - - ///
- pub const LIGHTSTEELBLUE: Rgb = Rgb::new(176.0 * D, 196.0 * D, 222.0 * D); - - ///
- pub const LIGHTYELLOW: Rgb = Rgb::new(255.0 * D, 255.0 * D, 224.0 * D); - - ///
- pub const LIME: Rgb = Rgb::new(0.0 * D, 255.0 * D, 0.0 * D); - - ///
- pub const LIMEGREEN: Rgb = Rgb::new(50.0 * D, 205.0 * D, 50.0 * D); - - ///
- pub const LINEN: Rgb = Rgb::new(250.0 * D, 240.0 * D, 230.0 * D); - - ///
- pub const MAGENTA: Rgb = Rgb::new(255.0 * D, 0.0 * D, 255.0 * D); - - ///
- pub const MAROON: Rgb = Rgb::new(128.0 * D, 0.0 * D, 0.0 * D); - - ///
- pub const MEDIUMAQUAMARINE: Rgb = Rgb::new(102.0 * D, 205.0 * D, 170.0 * D); - - ///
- pub const MEDIUMBLUE: Rgb = Rgb::new(0.0 * D, 0.0 * D, 205.0 * D); - - ///
- pub const MEDIUMORCHID: Rgb = Rgb::new(186.0 * D, 85.0 * D, 211.0 * D); - - ///
- pub const MEDIUMPURPLE: Rgb = Rgb::new(147.0 * D, 112.0 * D, 219.0 * D); - - ///
- pub const MEDIUMSEAGREEN: Rgb = Rgb::new(60.0 * D, 179.0 * D, 113.0 * D); - - ///
- pub const MEDIUMSLATEBLUE: Rgb = Rgb::new(123.0 * D, 104.0 * D, 238.0 * D); - - ///
- pub const MEDIUMSPRINGGREEN: Rgb = Rgb::new(0.0 * D, 250.0 * D, 154.0 * D); - - ///
- pub const MEDIUMTURQUOISE: Rgb = Rgb::new(72.0 * D, 209.0 * D, 204.0 * D); - - ///
- pub const MEDIUMVIOLETRED: Rgb = Rgb::new(199.0 * D, 21.0 * D, 133.0 * D); - - ///
- pub const MIDNIGHTBLUE: Rgb = Rgb::new(25.0 * D, 25.0 * D, 112.0 * D); - - ///
- pub const MINTCREAM: Rgb = Rgb::new(245.0 * D, 255.0 * D, 250.0 * D); - - ///
- pub const MISTYROSE: Rgb = Rgb::new(255.0 * D, 228.0 * D, 225.0 * D); - - ///
- pub const MOCCASIN: Rgb = Rgb::new(255.0 * D, 228.0 * D, 181.0 * D); - - ///
- pub const NAVAJOWHITE: Rgb = Rgb::new(255.0 * D, 222.0 * D, 173.0 * D); - - ///
- pub const NAVY: Rgb = Rgb::new(0.0 * D, 0.0 * D, 128.0 * D); - - ///
- pub const OLDLACE: Rgb = Rgb::new(253.0 * D, 245.0 * D, 230.0 * D); - - ///
- pub const OLIVE: Rgb = Rgb::new(128.0 * D, 128.0 * D, 0.0 * D); - - ///
- pub const OLIVEDRAB: Rgb = Rgb::new(107.0 * D, 142.0 * D, 35.0 * D); - - ///
- pub const ORANGE: Rgb = Rgb::new(255.0 * D, 165.0 * D, 0.0 * D); - - ///
- pub const ORANGERED: Rgb = Rgb::new(255.0 * D, 69.0 * D, 0.0 * D); - - ///
- pub const ORCHID: Rgb = Rgb::new(218.0 * D, 112.0 * D, 214.0 * D); - - ///
- pub const PALEGOLDENROD: Rgb = Rgb::new(238.0 * D, 232.0 * D, 170.0 * D); - - ///
- pub const PALEGREEN: Rgb = Rgb::new(152.0 * D, 251.0 * D, 152.0 * D); - - ///
- pub const PALETURQUOISE: Rgb = Rgb::new(175.0 * D, 238.0 * D, 238.0 * D); - - ///
- pub const PALEVIOLETRED: Rgb = Rgb::new(219.0 * D, 112.0 * D, 147.0 * D); - - ///
- pub const PAPAYAWHIP: Rgb = Rgb::new(255.0 * D, 239.0 * D, 213.0 * D); - - ///
- pub const PEACHPUFF: Rgb = Rgb::new(255.0 * D, 218.0 * D, 185.0 * D); - - ///
- pub const PERU: Rgb = Rgb::new(205.0 * D, 133.0 * D, 63.0 * D); - - ///
- pub const PINK: Rgb = Rgb::new(255.0 * D, 192.0 * D, 203.0 * D); - - ///
- pub const PLUM: Rgb = Rgb::new(221.0 * D, 160.0 * D, 221.0 * D); - - ///
- pub const POWDERBLUE: Rgb = Rgb::new(176.0 * D, 224.0 * D, 230.0 * D); - - ///
- pub const PURPLE: Rgb = Rgb::new(128.0 * D, 0.0 * D, 128.0 * D); - - ///
- pub const REBECCAPURPLE: Rgb = Rgb::new(102.0 * D, 51.0 * D, 153.0 * D); - - ///
- pub const RED: Rgb = Rgb::new(255.0 * D, 0.0 * D, 0.0 * D); - - ///
- pub const ROSYBROWN: Rgb = Rgb::new(188.0 * D, 143.0 * D, 143.0 * D); - - ///
- pub const ROYALBLUE: Rgb = Rgb::new(65.0 * D, 105.0 * D, 225.0 * D); - - ///
- pub const SADDLEBROWN: Rgb = Rgb::new(139.0 * D, 69.0 * D, 19.0 * D); - - ///
- pub const SALMON: Rgb = Rgb::new(250.0 * D, 128.0 * D, 114.0 * D); - - ///
- pub const SANDYBROWN: Rgb = Rgb::new(244.0 * D, 164.0 * D, 96.0 * D); - - ///
- pub const SEAGREEN: Rgb = Rgb::new(46.0 * D, 139.0 * D, 87.0 * D); - - ///
- pub const SEASHELL: Rgb = Rgb::new(255.0 * D, 245.0 * D, 238.0 * D); - - ///
- pub const SIENNA: Rgb = Rgb::new(160.0 * D, 82.0 * D, 45.0 * D); - - ///
- pub const SILVER: Rgb = Rgb::new(192.0 * D, 192.0 * D, 192.0 * D); - - ///
- pub const SKYBLUE: Rgb = Rgb::new(135.0 * D, 206.0 * D, 235.0 * D); - - ///
- pub const SLATEBLUE: Rgb = Rgb::new(106.0 * D, 90.0 * D, 205.0 * D); - - ///
- pub const SLATEGRAY: Rgb = Rgb::new(112.0 * D, 128.0 * D, 144.0 * D); - - ///
- pub const SLATEGREY: Rgb = Rgb::new(112.0 * D, 128.0 * D, 144.0 * D); - - ///
- pub const SNOW: Rgb = Rgb::new(255.0 * D, 250.0 * D, 250.0 * D); - - ///
- pub const SPRINGGREEN: Rgb = Rgb::new(0.0 * D, 255.0 * D, 127.0 * D); - - ///
- pub const STEELBLUE: Rgb = Rgb::new(70.0 * D, 130.0 * D, 180.0 * D); - - ///
- pub const TAN: Rgb = Rgb::new(210.0 * D, 180.0 * D, 140.0 * D); - - ///
- pub const TEAL: Rgb = Rgb::new(0.0 * D, 128.0 * D, 128.0 * D); - - ///
- pub const THISTLE: Rgb = Rgb::new(216.0 * D, 191.0 * D, 216.0 * D); - - ///
- pub const TOMATO: Rgb = Rgb::new(255.0 * D, 99.0 * D, 71.0 * D); - - ///
- pub const TURQUOISE: Rgb = Rgb::new(64.0 * D, 224.0 * D, 208.0 * D); - - ///
- pub const VIOLET: Rgb = Rgb::new(238.0 * D, 130.0 * D, 238.0 * D); - - ///
- pub const WHEAT: Rgb = Rgb::new(245.0 * D, 222.0 * D, 179.0 * D); - - ///
- pub const WHITE: Rgb = Rgb::new(255.0 * D, 255.0 * D, 255.0 * D); - - ///
- pub const WHITESMOKE: Rgb = Rgb::new(245.0 * D, 245.0 * D, 245.0 * D); - - ///
- pub const YELLOW: Rgb = Rgb::new(255.0 * D, 255.0 * D, 0.0 * D); -} +impl ColorType for T {} diff --git a/src/driver/mod.rs b/src/driver/mod.rs index f3a6dec..f215b18 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -1,7 +1,4 @@ -use crate::{ - color::{Rgb, Srgb}, - Led, Sled, SledError, Vec2, -}; +use crate::{color::ColorType, Led, Sled, SledError, Vec2}; use std::time::{Duration, Instant}; @@ -18,26 +15,25 @@ pub struct TimeInfo { } type SledResult = Result<(), SledError>; -type StartupCommands = Box SledResult>; -type ComputeCommands = - Box SledResult>; -type DrawCommands = Box SledResult>; /// Drivers are useful for encapsulating everything you need to drive a complicated lighting effect all in one place. /// /// Some [macros](driver_macros) have been provided to make authoring drivers a more ergonomic experience. See their doc comments for more information. -pub struct Driver { - sled: Option, - startup_commands: StartupCommands, - compute_commands: ComputeCommands, - draw_commands: DrawCommands, +pub struct Driver { + sled: Option>, + startup_commands: + Box, &mut BufferContainer, &mut Filters) -> SledResult>, + compute_commands: + Box, &mut BufferContainer, &mut Filters, &TimeInfo) -> SledResult>, + draw_commands: + Box, &BufferContainer, &Filters, &TimeInfo) -> SledResult>, startup: Instant, last_update: Instant, buffers: BufferContainer, filters: Filters, } -impl Driver { +impl Driver { pub fn new() -> Self { Driver { sled: None, @@ -52,7 +48,7 @@ impl Driver { } /// Returns `Some(&Sled)` if the Driver has been mounted, `None` if it hasn't. - pub fn sled(&self) -> Option<&Sled> { + pub fn sled(&self) -> Option<&Sled> { self.sled.as_ref() } @@ -83,7 +79,7 @@ impl Driver { /// } /// ``` pub fn set_startup_commands< - F: Fn(&mut Sled, &mut BufferContainer, &mut Filters) -> SledResult + 'static, + F: Fn(&mut Sled, &mut BufferContainer, &mut Filters) -> SledResult + 'static, >( &mut self, startup_commands: F, @@ -114,7 +110,7 @@ impl Driver { /// /// ``` pub fn set_compute_commands< - F: Fn(&Sled, &mut BufferContainer, &mut Filters, &TimeInfo) -> SledResult + 'static, + F: Fn(&Sled, &mut BufferContainer, &mut Filters, &TimeInfo) -> SledResult + 'static, >( &mut self, compute_commands: F, @@ -131,7 +127,7 @@ impl Driver { /// fn draw(sled: &mut Sled, buffers: &BufferContainer) -> SledResult { /// // gradually fade all LEDs to black /// sled.map(|led| led.color * 0.95); - /// + /// /// // For each position in our buffer, draw white in the direction to it. /// let streak_positions = buffers.get_buffer::("positions")?; /// let center = sled.center_point(); @@ -149,7 +145,7 @@ impl Driver { /// /// ``` pub fn set_draw_commands< - F: Fn(&mut Sled, &BufferContainer, &Filters, &TimeInfo) -> SledResult + 'static, + F: Fn(&mut Sled, &BufferContainer, &Filters, &TimeInfo) -> SledResult + 'static, >( &mut self, draw_commands: F, @@ -158,7 +154,7 @@ impl Driver { } /// Takes ownership of the given Sled and runs the Driver's [startup commands](Driver::set_startup_commands). - pub fn mount(&mut self, mut sled: Sled) { + pub fn mount(&mut self, mut sled: Sled) { (self.startup_commands)(&mut sled, &mut self.buffers, &mut self.filters).unwrap(); self.startup = Instant::now(); self.last_update = self.startup; @@ -186,12 +182,12 @@ impl Driver { } /// Returns full ownership over the Driver's assigned Sled. Panics if [Driver::mount()] was never called. - pub fn dismount(&mut self) -> Sled { + pub fn dismount(&mut self) -> Sled { self.sled.take().unwrap() } /// See [Sled::leds()]. - pub fn leds(&self) -> impl Iterator { + pub fn leds(&self) -> impl Iterator> { if let Some(sled) = &self.sled { sled.leds() } else { @@ -200,7 +196,7 @@ impl Driver { } /// See [Sled::colors()]. - pub fn colors(&self) -> impl Iterator + '_ { + pub fn colors(&self) -> impl Iterator + '_ { if let Some(sled) = &self.sled { sled.colors() } else { @@ -208,18 +204,6 @@ impl Driver { } } - /// See [Sled::colors_coerced()]. - pub fn colors_coerced(&self) -> impl Iterator> + '_ - where - f32: crate::color::stimulus::IntoStimulus, - { - if let Some(sled) = &self.sled { - sled.colors_coerced() - } else { - panic!("Driver has no Sled assigned!") - } - } - /// See [Sled::positions()]. pub fn positions(&self) -> impl Iterator + '_ { if let Some(sled) = &self.sled { @@ -229,13 +213,9 @@ impl Driver { } } - /// See [Sled::colors_and_positions_coerced()]. - pub fn colors_and_positions_coerced(&self) -> impl Iterator, Vec2)> + '_ - where - f32: crate::color::stimulus::IntoStimulus, - { + pub fn colors_and_positions(&self) -> impl Iterator + '_ { if let Some(sled) = &self.sled { - sled.colors_and_positions_coerced() + sled.colors_and_positions() } else { panic!("Driver has no Sled assigned!") } @@ -252,7 +232,7 @@ impl Driver { } } -impl Default for Driver { +impl Default for Driver { fn default() -> Self { Self::new() } diff --git a/src/led.rs b/src/led.rs index 4483c84..00f4eca 100644 --- a/src/led.rs +++ b/src/led.rs @@ -1,11 +1,12 @@ -use crate::color::Rgb; use glam::Vec2; +use crate::color::ColorType; + #[derive(Copy, Clone)] /// An LED in our Sled configuration, representing both the color of the LED as well as it's spatial information. -pub struct Led { - pub color: Rgb, +pub struct Led { + pub color: Color, position: Vec2, angle: f32, distance: f32, @@ -15,11 +16,11 @@ pub struct Led { /// *All properties listed below are pre-calculated on construction; /// there is no substantial overhead for calling these methods.* -impl Led { +impl Led { /// Constructs an LED struct. /// Fields like `position`, `angle`, and `distance` are derived from `center_point`. pub(crate) fn new( - color: Rgb, + color: Color, position: Vec2, index: u16, segment: u8, @@ -76,37 +77,37 @@ impl Led { } } -impl PartialEq for Led { +impl PartialEq for Led { fn eq(&self, other: &Self) -> bool { self.index() == other.index() } } -impl Eq for Led {} +impl Eq for Led {} -impl PartialOrd for Led { +impl PartialOrd for Led { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for Led { +impl Ord for Led { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.index.cmp(&other.index()) } } -impl std::hash::Hash for Led { +impl std::hash::Hash for Led { fn hash(&self, state: &mut H) { self.index.hash(state); } } -impl std::fmt::Debug for Led { +impl std::fmt::Debug for Led { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let dir = self.direction(); f.debug_struct("Led") - .field("color", &self.color.into_components()) + .field("color", &self.color) .field("position", &(self.position.x, self.position.y)) .field("direction", &(dir.x, dir.y)) .field("angle", &self.angle) @@ -117,12 +118,8 @@ impl std::fmt::Debug for Led { } } -impl std::fmt::Display for Led { +impl std::fmt::Display for Led { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}: ({}, {}, {})", - self.index, self.color.red, self.color.green, self.color.blue - ) + write!(f, "{}: {:?}", self.index, self.color) } -} \ No newline at end of file +} diff --git a/src/spatial_led/directional.rs b/src/spatial_led/directional.rs index 6ded003..45c3e52 100644 --- a/src/spatial_led/directional.rs +++ b/src/spatial_led/directional.rs @@ -1,11 +1,11 @@ use std::collections::HashSet; -use crate::{color::Rgb, led::Led, Filter, Sled}; +use crate::{color::ColorType, led::Led, Filter, Sled}; use glam::Vec2; use smallvec::SmallVec; /// # directional read and write methods -impl Sled { +impl Sled { fn raycast_for_indices(&self, start: Vec2, dir: Vec2) -> SmallVec<[usize; 4]> { let dist = 100_000.0; let end = start + dir * dist; @@ -61,7 +61,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate_at_dir Rgb>(&mut self, dir: Vec2, color_rule: F) -> bool { + pub fn modulate_at_dir) -> Color>(&mut self, dir: Vec2, color_rule: F) -> bool { self.modulate_at_dir_from(dir, self.center_point, color_rule) } @@ -84,7 +84,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate_at_dir_from Rgb>( + pub fn modulate_at_dir_from) -> Color>( &mut self, dir: Vec2, pos: Vec2, @@ -110,7 +110,7 @@ impl Sled { /// Returns false if there is no LED in that direction, true otherwise. /// /// O(SEGMENTS) - pub fn set_at_dir(&mut self, dir: Vec2, color: Rgb) -> bool { + pub fn set_at_dir(&mut self, dir: Vec2, color: Color) -> bool { self.set_at_dir_from(dir, self.center_point, color) } @@ -120,7 +120,7 @@ impl Sled { /// Returns false if there is no LED in that direction, true otherwise. /// /// O(SEGMENTS) - pub fn set_at_dir_from(&mut self, dir: Vec2, pos: Vec2, color: Rgb) -> bool { + pub fn set_at_dir_from(&mut self, dir: Vec2, pos: Vec2, color: Color) -> bool { let intersecting_indices = self.raycast_for_indices(pos, dir); if intersecting_indices.is_empty() { @@ -187,7 +187,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate_at_angle Rgb>(&mut self, angle: f32, color_rule: F) -> bool { + pub fn modulate_at_angle) -> Color>(&mut self, angle: f32, color_rule: F) -> bool { self.modulate_at_angle_from(angle, self.center_point, color_rule) } @@ -212,7 +212,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate_at_angle_from Rgb>( + pub fn modulate_at_angle_from) -> Color>( &mut self, angle: f32, pos: Vec2, @@ -230,7 +230,7 @@ impl Sled { /// Returns false if there is no LED at that angle, true otherwise. /// /// O(SEGMENTS) - pub fn set_at_angle(&mut self, angle: f32, color: Rgb) -> bool { + pub fn set_at_angle(&mut self, angle: f32, color: Color) -> bool { self.set_at_angle_from(angle, self.center_point, color) } @@ -242,7 +242,7 @@ impl Sled { /// Returns false if there is no LED at that angle, true otherwise. /// /// O(SEGMENTS) - pub fn set_at_angle_from(&mut self, angle: f32, pos: Vec2, color: Rgb) -> bool { + pub fn set_at_angle_from(&mut self, angle: f32, pos: Vec2, color: Color) -> bool { let dir = Vec2::from_angle(angle); self.set_at_dir_from(dir, pos, color) } diff --git a/src/spatial_led/filter.rs b/src/spatial_led/filter.rs index 8852459..f7607cd 100644 --- a/src/spatial_led/filter.rs +++ b/src/spatial_led/filter.rs @@ -1,14 +1,14 @@ use std::collections::{hash_set, HashSet}; -use crate::{color::Rgb, led::Led, spatial_led::Sled}; +use crate::{color::ColorType, led::Led, spatial_led::Sled}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct Filter { led_indices: HashSet, } -impl From<&[Led]> for Filter { - fn from(value: &[Led]) -> Self { +impl From<&[Led]> for Filter { + fn from(value: &[Led]) -> Self { let mut hs = HashSet::new(); for led in value { hs.insert(led.index()); @@ -97,28 +97,28 @@ impl Extend for Filter { } } -impl Sled { - pub fn set_filter(&mut self, filter: &Filter, color: Rgb) { +impl Sled { + pub fn set_filter(&mut self, filter: &Filter, color: Color) { for i in filter { self.leds[i as usize].color = color; } } - pub fn modulate_filter Rgb>(&mut self, filter: &Filter, color_rule: F) { + pub fn modulate_filter) -> Color>(&mut self, filter: &Filter, color_rule: F) { for i in filter { let led = &mut self.leds[i as usize]; led.color = color_rule(led) } } - pub fn map_filter Rgb>(&mut self, filter: &Filter, map: F) { + pub fn map_filter) -> Color>(&mut self, filter: &Filter, map: F) { for i in filter { let led = &mut self.leds[i as usize]; led.color = map(led) } } - pub fn for_each_in_filter(&mut self, filter: &Filter, mut func: F) { + pub fn for_each_in_filter)>(&mut self, filter: &Filter, mut func: F) { for i in filter { let led = &mut self.leds[i as usize]; func(led); diff --git a/src/spatial_led/indexical.rs b/src/spatial_led/indexical.rs index 8c598e4..8b8f15f 100644 --- a/src/spatial_led/indexical.rs +++ b/src/spatial_led/indexical.rs @@ -1,18 +1,18 @@ use std::ops::Range; use crate::{ - color::Rgb, + color::ColorType, error::SledError, led::Led, spatial_led::{Filter, Sled}, }; /// # Index-based read and write methods. -impl Sled { - /// Returns `Some(&Led)` if an [LED](Led) at `index` exists, `None` if not. +impl Sled { + /// Returns `Some(&Led)` if an [LED](Led) at `index` exists, `None` if not. /// /// O(1) - pub fn get(&self, index: usize) -> Option<&Led> { + pub fn get(&self, index: usize) -> Option<&Led> { self.leds.get(index) } @@ -31,7 +31,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate Rgb>( + pub fn modulate) -> Color>( &mut self, index: usize, color_rule: F, @@ -50,7 +50,7 @@ impl Sled { /// /// O(1) /// - pub fn set(&mut self, index: usize, color: Rgb) -> Result<(), SledError> { + pub fn set(&mut self, index: usize, color: Color) -> Result<(), SledError> { if index >= self.num_leds { return SledError::new(format!("LED at index {} does not exist.", index)).as_err(); } @@ -63,7 +63,7 @@ impl Sled { /// /// O(LEDS) /// - pub fn set_all(&mut self, color: Rgb) { + pub fn set_all(&mut self, color: Color) { for led in &mut self.leds { led.color = color; } @@ -84,7 +84,7 @@ impl Sled { /// } /// }); /// ``` - pub fn for_each(&mut self, mut func: F) { + pub fn for_each)>(&mut self, mut func: F) { for led in self.leds.iter_mut() { func(led); } @@ -92,7 +92,7 @@ impl Sled { } /// # Index and range-based read and write methods -impl Sled { +impl Sled { /// Returns a Some([Filter]) containing all [LEDs](Led) with indices within `index_range`. /// Returns None if the range extends beyond the size of the system. /// @@ -120,7 +120,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate_range Rgb>( + pub fn modulate_range) -> Color>( &mut self, index_range: Range, color_rule: F, @@ -142,7 +142,7 @@ impl Sled { /// /// O(RANGE_SIZE) /// - pub fn set_range(&mut self, index_range: Range, color: Rgb) -> Result<(), SledError> { + pub fn set_range(&mut self, index_range: Range, color: Color) -> Result<(), SledError> { if index_range.end >= self.num_leds { return SledError::new("Index range extends beyond size of system.".to_string()) .as_err(); @@ -171,7 +171,7 @@ impl Sled { /// } /// }); /// ``` - pub fn for_each_in_range( + pub fn for_each_in_range)>( &mut self, index_range: Range, func: F, diff --git a/src/spatial_led/maps_and_filters.rs b/src/spatial_led/maps_and_filters.rs index 77d854c..d0318f1 100644 --- a/src/spatial_led/maps_and_filters.rs +++ b/src/spatial_led/maps_and_filters.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use crate::{ - color::Rgb, + color::ColorType, led::Led, spatial_led::{Filter, Sled}, }; @@ -9,43 +9,43 @@ use crate::{ use glam::Vec2; /// Maps -impl Sled { - pub fn map(&mut self, led_to_color_map: impl Fn(&Led) -> Rgb) { +impl Sled { + pub fn map(&mut self, led_to_color_map: impl Fn(&Led) -> Color) { self.leds .iter_mut() .for_each(|led| led.color = led_to_color_map(led)); } - pub fn map_by_index(&mut self, index_to_color_map: impl Fn(usize) -> Rgb) { + pub fn map_by_index(&mut self, index_to_color_map: impl Fn(usize) -> Color) { self.map(|led| index_to_color_map(led.index() as usize)); } - pub fn map_by_segment(&mut self, segment_index_to_color_map: impl Fn(usize) -> Rgb) { + pub fn map_by_segment(&mut self, segment_index_to_color_map: impl Fn(usize) -> Color) { self.map(|led| segment_index_to_color_map(led.segment() as usize)); } - pub fn map_by_pos(&mut self, pos_to_color_map: impl Fn(Vec2) -> Rgb) { + pub fn map_by_pos(&mut self, pos_to_color_map: impl Fn(Vec2) -> Color) { self.map(|led| pos_to_color_map(led.position())); } - pub fn map_by_dir(&mut self, dir_to_color_map: impl Fn(Vec2) -> Rgb) { + pub fn map_by_dir(&mut self, dir_to_color_map: impl Fn(Vec2) -> Color) { self.map(|led| dir_to_color_map(led.direction())); } - pub fn map_by_dir_from(&mut self, point: Vec2, dir_to_color_map: impl Fn(Vec2) -> Rgb) { + pub fn map_by_dir_from(&mut self, point: Vec2, dir_to_color_map: impl Fn(Vec2) -> Color) { self.leds.iter_mut().for_each(|led| { let dir = (point - led.position()).normalize_or_zero(); led.color = dir_to_color_map(dir) }); } - pub fn map_by_angle(&mut self, angle_to_color_map: impl Fn(f32) -> Rgb) { + pub fn map_by_angle(&mut self, angle_to_color_map: impl Fn(f32) -> Color) { self.leds.iter_mut().for_each(|led| { led.color = angle_to_color_map(led.angle()); }); } - pub fn map_by_angle_from(&mut self, point: Vec2, angle_to_color_map: impl Fn(f32) -> Rgb) { + pub fn map_by_angle_from(&mut self, point: Vec2, angle_to_color_map: impl Fn(f32) -> Color) { self.leds.iter_mut().for_each(|led| { let delta = point - led.position(); let angle = delta.x.atan2(delta.y); @@ -53,13 +53,13 @@ impl Sled { }); } - pub fn map_by_dist(&mut self, dist_to_color_map: impl Fn(f32) -> Rgb) { + pub fn map_by_dist(&mut self, dist_to_color_map: impl Fn(f32) -> Color) { self.leds .iter_mut() .for_each(|led| led.color = dist_to_color_map(led.distance())); } - pub fn map_by_dist_from(&mut self, pos: Vec2, dist_to_color_map: impl Fn(f32) -> Rgb) { + pub fn map_by_dist_from(&mut self, pos: Vec2, dist_to_color_map: impl Fn(f32) -> Color) { self.leds.iter_mut().for_each(|led| { let dist = pos.distance(led.position()); led.color = dist_to_color_map(dist); @@ -68,8 +68,8 @@ impl Sled { } /// Filters -impl Sled { - pub fn filter(&self, filter: impl Fn(&Led) -> bool) -> Filter { +impl Sled { + pub fn filter(&self, filter: impl Fn(&Led) -> bool) -> Filter { let filtered: HashSet = self .leds .iter() diff --git a/src/spatial_led/meta.rs b/src/spatial_led/meta.rs index 4d0c04f..edd2502 100644 --- a/src/spatial_led/meta.rs +++ b/src/spatial_led/meta.rs @@ -1,8 +1,7 @@ use std::ops::Range; use crate::{ - color, - color::{Rgb, Srgb}, + color::ColorType, config::{Config, LineSegment}, error::SledError, led::Led, @@ -11,7 +10,7 @@ use crate::{ }; /// # Construction, output, and basic sled info -impl Sled { +impl Sled { /// Constructs a new Sled struct given the path to a config file. /// This is an expensive operation as many values are pre-calculated /// on construction (i.e, distances/angles from each LED to the center). @@ -51,14 +50,14 @@ impl Sled { } fn new_from_config(config: Config) -> Result { - let leds_per_segment = Sled::leds_per_segment(&config); + let leds_per_segment = Sled::::leds_per_segment(&config); let leds = Sled::build_led_list( &leds_per_segment, &config.line_segments, &config.center_point, ); - let line_segment_endpoint_indices = Sled::line_segment_endpoint_indices(&leds_per_segment); - let vertex_indices = Sled::vertex_indices(&config); + let line_segment_endpoint_indices = Sled::::line_segment_endpoint_indices(&leds_per_segment); + let vertex_indices = Sled::::vertex_indices(&config); let num_leds = leds.len(); let index_of_closest = leds .iter() @@ -104,7 +103,7 @@ impl Sled { /// ); /// } /// ``` - pub fn leds(&self) -> impl Iterator { + pub fn leds(&self) -> impl Iterator> { self.leds.iter() } @@ -122,32 +121,10 @@ impl Sled { /// /*- snip -*/ /// } /// ``` - pub fn colors(&self) -> impl Iterator + '_ { + pub fn colors(&self) -> impl Iterator + '_ { self.leds.iter().map(|led| &led.color) } - /// Returns an Iterator over the RGB colors for each [LED](Led) in the system. - /// Type annotations allow you to coerce from 32-bit RGB into another depth. - /// - /// O(LEDS) - /// - /// ```rust - ///# use spatial_led::{Sled, color::Rgb}; - ///# let sled = Sled::new("./examples/resources/config.yap").unwrap(); - /// let colors = sled.colors_coerced::(); - /// - /// for color in colors { - /// let red: u8 = color.red; - /// /*- snip -*/ - /// } - /// ``` - pub fn colors_coerced(&self) -> impl Iterator> + '_ - where - f32: color::stimulus::IntoStimulus, - { - self.leds.iter().map(|led| led.color.into_format::()) - } - /// Returns an Iterator over Vec2s, representing the position of each [LED](Led) in the system. /// /// O(LEDS) @@ -158,35 +135,10 @@ impl Sled { /// Returns an Iterator over tuple pairs of the color and position of each [LED](Led) in the system. /// /// O(LEDS) - pub fn colors_and_positions(&self) -> impl Iterator, Vec2)> + '_ { + pub fn colors_and_positions(&self) -> impl Iterator + '_ { self.leds.iter().map(|led| (led.color, led.position())) } - /// Returns an Iterator over tuple pairs of the color and position of each [LED](Led) in the system. - /// Supports color coercion just like [Sled::colors_coerced()] - /// - /// O(LEDS) - /// - /// ```rust - /// # use spatial_led::{Sled, color::Rgb}; - ///# let sled = Sled::new("./examples/resources/config.yap").unwrap(); - /// let col_and_pos = sled.colors_and_positions_coerced::(); - /// - /// for (color, position) in col_and_pos { - /// let red: u8 = color.red; - /// let x = position.x; - /// /*- snip -*/ - /// } - /// ``` - pub fn colors_and_positions_coerced(&self) -> impl Iterator, Vec2)> + '_ - where - f32: color::stimulus::IntoStimulus, - { - self.leds - .iter() - .map(|led| (led.color.into_format::(), led.position())) - } - /// Returns the static reference point declared in the [config file](Sled::new). /// /// O(1) @@ -238,9 +190,9 @@ impl Sled { leds_per_segment: &[usize], line_segments: &[LineSegment], center_point: &Vec2, - ) -> Vec { + ) -> Vec> { let mut leds = vec![]; - let default_color = Rgb::new(0.0, 0.0, 0.0); + let default_color = Color::default(); for (segment_index, segment_size) in leds_per_segment.iter().enumerate() { for i in 0..*segment_size { @@ -299,7 +251,7 @@ impl Sled { vertex_indices } - fn calc_domain(leds: &Vec) -> Range { + fn calc_domain(leds: &Vec>) -> Range { let mut min_x = f32::MAX; let mut min_y = f32::MAX; diff --git a/src/spatial_led/mod.rs b/src/spatial_led/mod.rs index a382f61..bc0c3d0 100644 --- a/src/spatial_led/mod.rs +++ b/src/spatial_led/mod.rs @@ -1,6 +1,6 @@ use std::ops::Range; -use crate::{config::LineSegment, led::Led, Vec2}; +use crate::{color::ColorType, config::LineSegment, led::Led, Vec2}; #[allow(dead_code)] #[derive(Clone, Debug)] @@ -8,9 +8,9 @@ use crate::{config::LineSegment, led::Led, Vec2}; /// /// Sled structs are [constructed](Sled::new) from a .toml file that describe this layout. /// Upon construction, key information like the indices of vertices or the angle from each led from the center_point is precalculated and cached for faster access later. -pub struct Sled { +pub struct Sled { center_point: Vec2, - leds: Vec, + leds: Vec>, num_leds: usize, density: f32, line_segments: Vec, diff --git a/src/spatial_led/positional.rs b/src/spatial_led/positional.rs index 6cc6ff3..c1ae377 100644 --- a/src/spatial_led/positional.rs +++ b/src/spatial_led/positional.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use crate::{ - color::Rgb, + color::ColorType, led::Led, spatial_led::{Filter, Sled}, }; @@ -10,7 +10,7 @@ use glam::Vec2; use smallvec::{smallvec, SmallVec}; /// # position-based read and write methods -impl Sled { +impl Sled { /* closest getters/setters */ /// Returns the index of the [LED](Led) closest to a given point. @@ -38,14 +38,14 @@ impl Sled { /// Returns the [LED](Led) closest to the center point. /// /// O(1) - pub fn closest(&self) -> &Led { + pub fn closest(&self) -> &Led { &self.leds[self.index_of_closest] } /// Returns the [LED](Led) closest to a given point. /// /// O(SEGMENTS) - pub fn closest_to(&self, pos: Vec2) -> &Led { + pub fn closest_to(&self, pos: Vec2) -> &Led { let index_of_closest = self.index_of_closest_to(pos); &self.leds[index_of_closest] } @@ -61,7 +61,7 @@ impl Sled { /// sled.modulate_closest(|led| led.color + Rgb::new(0.2, 0.2, 0.2)); ///# Ok(()) ///# } - pub fn modulate_closest Rgb>(&mut self, color_rule: F) { + pub fn modulate_closest) -> Color>(&mut self, color_rule: F) { let led = &mut self.leds[self.index_of_closest]; led.color = color_rule(led); } @@ -79,7 +79,7 @@ impl Sled { /// }); ///# Ok(()) ///# } - pub fn modulate_closest_to Rgb>(&mut self, pos: Vec2, color_rule: F) { + pub fn modulate_closest_to) -> Color>(&mut self, pos: Vec2, color_rule: F) { let index_of_closest = self.index_of_closest_to(pos); let led = &mut self.leds[index_of_closest]; led.color = color_rule(led); @@ -88,14 +88,14 @@ impl Sled { /// Sets the color of the [LED](Led) closest to the center point. /// /// O(1) - pub fn set_closest(&mut self, color: Rgb) { + pub fn set_closest(&mut self, color: Color) { self.leds[self.index_of_closest].color = color; } /// Sets the color of the [LED](Led) closest to a given point. /// /// O(SEGMENTS) - pub fn set_closest_to(&mut self, pos: Vec2, color: Rgb) { + pub fn set_closest_to(&mut self, pos: Vec2, color: Color) { let index_of_closest = self.index_of_closest_to(pos); self.leds[index_of_closest].color = color; } @@ -129,14 +129,14 @@ impl Sled { /// Returns the [LED](Led) furthest from the center point. /// /// O(1) - pub fn furthest(&self) -> &Led { + pub fn furthest(&self) -> &Led { &self.leds[self.index_of_furthest] } /// Returns the [LED](Led) furthest from a given point. /// /// O(VERTICES) - pub fn furthest_from(&self, pos: Vec2) -> &Led { + pub fn furthest_from(&self, pos: Vec2) -> &Led { let index_of_furthest = self.index_of_furthest_from(pos); &self.leds[index_of_furthest] } @@ -151,7 +151,7 @@ impl Sled { /// sled.modulate_furthest(|led| led.color / led.distance()); ///# Ok(()) ///# } - pub fn modulate_furthest Rgb>(&mut self, color_rule: F) { + pub fn modulate_furthest) -> Color>(&mut self, color_rule: F) { let led = &mut self.leds[self.index_of_furthest]; led.color = color_rule(led); } @@ -169,7 +169,7 @@ impl Sled { /// }); ///# Ok(()) ///# } - pub fn modulate_furthest_from Rgb>(&mut self, pos: Vec2, color_rule: F) { + pub fn modulate_furthest_from) -> Color>(&mut self, pos: Vec2, color_rule: F) { let index_of_furthest = self.index_of_furthest_from(pos); let led = &mut self.leds[index_of_furthest]; led.color = color_rule(led); @@ -178,14 +178,14 @@ impl Sled { /// Sets the color of the [LED](Led) furthest from the center point. /// /// O(1) - pub fn set_furthest(&mut self, color: Rgb) { + pub fn set_furthest(&mut self, color: Color) { self.leds[self.index_of_furthest].color = color; } /// Sets the color of the [LED](Led) furthest from a given point. /// /// O(VERTICES) - pub fn set_furthest_from(&mut self, pos: Vec2, color: Rgb) { + pub fn set_furthest_from(&mut self, pos: Vec2, color: Color) { let index_of_furthest = self.index_of_furthest_from(pos); self.leds[index_of_furthest].color = color; } @@ -221,11 +221,11 @@ impl Sled { all_at_distance.into() } - pub fn modulate_at_dist Rgb>(&mut self, dist: f32, color_rule: F) -> bool { + pub fn modulate_at_dist) -> Color>(&mut self, dist: f32, color_rule: F) -> bool { self.modulate_at_dist_from(dist, self.center_point, color_rule) } - pub fn modulate_at_dist_from Rgb>( + pub fn modulate_at_dist_from) -> Color>( &mut self, dist: f32, pos: Vec2, @@ -241,11 +241,11 @@ impl Sled { anything_found } - pub fn set_at_dist(&mut self, dist: f32, color: Rgb) -> bool { + pub fn set_at_dist(&mut self, dist: f32, color: Color) -> bool { self.set_at_dist_from(dist, self.center_point, color) } - pub fn set_at_dist_from(&mut self, dist: f32, pos: Vec2, color: Rgb) -> bool { + pub fn set_at_dist_from(&mut self, dist: f32, pos: Vec2, color: Color) -> bool { let indices = self.indices_at_dist(pos, dist); let anything_found = !indices.is_empty(); @@ -276,7 +276,7 @@ impl Sled { all_within_distance.into() } - pub fn modulate_within_dist Rgb>(&mut self, dist: f32, color_rule: F) -> bool { + pub fn modulate_within_dist) -> Color>(&mut self, dist: f32, color_rule: F) -> bool { let mut changes_made = false; for led in &mut self.leds { @@ -289,7 +289,7 @@ impl Sled { changes_made } - pub fn set_within_dist(&mut self, dist: f32, color: Rgb) -> bool { + pub fn set_within_dist(&mut self, dist: f32, color: Color) -> bool { let mut changes_made = false; for led in &mut self.leds { @@ -302,7 +302,7 @@ impl Sled { changes_made } - pub fn modulate_within_dist_from Rgb>( + pub fn modulate_within_dist_from) -> Color>( &mut self, dist: f32, pos: Vec2, @@ -321,7 +321,7 @@ impl Sled { changes_made } - pub fn set_within_dist_from(&mut self, dist: f32, pos: Vec2, color: Rgb) -> bool { + pub fn set_within_dist_from(&mut self, dist: f32, pos: Vec2, color: Color) -> bool { let target_sq = dist.powi(2); let mut changes_made = false; diff --git a/src/spatial_led/segmental.rs b/src/spatial_led/segmental.rs index 66b888e..3052226 100644 --- a/src/spatial_led/segmental.rs +++ b/src/spatial_led/segmental.rs @@ -1,5 +1,5 @@ use crate::{ - color::Rgb, + color::ColorType, error::SledError, led::Led, spatial_led::{Filter, Sled}, @@ -7,7 +7,7 @@ use crate::{ use std::{collections::HashSet, ops::Range}; /// # Segment-based read and write methods. -impl Sled { +impl Sled { /// Returns the set of all [LEDs](Led) assigned to the line segment with index `segment_index`. /// /// O(LEDS_IN_SEGMENT) @@ -27,7 +27,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate_segment Rgb>( + pub fn modulate_segment) -> Color>( &mut self, segment_index: usize, color_rule: F, @@ -51,7 +51,7 @@ impl Sled { /// Sets the color of each [LED](Led) assigned to the line segment with index `segment_index`. Returns an [error](SledError) if there is no line segment with the given index. /// O(LEDS_IN_SEGMENT) /// - pub fn set_segment(&mut self, segment_index: usize, color: Rgb) -> Result<(), SledError> { + pub fn set_segment(&mut self, segment_index: usize, color: Color) -> Result<(), SledError> { if segment_index >= self.line_segment_endpoint_indices.len() { return SledError::new(format!( "No line segment of index {} exists.", @@ -66,7 +66,7 @@ impl Sled { } /// Returns the set of all [LEDs](Led) assigned to the line segments whose indices are within the given range. - /// + /// /// If the range exceeds the number of segments in the system, returns None. /// /// O(LEDS_IN_SEGMENTS) @@ -104,7 +104,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate_segments Rgb>( + pub fn modulate_segments) -> Color>( &mut self, range: Range, color_rule: F, @@ -128,7 +128,7 @@ impl Sled { /// Sets the color of each [LED](Led) assigned to the line segments whose indices are within the given range. /// Returns an [error](SledError) if the range exceeds the number of line segments in the system. /// O(LEDS_IN_SEGMENTS) - pub fn set_segments(&mut self, range: Range, color: Rgb) -> Result<(), SledError> { + pub fn set_segments(&mut self, range: Range, color: Color) -> Result<(), SledError> { if range.start >= self.line_segment_endpoint_indices.len() { return SledError::new( "Segment index range extends beyond the number of segments in the system." @@ -149,7 +149,7 @@ impl Sled { /// Also passes an "alpha" value into the closure, representing how far along the line segment you are. 0 = first LED in segement, 1 = last. /// /// Returns an [error](SledError) if the no segment of given index exists. - /// + /// /// O(LEDS_IN_SEGMENT) /// /// ```rust @@ -160,7 +160,7 @@ impl Sled { /// }); /// ``` /// ![segment alpha example](https://raw.githubusercontent.com/DavJCosby/sled/master/resources/segment_alpha.png) - pub fn for_each_in_segment( + pub fn for_each_in_segment, f32)>( &mut self, segment_index: usize, mut func: F, @@ -184,13 +184,13 @@ impl Sled { } /// # Vertex-based read and write methods. -impl Sled { +impl Sled { /// Returns the [LED](Led) that represents the vertex the given index, if it exists. /// Vertices are distinct from line segement endpoints in that line segments with touching endpoints will share a vertex. /// /// O(1) /// - pub fn vertex(&self, vertex_index: usize) -> Option<&Led> { + pub fn vertex(&self, vertex_index: usize) -> Option<&Led> { if vertex_index >= self.vertex_indices.len() { return None; } @@ -201,7 +201,7 @@ impl Sled { /// Vertices are distinct from line segement endpoints in that line segments with touching endpoints will share a vertex. /// /// Returns an [error](SledError) if no vertex of given index exists. - /// + /// /// O(1) /// /// ```rust @@ -213,7 +213,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate_vertex Rgb>( + pub fn modulate_vertex) -> Color>( &mut self, vertex_index: usize, color_rule: F, @@ -232,10 +232,10 @@ impl Sled { /// Vertices are distinct from line segement endpoints in that line segments with touching endpoints will share a vertex. /// /// Returns an [error](SledError) if no vertex of given index exists. - /// + /// /// O(1) /// - pub fn set_vertex(&mut self, vertex_index: usize, color: Rgb) -> Result<(), SledError> { + pub fn set_vertex(&mut self, vertex_index: usize, color: Color) -> Result<(), SledError> { if vertex_index >= self.vertex_indices.len() { return SledError::new(format!( "Vertex with index {} does not exist.", @@ -268,7 +268,7 @@ impl Sled { ///# Ok(()) ///# } /// ``` - pub fn modulate_vertices Rgb>(&mut self, color_rule: F) { + pub fn modulate_vertices) -> Color>(&mut self, color_rule: F) { for i in &self.vertex_indices { let led = &mut self.leds[*i]; led.color = color_rule(led); @@ -278,7 +278,7 @@ impl Sled { /// Sets the color of each [LED](Led) that represents a vertex in the system. /// /// O(VERTICES) - pub fn set_vertices(&mut self, color: Rgb) { + pub fn set_vertices(&mut self, color: Color) { for i in &self.vertex_indices { let led = &mut self.leds[*i]; led.color = color; @@ -288,7 +288,7 @@ impl Sled { /// For each method that grants mutable access to each [LED](Led) that represents a vertex in the system. /// /// O(VERTICES) - pub fn for_each_vertex(&mut self, mut f: F) { + pub fn for_each_vertex)>(&mut self, mut f: F) { for i in &self.vertex_indices { f(&mut self.leds[*i]) } From c8d7b78181751e938a0e1d1c1e1c2d328cc320bd Mon Sep 17 00:00:00 2001 From: David Cosby Date: Mon, 11 Nov 2024 15:25:39 -0700 Subject: [PATCH 2/2] corrected f32 to u8 color casting --- examples/resources/tui.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/resources/tui.rs b/examples/resources/tui.rs index c8042c6..a31c94e 100644 --- a/examples/resources/tui.rs +++ b/examples/resources/tui.rs @@ -117,9 +117,9 @@ fn draw_led(ctx: &mut Context, led: &(Srgb, Vec2)) { y: pos.y as f64, radius: 0.0, color: Color::Rgb( - (col.red / 255.0) as u8, - (col.green / 255.0) as u8, - (col.blue / 255.0) as u8, + (col.red * 255.0) as u8, + (col.green * 255.0) as u8, + (col.blue * 255.0) as u8, ), }); }