Releases: DavJCosby/sled
0.3.0
Announcing Spatial_LED 0.3.0
This release is a big one, featuring some big wins for ergonomics, end-user freedom, and compile time performance!
Spatial_LED 0.2.0 | Spatial_LED 0.3.0 | |
---|---|---|
Dependencies | 31 | 17 |
Build time (release)* | 8.04s | 3.70s |
Dev Dependencies | 75 | 73 |
* Benchmarked with a 2023 14-inch Macbook Pro (Apple M2 Pro)
Use colors with any data type.
Previously, Spatial_LED used palette's Rgb Struct internally to represent colors. Though palette offers some incredible conveniences, it's not going to be a perfect fit for everyone.
Some users on incredibly constrained systems might want to represent their colors at 8 bits/channel, instead of 32. Others might want extra precision for their applications. Some might even be working with RGBW or grayscale strips!
To make Spatial_LED make sense for everyone, I chose to decouple palette from Sled (see #64 for more information).
Here are a few examples of what it looks like to use your own color representation in Spatial_LED 0.3.0:
8-bit color precision
let mut u8_sled = Sled::<(u8, u8, u8)>::new("/path/to/config.yap")?;
u8_sled.set(4, (255, 0, 0))?;
Custom RGBW struct
#[derive(Debug)]
struct RGBW {
r: f32,
g: f32,
b: f32,
w: f32
}
let mut rgbw_sled = Sled::<RGBW>::new("/path/to/config.yap")?;
rgbw_sled.set_all(RGBW {
r: 0.0,
g: 1.0,
b: 0.0,
w: 0.0
});
Grayscale
let mut grayscale_sled = Sled::<f32>::new("/path/to/config.yap")?;
grayscale_sled.set_segment(0, 1.0)?;
Just let me keep palette
use palette::rgb::Rgb;
let mut sled = Sled::<Rgb>::new("/path/to/config.yap")?;
sled.set_verticles(Rgb::new(1.0, 1.0, 1.0));
Any type that implements Debug
, Default
, and Copy
can be used to represent colors in a Sled. While I still highly recommend palette, use what makes the most sense for your project!
BufferContainer
is gone. Meet Data!
Check out #85 for a deeper dive into the inspiration behind this.
In short, code that used to look like this:
// spatial_led 0.2.0
sled.set_startup_commands(|_sled, buffers, filters|
let colors: &mut Vec<Rgb> = buffers.create_buffer::<Rgb>("colors");
colors.extend([
Rgb::new(1.0, 0.0, 0.0),
Rgb::new(0.0, 0.0, 1.0),
Rgb::new(0.0, 1.0, 0.0),
]);
Ok(())
});
Now looks like this:
// spatial_led 0.3.0
sled.set_startup_commands(|_sled, data| {
data.set::<Vec<Rgb>>("colors", vec![
Rgb::new(1.0, 0.0, 0.0),
Rgb::new(0.0, 0.0, 1.0),
Rgb::new(0.0, 1.0, 0.0),
]);
Ok(())
});
Further, Data
is capable of storing more than just vectors of values. They can take just about any type!
// spatial_led 0.3.0
sled.set_startup_commands(|_sled, data|, {
data.set::<f32>("lamp_brightness", 0.5);
data.set("lamp_color", Rgb::new(0.8, 0.6, 0.3));
data.set("lamp_pos", Vec2::new(0.0, 0.0));
});
sled.set_draw_commands(|_sled, data, _time| {
let lamp_brightness: &f32 = data.get("lamp_brightness")?;
let lamp_color: &Rgb = data.get("lamp_color")?;
let lamp_pos: &Vec2 = data.get("lamp_pos")?;
//--snip--
}
This added flexibility enables us to be a lot smarter about how we manage driver data. Gone are the days of creating an entire buffer just to store one value; express this information through whatever data structures make the most sense.
Filters
replaced in favor of Data
, TimeInfo
renamed to Time
.
Since data can now associate a value of any type with a key, there's no reason to keep Filters
around.
// spatial_led 0.2.0
fn compute(
sled: &Sled,
buffers: &mut BufferContainer,
filters: &mut Filters,
time_info: &TimeInfo
) -> SledResult {
//--snip--
}
driver.set_compute_commands(compute);
Becomes
// spatial_led 0.3.0
fn compute(sled: &Sled<Rgb>, data: &mut Data, time: &Time) -> SledResult {
//--snip--
}
driver.set_compute_commands(compute);
Driver Macros are gone.
You'll notice from the example above that driver command method signatures are way less verbose after these changes. After some debate, I decided that:
#[draw_commands]
fn draw(sled: &mut Sled<Rgb>) -> SledResult {
//--snip--
}
Is only so much better than writing
fn draw(sled: &Sled<Rgb>, _: &Data, _: &Time) -> SledResult {
//--snip--
}
Further, with generic type annotations required on Sled
, we'd have to pass in our underlying color format through the macro. That would probably would look something like this:
#[startup_commands(Rgb)]
fn startup(data: &mut Data) -> SledResult {
//--snip--
}
To keep things simple for new users and decrease compile times, I've pulled the plug on driver macros. They could come back in the future, but they probably won't. If you're looking for another way to save yourself some boilerplate, this pattern is still totally valid:
driver.set_draw_commands(|sled, _, time| {
//--snip--
});
Full Changelog
Full Changelog: 0.2.0...0.3.0
0.2.0
Breaking Changes from 0.1.1
- In order to support Error handling on
no_std
systems, we had to bump the MSRV up to 1.81 - The previously deprecated
Scheduler.change_hz()
method has been removed in favor ofScheduler.set_hz()
Sled::new_from_string(String)
andConfig::from_string(String)
removed in favor ofSled::new_from_str(&str)
andConfig::from_str(&str)
Added
-
Crate now supports most
no_std
environments thanks to some fantastic work done by @claudiomattera- Introduces
CustomDriver
andCustomScheduler
which allows you to create Drivers and Schedulers backed by custom Instant and Sleeper implementations. - Also introduces
AsyncCustomScheduler
- Introduces a
libm
feature flag forno_std
environments that'll need it.
- Introduces
-
Changed
- Examples have been extracted to the spatial_led_examples, bringing down our development dependencies considerably. This will also allow us to share more environment-specific examples, like Raspberry Pi or ESP32 implementations.
- Documentation improvements.
New Contributors
- @claudiomattera made their first contribution in #86
Full Changelog: 0.1.1...0.2.0
0.1.1
Full Changelog: 0.1.0...0.1.1
Added
scheduler.set_hz()
method- Added a new example: Scan
- Added a README file to the examples folder with a preview for each example
- Upgraded dev dependency ratatui from 0.28 to 0.29
- Improved documentation and test coverage
Changed
scheduler.change_hz()
deprecated in favor ofscheduler.set_hz()
for consistency.
Fixed
- Fixed issue where
sled.set_segment()
would panic on an invalid segment index instead of return an error.