Skip to content

Commit

Permalink
Add no_std support to bevy_color (#16633)
Browse files Browse the repository at this point in the history
# Objective

- Contributes to #15460

## Solution

- Added the following new features: 
  - `std` (default)
  - `alloc`
  - `encase` (default)
  - `libm`

## Testing

- Added to `compile-check-no-std` CI command

## Notes

- `ColorCurve` requires `alloc` due to how the underlying `EvenCore`
type works.
- `Srgba::to_hex` requires `alloc` to return a `String`.
- This was otherwise a _very_ simple change
  • Loading branch information
bushrat011899 authored Dec 5, 2024
1 parent 4be7530 commit 73c6479
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 15 deletions.
14 changes: 11 additions & 3 deletions crates/bevy_color/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,26 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
"bevy",
], optional = true }
bytemuck = { version = "1", features = ["derive"] }
serde = { version = "1.0", features = ["derive"], optional = true }
serde = { version = "1.0", features = [
"derive",
], default-features = false, optional = true }
derive_more = { version = "1", default-features = false, features = [
"error",
"from",
"display",
] }
wgpu-types = { version = "23", default-features = false, optional = true }
encase = { version = "0.10", default-features = false }
encase = { version = "0.10", default-features = false, optional = true }

[features]
default = ["bevy_reflect"]
default = ["std", "bevy_reflect", "encase"]
std = ["alloc", "bevy_math/std", "serde?/std"]
alloc = ["bevy_math/alloc", "serde?/alloc"]
serialize = ["serde", "bevy_math/serialize"]
bevy_reflect = ["dep:bevy_reflect", "std"]
wgpu-types = ["dep:wgpu-types", "std"]
encase = ["dep:encase", "std"]
libm = ["bevy_math/libm"]

[lints]
workspace = true
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_color/src/color_difference.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! Module for calculating distance between two colors in the same color space.
use bevy_math::ops;

/// Calculate the distance between this and another color as if they were coordinates
/// in a Euclidean space. Alpha is not considered in the distance calculation.
pub trait EuclideanDistance: Sized {
/// Distance from `self` to `other`.
fn distance(&self, other: &Self) -> f32 {
self.distance_squared(other).sqrt()
ops::sqrt(self.distance_squared(other))
}

/// Distance squared from `self` to `other`.
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_color/src/color_gradient.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::Mix;
use alloc::vec::Vec;
use bevy_math::curve::{
cores::{EvenCore, EvenCoreError},
Curve, Interval,
Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_color/src/color_ops.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy_math::{Vec3, Vec4};
use bevy_math::{ops, Vec3, Vec4};

/// Methods for changing the luminance of a color. Note that these methods are not
/// guaranteed to produce consistent results across color spaces,
Expand Down Expand Up @@ -90,7 +90,7 @@ pub trait Hue: Sized {

/// Return a new version of this color with the hue channel rotated by the given degrees.
fn rotate_hue(&self, degrees: f32) -> Self {
let rotated_hue = (self.hue() + degrees).rem_euclid(360.);
let rotated_hue = ops::rem_euclid(self.hue() + degrees, 360.);
self.with_hue(rotated_hue)
}
}
Expand Down Expand Up @@ -131,8 +131,8 @@ pub trait ColorToPacked {
/// takes the shortest path around the color wheel, and that the result is always between
/// 0 and 360.
pub(crate) fn lerp_hue(a: f32, b: f32, t: f32) -> f32 {
let diff = (b - a + 180.0).rem_euclid(360.) - 180.;
(a + diff * t).rem_euclid(360.0)
let diff = ops::rem_euclid(b - a + 180.0, 360.) - 180.;
ops::rem_euclid(a + diff * t, 360.)
}

#[cfg(test)]
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_color/src/hwba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use crate::{
Alpha, ColorToComponents, Gray, Hue, Lcha, LinearRgba, Mix, Srgba, StandardColor, Xyza,
};
use bevy_math::{Vec3, Vec4};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;

Expand Down Expand Up @@ -239,7 +239,7 @@ impl From<Hwba> for Srgba {
let v = 1. - blackness;

let h = (hue % 360.) / 60.;
let i = h.floor();
let i = ops::floor(h);
let f = h - i;

let i = i as u8;
Expand Down
6 changes: 6 additions & 0 deletions crates/bevy_color/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
html_logo_url = "https://bevyengine.org/assets/icon.png",
html_favicon_url = "https://bevyengine.org/assets/icon.png"
)]
#![cfg_attr(not(feature = "std"), no_std)]

//! Representations of colors in various color spaces.
//!
Expand Down Expand Up @@ -89,8 +90,12 @@
//! println!("Hsla: {:?}", hsla);
//! ```
#[cfg(feature = "alloc")]
extern crate alloc;

mod color;
pub mod color_difference;
#[cfg(feature = "alloc")]
mod color_gradient;
mod color_ops;
mod color_range;
Expand Down Expand Up @@ -121,6 +126,7 @@ pub mod prelude {
}

pub use color::*;
#[cfg(feature = "alloc")]
pub use color_gradient::*;
pub use color_ops::*;
pub use color_range::*;
Expand Down
11 changes: 8 additions & 3 deletions crates/bevy_color/src/linear_rgba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
ColorToPacked, Gray, Luminance, Mix, StandardColor,
};
use bevy_math::{Vec3, Vec4};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
use bytemuck::{Pod, Zeroable};
Expand Down Expand Up @@ -302,11 +302,11 @@ impl ColorToComponents for LinearRgba {
impl ColorToPacked for LinearRgba {
fn to_u8_array(self) -> [u8; 4] {
[self.red, self.green, self.blue, self.alpha]
.map(|v| (v.clamp(0.0, 1.0) * 255.0).round() as u8)
.map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
}

fn to_u8_array_no_alpha(self) -> [u8; 3] {
[self.red, self.green, self.blue].map(|v| (v.clamp(0.0, 1.0) * 255.0).round() as u8)
[self.red, self.green, self.blue].map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
}

fn from_u8_array(color: [u8; 4]) -> Self {
Expand All @@ -332,6 +332,7 @@ impl From<LinearRgba> for wgpu_types::Color {

// [`LinearRgba`] is intended to be used with shaders
// So it's the only color type that implements [`ShaderType`] to make it easier to use inside shaders
#[cfg(feature = "encase")]
impl encase::ShaderType for LinearRgba {
type ExtraMetadata = ();

Expand All @@ -353,6 +354,7 @@ impl encase::ShaderType for LinearRgba {
const UNIFORM_COMPAT_ASSERT: fn() = || {};
}

#[cfg(feature = "encase")]
impl encase::private::WriteInto for LinearRgba {
fn write_into<B: encase::private::BufferMut>(&self, writer: &mut encase::private::Writer<B>) {
for el in &[self.red, self.green, self.blue, self.alpha] {
Expand All @@ -361,6 +363,7 @@ impl encase::private::WriteInto for LinearRgba {
}
}

#[cfg(feature = "encase")]
impl encase::private::ReadFrom for LinearRgba {
fn read_from<B: encase::private::BufferRef>(
&mut self,
Expand All @@ -380,6 +383,7 @@ impl encase::private::ReadFrom for LinearRgba {
}
}

#[cfg(feature = "encase")]
impl encase::private::CreateFrom for LinearRgba {
fn create_from<B>(reader: &mut encase::private::Reader<B>) -> Self
where
Expand All @@ -400,6 +404,7 @@ impl encase::private::CreateFrom for LinearRgba {
}
}

#[cfg(feature = "encase")]
impl encase::ShaderSize for LinearRgba {}

#[cfg(test)]
Expand Down
7 changes: 5 additions & 2 deletions crates/bevy_color/src/srgba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use crate::{
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
ColorToPacked, Gray, LinearRgba, Luminance, Mix, StandardColor, Xyza,
};
#[cfg(feature = "alloc")]
use alloc::{format, string::String};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
Expand Down Expand Up @@ -167,6 +169,7 @@ impl Srgba {
}

/// Convert this color to CSS-style hexadecimal notation.
#[cfg(feature = "alloc")]
pub fn to_hex(&self) -> String {
let [r, g, b, a] = self.to_u8_array();
match a {
Expand Down Expand Up @@ -366,11 +369,11 @@ impl ColorToComponents for Srgba {
impl ColorToPacked for Srgba {
fn to_u8_array(self) -> [u8; 4] {
[self.red, self.green, self.blue, self.alpha]
.map(|v| (v.clamp(0.0, 1.0) * 255.0).round() as u8)
.map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
}

fn to_u8_array_no_alpha(self) -> [u8; 3] {
[self.red, self.green, self.blue].map(|v| (v.clamp(0.0, 1.0) * 255.0).round() as u8)
[self.red, self.green, self.blue].map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
}

fn from_u8_array(color: [u8; 4]) -> Self {
Expand Down
8 changes: 8 additions & 0 deletions tools/ci/src/commands/compile_check_no_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ impl Prepare for CompileCheckNoStdCommand {
"Please fix compiler errors in output above for bevy_math no_std compatibility.",
));

commands.push(PreparedCommand::new::<Self>(
cmd!(
sh,
"cargo check -p bevy_color --no-default-features --features libm --target {target}"
),
"Please fix compiler errors in output above for bevy_color no_std compatibility.",
));

commands
}
}

0 comments on commit 73c6479

Please sign in to comment.