Skip to content

Commit

Permalink
Merge pull request #86 from claudiomattera/no_std
Browse files Browse the repository at this point in the history
Make crate compatible with no_std
  • Loading branch information
DavJCosby authored Nov 14, 2024
2 parents 2743f2a + 99f7c61 commit d08b1ca
Show file tree
Hide file tree
Showing 23 changed files with 391 additions and 113 deletions.
18 changes: 10 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,22 @@ documentation = "https://docs.rs/spatial_led"
exclude = ["*.gif", "*.cast"]

[features]
default = ["drivers", "scheduler"]
default = ["drivers", "scheduler", "std"]
drivers = ["compact_str", "sled_driver_macros"]
scheduler = ["spin_sleep"]
scheduler = []
named_colors = []
std = ["glam/std", "palette/std"]
libm = ["glam/libm", "palette/libm"]
async = []
spin_sleep = ["std", "dep:spin_sleep"]

[dependencies]
glam = { version = "0.29" }
palette = { version = "0.7", default-features = false, features = [
"std",
"approx",
] }
glam = { version = "0.29", default-features = false, features = [] }
palette = { version = "0.7", default-features = false, features = ["approx"] }
smallvec = "1.13"
compact_str = { version = "0.8", optional = true }
compact_str = { version = "0.8", default-features = false, optional = true }
sled_driver_macros = { version = "0.1.2", optional = true }
num-traits = { version = "0.2", default-features = false }
spin_sleep = { version = "1.2", optional = true }

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion examples/drivers/comet.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use spatial_led::driver_macros::*;
use spatial_led::driver::{Driver, TimeInfo};
use spatial_led::driver_macros::*;
use spatial_led::SledResult;
use spatial_led::{color::Rgb, Sled};

Expand Down
2 changes: 1 addition & 1 deletion examples/drivers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod comet;
pub mod ripples;
pub mod scan;
pub mod warpspeed;
pub mod scan;
2 changes: 1 addition & 1 deletion examples/drivers/ripples.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use spatial_led::driver_macros::*;
use rand::Rng;
use spatial_led::driver::{BufferContainer, Driver, TimeInfo};
use spatial_led::driver_macros::*;
use spatial_led::SledResult;
use spatial_led::{color::Rgb, Sled, Vec2};
use std::ops::Range;
Expand Down
2 changes: 1 addition & 1 deletion examples/drivers/warpspeed.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use spatial_led::driver_macros::*;
use rand::Rng;
use spatial_led::driver::{BufferContainer, Driver, TimeInfo};
use spatial_led::driver_macros::*;
use spatial_led::SledResult;
use spatial_led::{color::Rgb, Sled, Vec2};

Expand Down
2 changes: 1 addition & 1 deletion src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub mod consts {
//!
//! 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:
Expand Down
17 changes: 13 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
use alloc::string::String;
use alloc::string::ToString as _;
use alloc::vec;
use alloc::vec::Vec;

use crate::error::SledError;
use core::str::Lines;
use glam::Vec2;
use smallvec::SmallVec;
use std::{fs, str::Lines};

#[cfg(not(feature = "std"))]
use num_traits::float::Float as _;

pub(crate) struct Config {
pub center_point: Vec2,
Expand Down Expand Up @@ -95,7 +103,7 @@ fn extract_segments_from_string(s: &str) -> Vec<LineSegment> {
}

impl Config {
pub fn from_string(string: String) -> Result<Self, SledError> {
pub fn from_string(string: &str) -> Result<Self, SledError> {
let mut lines = string.lines();

let (center, density) = extract_center_and_density_from_lines(&mut lines);
Expand All @@ -121,9 +129,10 @@ impl Config {
})
}

#[cfg(feature = "std")]
pub fn from_toml_file(path: &str) -> Result<Self, SledError> {
let as_string = fs::read_to_string(path).map_err(SledError::from_error)?;
Config::from_string(as_string)
let as_string = std::fs::read_to_string(path).map_err(SledError::from_error)?;
Config::from_string(&as_string)
}
}

Expand Down
26 changes: 15 additions & 11 deletions src/driver/buffers.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
use std::{
use core::{
any::{type_name, Any},
fmt::Debug,
};

use alloc::boxed::Box;
use alloc::collections::BTreeMap;
use alloc::format;
use alloc::vec::Vec;

use compact_str::{CompactString, ToCompactString};
use std::collections::HashMap;

use crate::SledError;

#[derive(Debug)]
pub struct BufferContainer {
buffers: HashMap<CompactString, Box<dyn Buffer>>,
buffers: BTreeMap<CompactString, Box<dyn Buffer>>,
}

impl BufferContainer {
pub fn new() -> Self {
BufferContainer {
buffers: HashMap::new(),
buffers: BTreeMap::new(),
}
}

Expand Down Expand Up @@ -235,18 +239,18 @@ impl BufferContainer {
Ok(())
}

pub fn iter(&self) -> std::collections::hash_map::Iter<CompactString, Box<dyn Buffer>> {
pub fn iter(&self) -> alloc::collections::btree_map::Iter<CompactString, Box<dyn Buffer>> {
self.buffers.iter()
}

pub fn iter_mut(
&mut self,
) -> std::collections::hash_map::IterMut<CompactString, Box<dyn Buffer>> {
) -> alloc::collections::btree_map::IterMut<CompactString, Box<dyn Buffer>> {
self.buffers.iter_mut()
}
}

pub trait Buffer: std::fmt::Debug {
pub trait Buffer: core::fmt::Debug {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
Expand All @@ -264,16 +268,16 @@ impl<T: BufferableData + Debug> Buffer for Vec<T> {
}
}

impl std::iter::IntoIterator for BufferContainer {
impl core::iter::IntoIterator for BufferContainer {
type Item = (CompactString, Box<dyn Buffer>);
type IntoIter = std::collections::hash_map::IntoIter<CompactString, Box<dyn Buffer>>;
type IntoIter = alloc::collections::btree_map::IntoIter<CompactString, Box<dyn Buffer>>;

fn into_iter(self) -> Self::IntoIter {
self.buffers.into_iter()
}
}

impl std::iter::FromIterator<(CompactString, Box<dyn Buffer>)> for BufferContainer {
impl core::iter::FromIterator<(CompactString, Box<dyn Buffer>)> for BufferContainer {
fn from_iter<T: IntoIterator<Item = (CompactString, Box<dyn Buffer>)>>(iter: T) -> Self {
let mut bc = BufferContainer::new();

Expand All @@ -285,7 +289,7 @@ impl std::iter::FromIterator<(CompactString, Box<dyn Buffer>)> for BufferContain
}
}

impl std::iter::Extend<(CompactString, Box<dyn Buffer>)> for BufferContainer {
impl core::iter::Extend<(CompactString, Box<dyn Buffer>)> for BufferContainer {
fn extend<T: IntoIterator<Item = (CompactString, Box<dyn Buffer>)>>(&mut self, iter: T) {
for (key, value) in iter {
self.buffers.insert(key, value);
Expand Down
15 changes: 9 additions & 6 deletions src/driver/filters.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::{Filter, SledError};
use alloc::collections::BTreeMap;
use alloc::format;

use compact_str::{CompactString, ToCompactString};
use std::collections::HashMap;

use crate::{Filter, SledError};

#[derive(Clone, Debug)]
pub struct Filters {
map: HashMap<CompactString, Filter>,
map: BTreeMap<CompactString, Filter>,
}

impl Default for Filters {
Expand All @@ -16,7 +19,7 @@ impl Default for Filters {
impl Filters {
pub fn new() -> Self {
Filters {
map: HashMap::new(),
map: BTreeMap::new(),
}
}

Expand All @@ -30,14 +33,14 @@ impl Filters {
.ok_or_else(|| SledError::new(format!("No filter found with key '{}'", key)))
}

pub fn iter(&self) -> std::collections::hash_map::Iter<CompactString, Filter> {
pub fn iter(&self) -> alloc::collections::btree_map::Iter<CompactString, Filter> {
self.map.iter()
}
}

impl IntoIterator for Filters {
type Item = (CompactString, Filter);
type IntoIter = std::collections::hash_map::IntoIter<CompactString, Filter>;
type IntoIter = alloc::collections::btree_map::IntoIter<CompactString, Filter>;

fn into_iter(self) -> Self::IntoIter {
self.map.into_iter()
Expand Down
52 changes: 34 additions & 18 deletions src/driver/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
use core::time::Duration;

use alloc::boxed::Box;

use crate::{
color::{Rgb, Srgb},
time::Instant,
Led, Sled, SledError, Vec2,
};

use std::time::{Duration, Instant};
/// A driver representing instants with `std::time::Instant`
#[cfg(feature = "std")]
pub type Driver = CustomDriver<std::time::Instant>;

mod filters;
// mod sliders;
Expand All @@ -26,26 +33,32 @@ type DrawCommands = Box<dyn Fn(&mut Sled, &BufferContainer, &Filters, &TimeInfo)
/// 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 {
pub struct CustomDriver<INSTANT>
where
INSTANT: Instant,
{
sled: Option<Sled>,
startup_commands: StartupCommands,
compute_commands: ComputeCommands,
draw_commands: DrawCommands,
startup: Instant,
last_update: Instant,
startup: INSTANT,
last_update: INSTANT,
buffers: BufferContainer,
filters: Filters,
}

impl Driver {
impl<INSTANT> CustomDriver<INSTANT>
where
INSTANT: Instant,
{
pub fn new() -> Self {
Driver {
CustomDriver {
sled: None,
startup_commands: Box::new(|_, _, _| Ok(())),
compute_commands: Box::new(|_, _, _, _| Ok(())),
draw_commands: Box::new(|_, _, _, _| Ok(())),
startup: Instant::now(),
last_update: Instant::now(),
startup: INSTANT::now(),
last_update: INSTANT::now(),
buffers: BufferContainer::new(),
filters: Filters::new(),
}
Expand All @@ -61,7 +74,7 @@ impl Driver {
self.startup.elapsed()
}

/// Define commands to be called as soon as a Sled is [mounted](Driver::mount) to the driver. This is a good place to initialize important buffer values.
/// Define commands to be called as soon as a Sled is [mounted](CustomDriver::mount) to the driver. This is a good place to initialize important buffer values.
/// ```rust
/// # use spatial_led::{Vec2, BufferContainer, SledResult, driver::Driver};
/// use spatial_led::driver_macros::*;
Expand Down Expand Up @@ -91,7 +104,7 @@ impl Driver {
self.startup_commands = Box::new(startup_commands);
}

/// Define commands to be called each time [Driver::step()] is called, right before we run [draw commands](Driver::set_draw_commands).
/// Define commands to be called each time [CustomDriver::step()] is called, right before we run [draw commands](CustomDriver::set_draw_commands).
/// ```rust
/// # use spatial_led::{Vec2, BufferContainer, TimeInfo, SledResult, driver::Driver};
/// use spatial_led::driver_macros::*;
Expand Down Expand Up @@ -122,7 +135,7 @@ impl Driver {
self.compute_commands = Box::new(compute_commands);
}

/// Define commands to be called each time [Driver::step()] is called, right after we run [compute commands](Driver::set_compute_commands).
/// Define commands to be called each time [CustomDriver::step()] is called, right after we run [compute commands](CustomDriver::set_compute_commands).
/// ```rust
/// # use spatial_led::{Sled, Vec2, color::Rgb, BufferContainer, TimeInfo, SledResult, driver::Driver};
/// use spatial_led::driver_macros::*;
Expand All @@ -131,7 +144,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::<Vec2>("positions")?;
/// let center = sled.center_point();
Expand All @@ -157,23 +170,23 @@ impl Driver {
self.draw_commands = Box::new(draw_commands);
}

/// Takes ownership of the given Sled and runs the Driver's [startup commands](Driver::set_startup_commands).
/// Takes ownership of the given Sled and runs the Driver's [startup commands](CustomDriver::set_startup_commands).
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.startup = INSTANT::now();
self.last_update = self.startup;
self.sled = Some(sled);
}

/// Runs the Driver's [compute commands](Driver::set_compute_commands) first, and then runs its [draw commands](Driver::set_draw_commands).
/// Runs the Driver's [compute commands](CustomDriver::set_compute_commands) first, and then runs its [draw commands](CustomDriver::set_draw_commands).
pub fn step(&mut self) {
if let Some(sled) = &mut self.sled {
let time_info = TimeInfo {
elapsed: self.startup.elapsed(),
delta: self.last_update.elapsed(),
};

self.last_update = Instant::now();
self.last_update = INSTANT::now();
(self.compute_commands)(sled, &mut self.buffers, &mut self.filters, &time_info)
.unwrap();
(self.draw_commands)(sled, &self.buffers, &self.filters, &time_info).unwrap();
Expand All @@ -185,7 +198,7 @@ impl Driver {
self.step();
}

/// Returns full ownership over the Driver's assigned Sled. Panics if [Driver::mount()] was never called.
/// Returns full ownership over the Driver's assigned Sled. Panics if [CustomDriver::mount()] was never called.
pub fn dismount(&mut self) -> Sled {
self.sled.take().unwrap()
}
Expand Down Expand Up @@ -252,7 +265,10 @@ impl Driver {
}
}

impl Default for Driver {
impl<INSTANT> Default for CustomDriver<INSTANT>
where
INSTANT: Instant,
{
fn default() -> Self {
Self::new()
}
Expand Down
Loading

0 comments on commit d08b1ca

Please sign in to comment.