Skip to content

Commit 73c6479

Browse files
Add no_std support to bevy_color (bevyengine#16633)
# Objective - Contributes to bevyengine#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
1 parent 4be7530 commit 73c6479

File tree

9 files changed

+48
-15
lines changed

9 files changed

+48
-15
lines changed

crates/bevy_color/Cargo.toml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,26 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
1717
"bevy",
1818
], optional = true }
1919
bytemuck = { version = "1", features = ["derive"] }
20-
serde = { version = "1.0", features = ["derive"], optional = true }
20+
serde = { version = "1.0", features = [
21+
"derive",
22+
], default-features = false, optional = true }
2123
derive_more = { version = "1", default-features = false, features = [
2224
"error",
2325
"from",
2426
"display",
2527
] }
2628
wgpu-types = { version = "23", default-features = false, optional = true }
27-
encase = { version = "0.10", default-features = false }
29+
encase = { version = "0.10", default-features = false, optional = true }
2830

2931
[features]
30-
default = ["bevy_reflect"]
32+
default = ["std", "bevy_reflect", "encase"]
33+
std = ["alloc", "bevy_math/std", "serde?/std"]
34+
alloc = ["bevy_math/alloc", "serde?/alloc"]
3135
serialize = ["serde", "bevy_math/serialize"]
36+
bevy_reflect = ["dep:bevy_reflect", "std"]
37+
wgpu-types = ["dep:wgpu-types", "std"]
38+
encase = ["dep:encase", "std"]
39+
libm = ["bevy_math/libm"]
3240

3341
[lints]
3442
workspace = true

crates/bevy_color/src/color_difference.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
//! Module for calculating distance between two colors in the same color space.
22
3+
use bevy_math::ops;
4+
35
/// Calculate the distance between this and another color as if they were coordinates
46
/// in a Euclidean space. Alpha is not considered in the distance calculation.
57
pub trait EuclideanDistance: Sized {
68
/// Distance from `self` to `other`.
79
fn distance(&self, other: &Self) -> f32 {
8-
self.distance_squared(other).sqrt()
10+
ops::sqrt(self.distance_squared(other))
911
}
1012

1113
/// Distance squared from `self` to `other`.

crates/bevy_color/src/color_gradient.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::Mix;
2+
use alloc::vec::Vec;
23
use bevy_math::curve::{
34
cores::{EvenCore, EvenCoreError},
45
Curve, Interval,

crates/bevy_color/src/color_ops.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bevy_math::{Vec3, Vec4};
1+
use bevy_math::{ops, Vec3, Vec4};
22

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

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

138138
#[cfg(test)]

crates/bevy_color/src/hwba.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use crate::{
66
Alpha, ColorToComponents, Gray, Hue, Lcha, LinearRgba, Mix, Srgba, StandardColor, Xyza,
77
};
8-
use bevy_math::{Vec3, Vec4};
8+
use bevy_math::{ops, Vec3, Vec4};
99
#[cfg(feature = "bevy_reflect")]
1010
use bevy_reflect::prelude::*;
1111

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

241241
let h = (hue % 360.) / 60.;
242-
let i = h.floor();
242+
let i = ops::floor(h);
243243
let f = h - i;
244244

245245
let i = i as u8;

crates/bevy_color/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
html_logo_url = "https://bevyengine.org/assets/icon.png",
55
html_favicon_url = "https://bevyengine.org/assets/icon.png"
66
)]
7+
#![cfg_attr(not(feature = "std"), no_std)]
78

89
//! Representations of colors in various color spaces.
910
//!
@@ -89,8 +90,12 @@
8990
//! println!("Hsla: {:?}", hsla);
9091
//! ```
9192
93+
#[cfg(feature = "alloc")]
94+
extern crate alloc;
95+
9296
mod color;
9397
pub mod color_difference;
98+
#[cfg(feature = "alloc")]
9499
mod color_gradient;
95100
mod color_ops;
96101
mod color_range;
@@ -121,6 +126,7 @@ pub mod prelude {
121126
}
122127

123128
pub use color::*;
129+
#[cfg(feature = "alloc")]
124130
pub use color_gradient::*;
125131
pub use color_ops::*;
126132
pub use color_range::*;

crates/bevy_color/src/linear_rgba.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
33
ColorToPacked, Gray, Luminance, Mix, StandardColor,
44
};
5-
use bevy_math::{Vec3, Vec4};
5+
use bevy_math::{ops, Vec3, Vec4};
66
#[cfg(feature = "bevy_reflect")]
77
use bevy_reflect::prelude::*;
88
use bytemuck::{Pod, Zeroable};
@@ -302,11 +302,11 @@ impl ColorToComponents for LinearRgba {
302302
impl ColorToPacked for LinearRgba {
303303
fn to_u8_array(self) -> [u8; 4] {
304304
[self.red, self.green, self.blue, self.alpha]
305-
.map(|v| (v.clamp(0.0, 1.0) * 255.0).round() as u8)
305+
.map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
306306
}
307307

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

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

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

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

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

366+
#[cfg(feature = "encase")]
364367
impl encase::private::ReadFrom for LinearRgba {
365368
fn read_from<B: encase::private::BufferRef>(
366369
&mut self,
@@ -380,6 +383,7 @@ impl encase::private::ReadFrom for LinearRgba {
380383
}
381384
}
382385

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

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

405410
#[cfg(test)]

crates/bevy_color/src/srgba.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use crate::{
22
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
33
ColorToPacked, Gray, LinearRgba, Luminance, Mix, StandardColor, Xyza,
44
};
5+
#[cfg(feature = "alloc")]
6+
use alloc::{format, string::String};
57
use bevy_math::{ops, Vec3, Vec4};
68
#[cfg(feature = "bevy_reflect")]
79
use bevy_reflect::prelude::*;
@@ -167,6 +169,7 @@ impl Srgba {
167169
}
168170

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

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

376379
fn from_u8_array(color: [u8; 4]) -> Self {

tools/ci/src/commands/compile_check_no_std.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ impl Prepare for CompileCheckNoStdCommand {
8686
"Please fix compiler errors in output above for bevy_math no_std compatibility.",
8787
));
8888

89+
commands.push(PreparedCommand::new::<Self>(
90+
cmd!(
91+
sh,
92+
"cargo check -p bevy_color --no-default-features --features libm --target {target}"
93+
),
94+
"Please fix compiler errors in output above for bevy_color no_std compatibility.",
95+
));
96+
8997
commands
9098
}
9199
}

0 commit comments

Comments
 (0)