Skip to content

Commit

Permalink
Merge pull request #77 from DavJCosby/option/result-reevaluation
Browse files Browse the repository at this point in the history
Reevaluating When to Use Results, Options, or Bools
  • Loading branch information
DavJCosby authored Mar 28, 2024
2 parents 6dc20dd + bdc41a3 commit a2e40dd
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 98 deletions.
8 changes: 4 additions & 4 deletions examples/calibration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ fn main() -> Result<(), SledError> {

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_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));

display.set_leds(sled.colors_and_positions_coerced());
display.refresh().unwrap();
Expand Down
4 changes: 2 additions & 2 deletions examples/drivers/comet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ fn draw(
// speckle in swirling green points
for i in 0..GREEN_COUNT {
let angle = inner_time_scale + (TAU / GREEN_COUNT as f32) * i as f32 % TAU;
sled.modulate_at_angle(angle, |led| led.color + GREEN)?
sled.modulate_at_angle(angle, |led| led.color + GREEN);
}

// speckle in swirling blue points
for i in 0..BLUE_COUNT {
let angle = outer_time_scale + (TAU / BLUE_COUNT as f32) * i as f32 % TAU;
sled.modulate_at_angle(angle, |led| led.color + BLUE)?
sled.modulate_at_angle(angle, |led| led.color + BLUE);
}

// brighten or darken points depending on time and angle to simulate a sweeping
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
//! [[line_segment]]
//! start = [2.0, 2]
//! end = [-2.0, 2]
//!
//! [[line_segment]]
//! start = [-2.0, 2]
//! end = [-2.0, 0.0]
Expand All @@ -68,7 +69,7 @@
//! # use sled::{Sled, color::Rgb};
//! # fn main() -> Result<(), sled::SledError> {
//! # let mut sled = Sled::new("./examples/resources/config.toml").unwrap();
//! sled.set_at_dist(2.0, Rgb::new(1.0, 0.0, 0.0))?;
//! sled.set_at_dist(2.0, Rgb::new(1.0, 0.0, 0.0));
//! # Ok(())
//! # }
//! ```
Expand Down Expand Up @@ -165,7 +166,7 @@
//! for i in 0..num_colors {
//! let alpha = i as f32 / num_colors as f32;
//! let angle = elapsed + (std::f32::consts::TAU * alpha);
//! sled.set_at_angle(angle, colors[i])?;
//! sled.set_at_angle(angle, colors[i]);
//! }
//!
//! Ok(())
Expand Down
77 changes: 41 additions & 36 deletions src/sled/directional.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashSet;

use crate::{color::Rgb, error::SledError, led::Led, Filter, Sled};
use crate::{color::Rgb, led::Led, Filter, Sled};
use glam::Vec2;
use smallvec::SmallVec;

Expand All @@ -26,13 +26,17 @@ impl Sled {
/// Returns A [Filter] containing each [LED](Led) in the given direction from the center point.
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// If no LEDs exist at the given direction, the Filter will be empty.
///
/// O(SEGMENTS)
pub fn at_dir(&self, dir: Vec2) -> Filter {
self.at_dir_from(dir, self.center_point)
}

/// Returns A [Filter] containing each [LED](Led) in the given direction from a given point.
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// Currently returns no more than 4 LEDs, may change in the future.
pub fn at_dir_from(&self, dir: Vec2, pos: Vec2) -> Filter {
let intersecting_indices = self.raycast_for_indices(pos, dir);
intersecting_indices
Expand All @@ -45,30 +49,26 @@ impl Sled {
/// Modulates the color of each [LED](Led) in the given direction from the center point.
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// Returns an [error](SledError) if there is no LED in that direction.
/// Returns false if there is no LED in that direction, true otherwise.
///
/// O(SEGMENTS)
///
///```rust
///# use sled::{Sled, SledError, color::Rgb, Vec2};
///# fn demo() -> Result<(), SledError> {
///# let mut sled = Sled::new("./examples/resources/config.toml")?;
/// sled.modulate_at_dir(Vec2::new(0.0, 1.0), |led| led.color * 2.0)?;
/// sled.modulate_at_dir(Vec2::new(0.0, 1.0), |led| led.color * 2.0);
///# Ok(())
///# }
/// ```
pub fn modulate_at_dir<F: Fn(&Led) -> Rgb>(
&mut self,
dir: Vec2,
color_rule: F,
) -> Result<(), SledError> {
pub fn modulate_at_dir<F: Fn(&Led) -> Rgb>(&mut self, dir: Vec2, color_rule: F) -> bool {
self.modulate_at_dir_from(dir, self.center_point, color_rule)
}

/// Modulates the color of each [LED](Led) in the given direction from a given point.
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// Returns an [error](SledError) if there is no LED in that direction.
/// Returns false if there is no LED in that direction, true otherwise.
///
/// O(SEGMENTS)
///
Expand All @@ -80,7 +80,7 @@ impl Sled {
/// let from = Vec2::new(0.25, -0.6);
/// sled.modulate_at_dir_from(dir, from, |led| {
/// led.color * 2.0
/// })?;
/// });
///# Ok(())
///# }
/// ```
Expand All @@ -89,47 +89,49 @@ impl Sled {
dir: Vec2,
pos: Vec2,
color_rule: F,
) -> Result<(), SledError> {
) -> bool {
let intersecting_indices = self.raycast_for_indices(pos, dir);

if intersecting_indices.is_empty() {
return SledError::new(format!("No LED in directon: {} from {}", dir, pos)).as_err();
return false;
}

for index in intersecting_indices {
let led = &mut self.leds[index];
led.color = color_rule(led);
}
Ok(())

true
}

/// Sets the color of each [LED](Led) in the given direction from the center.
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// Returns an [error](SledError) if there is no LED in that direction.
/// 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) -> Result<(), SledError> {
pub fn set_at_dir(&mut self, dir: Vec2, color: Rgb) -> bool {
self.set_at_dir_from(dir, self.center_point, color)
}

/// Sets the color of each [LED](Led) in the given direction from a given point.
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// Returns an [error](SledError) if there is no LED in that direction.
/// 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) -> Result<(), SledError> {
pub fn set_at_dir_from(&mut self, dir: Vec2, pos: Vec2, color: Rgb) -> bool {
let intersecting_indices = self.raycast_for_indices(pos, dir);

if intersecting_indices.is_empty() {
return SledError::new(format!("No LED in directon: {} from {}", dir, pos)).as_err();
return false;
}

for index in intersecting_indices {
self.leds[index].color = color;
}
Ok(())

true
}

/* angle setters/getters */
Expand All @@ -140,6 +142,10 @@ impl Sled {
///
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// If no LEDs exist at the given direction, the Filter will be empty.
///
/// Currently returns no more than 4 LEDs, may change in the future.
///
/// O(SEGMENTS)
pub fn at_angle(&self, angle: f32) -> Filter {
let dir = Vec2::from_angle(angle);
Expand All @@ -152,6 +158,10 @@ impl Sled {
///
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// If no LEDs exist at the given direction, the Filter will be empty.
///
/// Currently returns no more than 4 LEDs, may change in the future.
///
/// O(SEGMENTS)
pub fn at_angle_from(&self, angle: f32, pos: Vec2) -> Filter {
let dir = Vec2::from_angle(angle);
Expand All @@ -164,7 +174,7 @@ impl Sled {
///
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// Returns an [error](SledError) if there is no LED in that direction.
/// Returns false if there is no LED at that angle, true otherwise.
///
/// O(SEGMENTS)
///
Expand All @@ -173,15 +183,11 @@ impl Sled {
/// use std::f32::consts::PI;
///# fn demo() -> Result<(), SledError> {
///# let mut sled = Sled::new("./examples/resources/config.toml")?;
/// sled.modulate_at_angle(PI / 4.0, |led| led.color * 2.0)?;
/// sled.modulate_at_angle(PI / 4.0, |led| led.color * 2.0);
///# Ok(())
///# }
/// ```
pub fn modulate_at_angle<F: Fn(&Led) -> Rgb>(
&mut self,
angle: f32,
color_rule: F,
) -> Result<(), SledError> {
pub fn modulate_at_angle<F: Fn(&Led) -> Rgb>(&mut self, angle: f32, color_rule: F) -> bool {
self.modulate_at_angle_from(angle, self.center_point, color_rule)
}

Expand All @@ -191,7 +197,7 @@ impl Sled {
///
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// Returns an [error](SledError) if there is no LED in that direction.
/// Returns false if there is no LED at that angle, true otherwise.
///
/// O(SEGMENTS)
///
Expand All @@ -202,7 +208,7 @@ impl Sled {
///# let mut sled = Sled::new("./examples/resources/config.toml")?;
/// let angle = PI * 1.25;
/// let from = Vec2::new(0.3, 0.2);
/// sled.modulate_at_angle_from(angle, from, |led| led.color * 2.0)?;
/// sled.modulate_at_angle_from(angle, from, |led| led.color * 2.0);
///# Ok(())
///# }
/// ```
Expand All @@ -211,7 +217,7 @@ impl Sled {
angle: f32,
pos: Vec2,
color_rule: F,
) -> Result<(), SledError> {
) -> bool {
let dir = Vec2::from_angle(angle);
self.modulate_at_dir_from(dir, pos, color_rule)
}
Expand All @@ -221,8 +227,10 @@ impl Sled {
///
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// 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) -> Result<(), SledError> {
pub fn set_at_angle(&mut self, angle: f32, color: Rgb) -> bool {
self.set_at_angle_from(angle, self.center_point, color)
}

Expand All @@ -231,13 +239,10 @@ impl Sled {
///
/// Calculated by performing a raycast against each line segment and finding the closest LED to the point of contact.
///
/// 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,
) -> Result<(), SledError> {
pub fn set_at_angle_from(&mut self, angle: f32, pos: Vec2, color: Rgb) -> bool {
let dir = Vec2::from_angle(angle);
self.set_at_dir_from(dir, pos, color)
}
Expand Down
25 changes: 18 additions & 7 deletions src/sled/indexical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,17 @@ impl Sled {

/// # Index and range-based read and write methods
impl Sled {
/// Returns a [Filter] containing all [LEDs](Led) with indices within `index_range`.
/// Returns an [error](SledError) if the range extends beyond the size of the system.
/// 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.
///
/// O(RANGE_SIZE)
///
pub fn range(&self, index_range: Range<usize>) -> Result<Filter, SledError> {
pub fn range(&self, index_range: Range<usize>) -> Option<Filter> {
if index_range.end < self.num_leds {
let led_range = &self.leds[index_range];
Ok(led_range.into())
Some(led_range.into())
} else {
SledError::new("Index range extends beyond size of system.".to_string()).as_err()
None
}
}

Expand Down Expand Up @@ -155,6 +155,8 @@ impl Sled {
}

/// For-each method granting mutable access to each [LED](Led) with an index in `index_range`
///
/// Returns an [error](SledError) if the range extends beyond the size of the system.
///
/// O(RANGE_SIZE)
///
Expand All @@ -169,7 +171,16 @@ impl Sled {
/// }
/// });
/// ```
pub fn for_each_in_range<F: FnMut(&mut Led)>(&mut self, index_range: Range<usize>, func: F) {
pub fn for_each_in_range<F: FnMut(&mut Led)>(
&mut self,
index_range: Range<usize>,
func: F,
) -> Result<(), SledError> {
if index_range.end >= self.num_leds {
return SledError::new("Index range extends beyond size of system.".to_string())
.as_err();
}
self.leds[index_range].iter_mut().for_each(func);
Ok(())
}
}
}
16 changes: 9 additions & 7 deletions src/sled/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ impl Sled {
})
}

/// Returns a copy of the system's [LEDs](Led), stored in an ordered vector.
/// Returns a read-only iterator over the system's [LEDs](Led).
///
/// If you need owned copies of these values, `.collect()` this iterator into a Vector.
///
/// O(LEDS)
///
Expand All @@ -100,11 +102,11 @@ impl Sled {
/// );
/// }
/// ```
pub fn leds(&self) -> Vec<Led> {
self.leds.clone()
pub fn leds(&self) -> impl Iterator<Item = &Led> {
self.leds.iter()
}

/// Returns an Iterator of the 32-bit RGB colors for each [LED](Led) in the system
/// Returns an Iterator over the 32-bit RGB colors for each [LED](Led) in the system
///
/// O(LEDS)
///
Expand All @@ -122,7 +124,7 @@ impl Sled {
self.leds.iter().map(|led| led.color)
}

/// Returns an Iterator of the RGB colors for each [LED](Led) in the system.
/// 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)
Expand All @@ -144,7 +146,7 @@ impl Sled {
self.leds.iter().map(|led| led.color.into_format::<T>())
}

/// Returns an Iterator of Vec2s, representing the position of each [LED](Led) in the system.
/// Returns an Iterator over Vec2s, representing the position of each [LED](Led) in the system.
///
/// O(LEDS)
pub fn positions(&self) -> impl Iterator<Item = Vec2> + '_ {
Expand All @@ -162,7 +164,7 @@ impl Sled {
/// Supports color coercion just like [Sled::colors_coerced()](colors_coerced())
///
/// O(LEDS)
///
///
/// ```rust
/// # use sled::{Sled, color::Rgb};
///# let sled = Sled::new("./examples/resources/config.toml").unwrap();
Expand Down
Loading

0 comments on commit a2e40dd

Please sign in to comment.