Skip to content

Commit 46af466

Browse files
Add no_std support to bevy_input (#16995)
# Objective - Contributes to #15460 ## Solution - Added the following features: - `std` (default) - `smol_str` (default) - `portable-atomic` - `critical-section` - `libm` - Fixed an existing issue where `bevy_reflect` wasn't properly feature gated. ## Testing - CI ## Notes - There were some minor issues with `bevy_math` and `bevy_ecs` noticed in this PR which I have also resolved here. I can split these out if desired, but I've left them here for now as they're very small changes and I don't consider this PR itself to be very controversial. - `libm`, `portable-atomic`, and `critical-section` are shortcuts to enable the relevant features in dependencies, making the usage of this crate on atomically challenged platforms possible and simpler. - `smol_str` is gated as it doesn't support atomically challenged platforms (e.g., Raspberry Pi Pico). I have an issue and a [PR](rust-analyzer/smol_str#91) to discuss this upstream.
1 parent 6114347 commit 46af466

File tree

7 files changed

+111
-54
lines changed

7 files changed

+111
-54
lines changed

crates/bevy_ecs/src/name.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ use core::{
1313
};
1414

1515
#[cfg(feature = "serialize")]
16-
use serde::{
17-
de::{Error, Visitor},
18-
Deserialize, Deserializer, Serialize, Serializer,
16+
use {
17+
alloc::string::ToString,
18+
serde::{
19+
de::{Error, Visitor},
20+
Deserialize, Deserializer, Serialize, Serializer,
21+
},
1922
};
2023

2124
#[cfg(feature = "bevy_reflect")]

crates/bevy_input/Cargo.toml

+50-14
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,72 @@ license = "MIT OR Apache-2.0"
99
keywords = ["bevy"]
1010

1111
[features]
12-
default = ["bevy_reflect"]
12+
default = ["std", "bevy_reflect", "bevy_ecs/async_executor", "smol_str"]
13+
14+
# Functionality
15+
16+
## Adds runtime reflection support using `bevy_reflect`.
1317
bevy_reflect = [
1418
"dep:bevy_reflect",
1519
"bevy_app/bevy_reflect",
1620
"bevy_ecs/bevy_reflect",
1721
"bevy_math/bevy_reflect",
1822
]
19-
serialize = ["serde", "smol_str/serde"]
23+
24+
## Adds serialization support through `serde`.
25+
serialize = [
26+
"serde",
27+
"smol_str/serde",
28+
"bevy_ecs/serialize",
29+
"bevy_math/serialize",
30+
]
31+
32+
## Uses the small-string optimization provided by `smol_str`.
33+
smol_str = ["dep:smol_str", "bevy_reflect/smol_str"]
34+
35+
# Platform Compatibility
36+
37+
## Allows access to the `std` crate. Enabling this feature will prevent compilation
38+
## on `no_std` targets, but provides access to certain additional features on
39+
## supported platforms.
40+
std = [
41+
"bevy_app/std",
42+
"bevy_ecs/std",
43+
"bevy_math/std",
44+
"bevy_utils/std",
45+
"bevy_reflect/std",
46+
]
47+
48+
## `critical-section` provides the building blocks for synchronization primitives
49+
## on all platforms, including `no_std`.
50+
critical-section = ["bevy_app/critical-section", "bevy_ecs/critical-section"]
51+
52+
## `portable-atomic` provides additional platform support for atomic types and
53+
## operations, even on targets without native support.
54+
portable-atomic = ["bevy_app/portable-atomic", "bevy_ecs/portable-atomic"]
55+
56+
## Uses the `libm` maths library instead of the one provided in `std` and `core`.
57+
libm = ["bevy_math/libm"]
2058

2159
[dependencies]
2260
# bevy
2361
bevy_app = { path = "../bevy_app", version = "0.15.0-dev", default-features = false }
24-
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev", default-features = false, features = [
25-
"serialize",
26-
] }
27-
bevy_math = { path = "../bevy_math", version = "0.15.0-dev", default-features = false, features = [
28-
"rand",
29-
"serialize",
30-
] }
31-
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
62+
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev", default-features = false }
63+
bevy_math = { path = "../bevy_math", version = "0.15.0-dev", default-features = false }
64+
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev", default-features = false }
3265
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
3366
"glam",
34-
"smol_str",
35-
], optional = true }
67+
], default-features = false, optional = true }
3668

3769
# other
38-
serde = { version = "1", features = ["derive"], optional = true }
70+
serde = { version = "1", features = [
71+
"alloc",
72+
"derive",
73+
], default-features = false, optional = true }
3974
thiserror = { version = "2", default-features = false }
4075
derive_more = { version = "1", default-features = false, features = ["from"] }
41-
smol_str = "0.2"
76+
smol_str = { version = "0.2", default-features = false, optional = true }
77+
log = { version = "0.4", default-features = false }
4278

4379
[lints]
4480
workspace = true

crates/bevy_input/src/gamepad.rs

+34-34
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! The gamepad input functionality.
22
33
use crate::{Axis, ButtonInput, ButtonState};
4+
use alloc::string::String;
45
#[cfg(feature = "bevy_reflect")]
56
use bevy_ecs::prelude::ReflectComponent;
67
use bevy_ecs::{
@@ -12,16 +13,15 @@ use bevy_ecs::{
1213
prelude::require,
1314
system::{Commands, Query},
1415
};
16+
use bevy_math::ops;
1517
use bevy_math::Vec2;
1618
#[cfg(feature = "bevy_reflect")]
1719
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
1820
#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
1921
use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
20-
use bevy_utils::{
21-
tracing::{info, warn},
22-
Duration, HashMap,
23-
};
22+
use bevy_utils::{Duration, HashMap};
2423
use derive_more::derive::From;
24+
use log::{info, warn};
2525
use thiserror::Error;
2626

2727
/// A gamepad event.
@@ -54,11 +54,11 @@ pub enum GamepadEvent {
5454
/// the in-frame relative ordering of events is important.
5555
///
5656
/// This event type is used by `bevy_input` to feed its components.
57-
#[derive(Event, Debug, Clone, PartialEq, Reflect, From)]
58-
#[reflect(Debug, PartialEq)]
57+
#[derive(Event, Debug, Clone, PartialEq, From)]
58+
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
59+
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
5960
#[cfg_attr(
60-
feature = "serialize",
61-
derive(serde::Serialize, serde::Deserialize),
61+
all(feature = "serialize", feature = "bevy_reflect"),
6262
reflect(Serialize, Deserialize)
6363
)]
6464
pub enum RawGamepadEvent {
@@ -71,11 +71,11 @@ pub enum RawGamepadEvent {
7171
}
7272

7373
/// [`GamepadButton`] changed event unfiltered by [`GamepadSettings`]
74-
#[derive(Event, Debug, Copy, Clone, PartialEq, Reflect)]
75-
#[reflect(Debug, PartialEq)]
74+
#[derive(Event, Debug, Copy, Clone, PartialEq)]
75+
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
76+
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
7677
#[cfg_attr(
77-
feature = "serialize",
78-
derive(serde::Serialize, serde::Deserialize),
78+
all(feature = "serialize", feature = "bevy_reflect"),
7979
reflect(Serialize, Deserialize)
8080
)]
8181
pub struct RawGamepadButtonChangedEvent {
@@ -99,11 +99,11 @@ impl RawGamepadButtonChangedEvent {
9999
}
100100

101101
/// [`GamepadAxis`] changed event unfiltered by [`GamepadSettings`]
102-
#[derive(Event, Debug, Copy, Clone, PartialEq, Reflect)]
103-
#[reflect(Debug, PartialEq)]
102+
#[derive(Event, Debug, Copy, Clone, PartialEq)]
103+
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
104+
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
104105
#[cfg_attr(
105-
feature = "serialize",
106-
derive(serde::Serialize, serde::Deserialize),
106+
all(feature = "serialize", feature = "bevy_reflect"),
107107
reflect(Serialize, Deserialize)
108108
)]
109109
pub struct RawGamepadAxisChangedEvent {
@@ -128,11 +128,11 @@ impl RawGamepadAxisChangedEvent {
128128

129129
/// A Gamepad connection event. Created when a connection to a gamepad
130130
/// is established and when a gamepad is disconnected.
131-
#[derive(Event, Debug, Clone, PartialEq, Reflect)]
132-
#[reflect(Debug, PartialEq)]
131+
#[derive(Event, Debug, Clone, PartialEq)]
132+
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
133+
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
133134
#[cfg_attr(
134-
feature = "serialize",
135-
derive(serde::Serialize, serde::Deserialize),
135+
all(feature = "serialize", feature = "bevy_reflect"),
136136
reflect(Serialize, Deserialize)
137137
)]
138138
pub struct GamepadConnectionEvent {
@@ -163,11 +163,11 @@ impl GamepadConnectionEvent {
163163
}
164164

165165
/// [`GamepadButton`] event triggered by a digital state change
166-
#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
167-
#[reflect(Debug, PartialEq)]
166+
#[derive(Event, Debug, Clone, Copy, PartialEq, Eq)]
167+
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
168+
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
168169
#[cfg_attr(
169-
feature = "serialize",
170-
derive(serde::Serialize, serde::Deserialize),
170+
all(feature = "serialize", feature = "bevy_reflect"),
171171
reflect(Serialize, Deserialize)
172172
)]
173173
pub struct GamepadButtonStateChangedEvent {
@@ -191,11 +191,11 @@ impl GamepadButtonStateChangedEvent {
191191
}
192192

193193
/// [`GamepadButton`] event triggered by an analog state change
194-
#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)]
195-
#[reflect(Debug, PartialEq)]
194+
#[derive(Event, Debug, Clone, Copy, PartialEq)]
195+
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
196+
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
196197
#[cfg_attr(
197-
feature = "serialize",
198-
derive(serde::Serialize, serde::Deserialize),
198+
all(feature = "serialize", feature = "bevy_reflect"),
199199
reflect(Serialize, Deserialize)
200200
)]
201201
pub struct GamepadButtonChangedEvent {
@@ -222,11 +222,11 @@ impl GamepadButtonChangedEvent {
222222
}
223223

224224
/// [`GamepadAxis`] event triggered by an analog state change
225-
#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)]
226-
#[reflect(Debug, PartialEq)]
225+
#[derive(Event, Debug, Clone, Copy, PartialEq)]
226+
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
227+
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
227228
#[cfg_attr(
228-
feature = "serialize",
229-
derive(serde::Serialize, serde::Deserialize),
229+
all(feature = "bevy_reflect", feature = "serialize"),
230230
reflect(Serialize, Deserialize)
231231
)]
232232
pub struct GamepadAxisChangedEvent {
@@ -1232,7 +1232,7 @@ impl AxisSettings {
12321232
return true;
12331233
}
12341234

1235-
f32::abs(new_value - old_value.unwrap()) > self.threshold
1235+
ops::abs(new_value - old_value.unwrap()) > self.threshold
12361236
}
12371237

12381238
/// Filters the `new_value` based on the `old_value`, according to the [`AxisSettings`].
@@ -1307,7 +1307,7 @@ impl ButtonAxisSettings {
13071307
return true;
13081308
}
13091309

1310-
f32::abs(new_value - old_value.unwrap()) > self.threshold
1310+
ops::abs(new_value - old_value.unwrap()) > self.threshold
13111311
}
13121312

13131313
/// Filters the `new_value` based on the `old_value`, according to the [`ButtonAxisSettings`].

crates/bevy_input/src/keyboard.rs

+6
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,14 @@ use bevy_ecs::{
7272
event::{Event, EventReader},
7373
system::ResMut,
7474
};
75+
7576
#[cfg(feature = "bevy_reflect")]
7677
use bevy_reflect::Reflect;
78+
79+
#[cfg(not(feature = "smol_str"))]
80+
use alloc::string::String as SmolStr;
81+
82+
#[cfg(feature = "smol_str")]
7783
use smol_str::SmolStr;
7884

7985
#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]

crates/bevy_input/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
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
//! Input functionality for the [Bevy game engine](https://bevyengine.org/).
910
//!
1011
//! # Supported input devices
1112
//!
1213
//! `bevy` currently supports keyboard, mouse, gamepad, and touch inputs.
1314
15+
extern crate alloc;
16+
1417
mod axis;
1518
mod button_input;
1619
/// Common run conditions

crates/bevy_math/Cargo.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ approx = { version = "0.5", default-features = false, optional = true }
2525
rand = { version = "0.8", default-features = false, optional = true }
2626
rand_distr = { version = "0.4.3", optional = true }
2727
smallvec = { version = "1.11" }
28-
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
28+
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", default-features = false, features = [
2929
"glam",
3030
], optional = true }
3131
variadics_please = "1.1"
@@ -52,6 +52,7 @@ std = [
5252
"approx?/std",
5353
"rand?/std",
5454
"rand_distr?/std",
55+
"bevy_reflect?/std",
5556
]
5657
alloc = [
5758
"itertools/use_alloc",
@@ -76,8 +77,8 @@ debug_glam_assert = ["glam/debug-glam-assert"]
7677
rand = ["dep:rand", "dep:rand_distr", "glam/rand"]
7778
# Include code related to the Curve trait
7879
curve = []
79-
# Enable bevy_reflect (requires std)
80-
bevy_reflect = ["dep:bevy_reflect", "std"]
80+
# Enable bevy_reflect (requires alloc)
81+
bevy_reflect = ["dep:bevy_reflect", "alloc"]
8182

8283
[lints]
8384
workspace = true

tools/ci/src/commands/compile_check_no_std.rs

+8
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,14 @@ impl Prepare for CompileCheckNoStdCommand {
118118
"Please fix compiler errors in output above for bevy_hierarchy no_std compatibility.",
119119
));
120120

121+
commands.push(PreparedCommand::new::<Self>(
122+
cmd!(
123+
sh,
124+
"cargo check -p bevy_input --no-default-features --features libm,serialize,bevy_reflect --target {target}"
125+
),
126+
"Please fix compiler errors in output above for bevy_input no_std compatibility.",
127+
));
128+
121129
commands
122130
}
123131
}

0 commit comments

Comments
 (0)