refactor: update bevy version

This commit is contained in:
2026-09-03 22:57:39 +00:00
parent 98d7b52546
commit 11c5ff2aff
15 changed files with 3961 additions and 3381 deletions
Generated
+1905 -2100
View File
File diff suppressed because it is too large Load Diff
Regular → Executable
+8 -9
View File
@@ -10,19 +10,18 @@ reflect = ["dep:bevy_reflect"]
inspector-egui = ["reflect", "dep:bevy-inspector-egui"] inspector-egui = ["reflect", "dep:bevy-inspector-egui"]
[dependencies] [dependencies]
bevy-inspector-egui = { version = "0.22.1", optional = true } bevy-inspector-egui = { version = "0.33.1", optional = true, default-features = false }
bevy_app = "0.14.1" bevy_app = "0.16.1"
bevy_derive = "0.14.1" bevy_derive = "0.16.1"
bevy_ecs = "0.14.1" bevy_ecs = "0.16.1"
bevy_input = "0.14.1" bevy_input = "0.16.1"
bevy_state = "0.14.1" bevy_state = "0.16.1"
bevy_reflect = { version = "0.14.1", optional = true } bevy_platform = "0.16.1"
bevy_utils = "0.14.1" bevy_reflect = { version = "0.16.1", optional = true }
log = "0.4.20" log = "0.4.20"
serde = { version = "1.0.194", optional = true } serde = { version = "1.0.194", optional = true }
strum = "0.26.2" strum = "0.26.2"
strum_macros = "0.26.2" strum_macros = "0.26.2"
bevy_controls_macros = { path = "macros", version = "0.1.0" }
[dev-dependencies] [dev-dependencies]
env_logger = "0.10.1" env_logger = "0.10.1"
+1843 -1089
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -12,11 +12,13 @@ wayland = ["bevy/wayland"]
windows = ["bevy/bevy_winit"] windows = ["bevy/bevy_winit"]
[dependencies] [dependencies]
bevy = { version = "0.14.1", default-features = false, features = [ bevy = { version = "0.16.1", default-features = false, features = [
"bevy_asset", "bevy_asset",
"bevy_text", "bevy_text",
"bevy_state", "bevy_state",
"bevy_ui", "bevy_ui",
"bevy_window",
"bevy_winit",
#"dynamic_linking", #"dynamic_linking",
"default_font", "default_font",
]} ]}
+1 -1
View File
@@ -2,5 +2,5 @@ Basic example
to run to run
```bash ```bash
cargo run --feature '<x11|wayland|windows>' cargo run --features '<x11|wayland|windows>'
``` ```
+6 -6
View File
@@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1712163089, "lastModified": 1788316716,
"narHash": "sha256-Um+8kTIrC19vD4/lUCN9/cU9kcOsD1O1m+axJqQPyMM=", "narHash": "sha256-bc7rSpXIdn9QWGNqfWcPZWOhEVF8NoeAZkWq0XWnf/k=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "fd281bd6b7d3e32ddfa399853946f782553163b5", "rev": "3ed67ec0a4d3c7ab4ae1f04f8ee8df07bfa506a2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -48,11 +48,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1723429325, "lastModified": 1788456718,
"narHash": "sha256-4x/32xTCd+xCwFoI/kKSiCr5LQA2ZlyTRYXKEni5HR8=", "narHash": "sha256-TxHC0sBjV2pmsBLKAX02JTXlye/EOLt6Do+WNtGofGw=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "65e3dc0fe079fe8df087cd38f1fe6836a0373aad", "rev": "0b20a18e84d9164464739189c2b2a1b00f6f0e4b",
"type": "github" "type": "github"
}, },
"original": { "original": {
+4 -5
View File
@@ -6,7 +6,6 @@
url = "github:oxalica/rust-overlay"; url = "github:oxalica/rust-overlay";
inputs = { inputs = {
nixpkgs.follows = "nixpkgs"; nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
}; };
}; };
}; };
@@ -27,10 +26,10 @@
vulkan-loader vulkan-loader
xorg.libX11 libx11
xorg.libXrandr libxrandr
xorg.libXcursor libxcursor
xorg.libXi libxi
wayland wayland
libxkbcommon libxkbcommon
@@ -1,2 +1,2 @@
[toolchain] [toolchain]
channel = '1.79.0' channel = '1.88.0'
+88 -110
View File
@@ -143,132 +143,110 @@ fn main() {
.run(); .run();
} }
#[derive(Component)] #[derive(Component, Clone, Copy)]
struct TextBlock; enum TextSpanKind {
MoveLeft,
MoveBack,
MoveForward,
MoveRight,
Jump,
DeltaX,
DeltaY,
}
const TEXT_SIZE: f32 = 30.; const TEXT_SIZE: f32 = 30.;
fn setup(mut commands: Commands) { fn text_span(text: &str, kind: TextSpanKind) -> (TextSpan, TextFont, TextColor, TextSpanKind) {
commands.spawn(Camera2dBundle::default()); (
TextSpan::new(text),
commands.spawn(( TextFont {
TextBundle::from_sections([ font_size: TEXT_SIZE,
TextSection::new( ..default()
"Info: this example is intended to show basic crate capabilities and limitations\nso WASD work only on US layout, but HJKL may work on any layout\nAction: ", },
TextStyle { TextColor(Color::WHITE),
font_size: TEXT_SIZE, kind,
..default() )
},
),
TextSection::new(
"Left (H/A) ",
TextStyle {
font_size: TEXT_SIZE,
..default()
},
),
TextSection::new(
"Back (J/S) ",
TextStyle {
font_size: TEXT_SIZE,
..default()
},
),
TextSection::new(
"Forward (K/W) ",
TextStyle {
font_size: TEXT_SIZE,
..default()
},
),
TextSection::new(
"Right (L/D) ",
TextStyle {
font_size: TEXT_SIZE,
..default()
},
),
TextSection::new(
"Up (Space)",
TextStyle {
font_size: TEXT_SIZE,
..default()
},
),
TextSection::new(
"(MouseDeltaX)",
TextStyle {
font_size: TEXT_SIZE,
..default()
},
),
TextSection::new(
"(MouseDeltaY)",
TextStyle {
font_size: TEXT_SIZE,
..default()
},
),
])
.with_background_color(Color::BLACK),
TextBlock,
));
} }
// text sections indexes fn setup(mut commands: Commands) {
const MOVE_LEFT_INDEX: usize = 1; commands.spawn(Camera2d);
const MOVE_BACK_INDEX: usize = 2;
const MOVE_FORWARD_INDEX: usize = 3; commands
const MOVE_RIGHT_INDEX: usize = 4; .spawn((
const JUMP_INDEX: usize = 5; Text::new(
const DELTA_X_INDEX: usize = 6; "Info: this example is intended to show basic crate capabilities and limitations\nso WASD work only on US layout, but HJKL may work on any layout\nAction: ",
const DELTA_Y_INDEX: usize = 7; ),
TextFont {
font_size: TEXT_SIZE,
..default()
},
TextColor(Color::WHITE),
BackgroundColor(Color::BLACK),
))
.with_children(|parent| {
parent.spawn(text_span("Left (H/A) ", TextSpanKind::MoveLeft));
parent.spawn(text_span("Back (J/S) ", TextSpanKind::MoveBack));
parent.spawn(text_span("Forward (K/W) ", TextSpanKind::MoveForward));
parent.spawn(text_span("Right (L/D) ", TextSpanKind::MoveRight));
parent.spawn(text_span("Up (Space)", TextSpanKind::Jump));
parent.spawn(text_span("(MouseDeltaX)", TextSpanKind::DeltaX));
parent.spawn(text_span("(MouseDeltaY)", TextSpanKind::DeltaY));
});
}
fn text_update_system( fn text_update_system(
mut query: Query<&mut Text, With<TextBlock>>, mut query: Query<(&TextSpanKind, &mut TextSpan, &mut TextColor)>,
inputs_container: Res<MyInputsContainer>, inputs_container: Res<MyInputsContainer>,
mut jumps_count: ResMut<JumpsCount>, mut jumps_count: ResMut<JumpsCount>,
) { ) {
for text in query.iter_mut() { for (text_span_kind, mut text_span, mut text_color) in &mut query {
let player_inputs = inputs_container.me().expect("This is bad"); let player_inputs = inputs_container.me().expect("This is bad");
let mut text = update_text(text, player_inputs.get(MyAction::Left), MOVE_LEFT_INDEX); match *text_span_kind {
text = update_text(text, player_inputs.get(MyAction::Back), MOVE_BACK_INDEX); TextSpanKind::MoveLeft => {
text = update_text( update_text_color(&mut text_color, player_inputs.get(MyAction::Left))
text, }
player_inputs.get(MyAction::Forward), TextSpanKind::MoveBack => {
MOVE_FORWARD_INDEX, update_text_color(&mut text_color, player_inputs.get(MyAction::Back))
); }
text = update_text(text, player_inputs.get(MyAction::Right), MOVE_RIGHT_INDEX); TextSpanKind::MoveForward => {
if player_inputs update_text_color(&mut text_color, player_inputs.get(MyAction::Forward));
.get_just_pressed(MyAction::Up) }
.unwrap_or(false) TextSpanKind::MoveRight => {
{ update_text_color(&mut text_color, player_inputs.get(MyAction::Right));
**jumps_count += 1; }
text.sections[JUMP_INDEX].value = format!("Up (Space) - {}", **jumps_count); TextSpanKind::Jump => {
if player_inputs
.get_just_pressed(MyAction::Up)
.unwrap_or(false)
{
**jumps_count += 1;
text_span.0 = format!("Up (Space) - {}", **jumps_count);
}
if player_inputs
.get_just_pressed(MyAction::Down)
.unwrap_or(false)
{
**jumps_count -= 1;
text_span.0 = format!("Up (Space) - {}", **jumps_count);
}
}
TextSpanKind::DeltaX => {
let x = player_inputs.get(MyAction::MouseHorizontal).to_float();
text_span.0 = format!("(MouseDeltaX) - {}", x);
}
TextSpanKind::DeltaY => {
let y = player_inputs.get(MyAction::MouseVertical).to_float();
text_span.0 = format!("(MouseDeltaY) - {}", y);
}
} }
if player_inputs
.get_just_pressed(MyAction::Down)
.unwrap_or(false)
{
**jumps_count -= 1;
text.sections[JUMP_INDEX].value = format!("Up (Space) - {}", **jumps_count);
}
let x = player_inputs.get(MyAction::MouseHorizontal).to_float();
text.sections[DELTA_X_INDEX].value = format!("(MouseDeltaX) - {}", x);
let y = player_inputs.get(MyAction::MouseVertical).to_float();
text.sections[DELTA_Y_INDEX].value = format!("(MouseDeltaY) - {}", y);
} }
} }
fn update_text(mut text: Mut<Text>, input_value: InputValue, index: usize) -> Mut<Text> { fn update_text_color(text_color: &mut TextColor, input_value: InputValue) {
if input_value.is_boolean() && input_value.to_boolean() { if input_value.is_boolean() && input_value.to_boolean() {
text.sections[index].style.color = Color::linear_rgb(0.855, 0.647, 0.125); text_color.0 = Color::linear_rgb(0.855, 0.647, 0.125);
} else { } else {
text.sections[index].style.color = Color::WHITE; text_color.0 = Color::WHITE;
} }
text
} }
-1
View File
@@ -13,4 +13,3 @@ quote = "1.0"
[dev-dependencies] [dev-dependencies]
env_logger = "0.10.1" env_logger = "0.10.1"
+67 -46
View File
@@ -1,61 +1,82 @@
use std::hash::Hash; use std::hash::Hash;
use bevy_ecs::system::Resource; use bevy_ecs::prelude::Resource;
#[cfg(feature = "inspector-egui")] #[cfg(feature = "inspector-egui")]
use bevy_inspector_egui::inspector_options::InspectorOptionsType; use bevy_inspector_egui::inspector_options::InspectorOptionsType;
use bevy_state::state::{FreelyMutableState, States};
use strum::IntoEnumIterator;
// #[cfg(all(feature = "reflect", feature = "serialize"))]
// use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
use bevy_controls_macros::supertraits;
#[cfg(feature = "reflect")] #[cfg(feature = "reflect")]
use bevy_reflect::{FromReflect, Reflect, TypePath}; use bevy_reflect::{FromReflect, Reflect, TypePath};
use bevy_state::state::{FreelyMutableState, States};
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{de::DeserializeOwned, Serialize}; use serde::{de::DeserializeOwned, Serialize};
use strum::IntoEnumIterator;
use crate::resource::PlayerActions; use crate::resource::PlayerActions;
// ===== Action ===== macro_rules! define_contracts {
// SAFETY: inspector-egui includes reflect ($($feature_bounds:tt)*) => {
pub trait Action:
'static
+ std::marker::Sync
+ std::marker::Send
+ PartialEq
+ Eq
+ Hash
+ IntoEnumIterator
+ Clone
+ Copy
+ std::fmt::Debug
$($feature_bounds)*
{
}
pub trait GameState:
'static
+ std::marker::Sync
+ std::marker::Send
+ States
+ Default
+ std::fmt::Debug
+ FreelyMutableState
$($feature_bounds)*
{
}
pub trait InputsContainer<A: Action>:
'static
+ std::marker::Sync
+ std::marker::Send
+ Resource
+ Default
+ std::fmt::Debug
$($feature_bounds)*
{
/// The method returning an iterator over references to the PlayerInputs.
fn iter_inputs<'a>(&'a self) -> Box<dyn Iterator<Item = &'a PlayerActions<A>> + 'a>;
/// The method returning an player inputs of this client.
fn me<'a>(&'a self) -> Option<&'a PlayerActions<A>>;
/// The method returning an mutable player inputs of this client.
fn me_mut<'a>(&'a mut self) -> Option<&'a mut PlayerActions<A>>;
}
};
}
#[cfg(all(not(feature = "serialize"), not(feature = "reflect")))]
define_contracts!();
#[cfg(all(feature = "serialize", not(feature = "reflect")))]
define_contracts!(+ Serialize + DeserializeOwned);
#[cfg(all( #[cfg(all(
feature = "reflect",
not(feature = "serialize"), not(feature = "serialize"),
not(feature = "reflect"),
not(feature = "inspector-egui") not(feature = "inspector-egui")
))] ))]
#[supertraits] define_contracts!(+ Reflect + TypePath + FromReflect + bevy_reflect::GetTypeRegistration + bevy_reflect::Typed);
pub trait Action: #[cfg(all(
'static feature = "reflect",
+ std::marker::Sync feature = "serialize",
+ std::marker::Send not(feature = "inspector-egui")
+ PartialEq ))]
+ Eq define_contracts!(+ Serialize + DeserializeOwned + Reflect + TypePath + FromReflect + bevy_reflect::GetTypeRegistration + bevy_reflect::Typed);
+ Hash #[cfg(all(feature = "inspector-egui", not(feature = "serialize")))]
+ IntoEnumIterator define_contracts!(+ Reflect + TypePath + FromReflect + bevy_reflect::GetTypeRegistration + bevy_reflect::Typed + InspectorOptionsType);
+ Clone #[cfg(all(feature = "inspector-egui", feature = "serialize"))]
+ Copy define_contracts!(+ Serialize + DeserializeOwned + Reflect + TypePath + FromReflect + bevy_reflect::GetTypeRegistration + bevy_reflect::Typed + InspectorOptionsType);
+ std::fmt::Debug
{
}
// ===== GameState =====
// SAFETY: inspector-egui includes reflect
#[supertraits]
pub trait GameState:
'static + std::marker::Sync + std::marker::Send + States + Default + std::fmt::Debug + FreelyMutableState
{
}
// ===== InputsContainer =====
// SAFETY: inspector-egui includes reflect
#[supertraits]
pub trait InputsContainer<A: Action>:
'static + std::marker::Sync + std::marker::Send + Resource + Default + std::fmt::Debug
{
/// The method returning an iterator over references to the PlayerInputs.
/// Note: the use of 'a for both the method's lifetime and the returned Iterator's lifetime.
fn iter_inputs<'a>(&'a self) -> Box<dyn Iterator<Item = &'a PlayerActions<A>> + 'a>;
/// The method returning an player inputs of this client.
fn me<'a>(&'a self) -> Option<&'a PlayerActions<A>>;
/// The method returning an mutable player inputs of this client.
fn me_mut<'a>(&'a mut self) -> Option<&'a mut PlayerActions<A>>;
}
+26 -3
View File
@@ -1,18 +1,19 @@
use bevy_app::{App, Plugin, PreUpdate}; use bevy_app::{App, Plugin, PreUpdate};
use bevy_derive::{Deref, DerefMut}; use bevy_derive::{Deref, DerefMut};
use bevy_ecs::system::{In, IntoSystem}; use bevy_ecs::system::{In, IntoSystem};
use bevy_state::app::AppExtStates;
use bevy_ecs::{ use bevy_ecs::{
event::EventReader, event::EventReader,
system::{Res, ResMut, Resource}, prelude::Resource,
system::{Res, ResMut},
}; };
use bevy_input::{ use bevy_input::{
keyboard::KeyCode, keyboard::KeyCode,
mouse::{MouseButton, MouseMotion, MouseScrollUnit, MouseWheel}, mouse::{MouseButton, MouseMotion, MouseScrollUnit, MouseWheel},
ButtonInput, ButtonInput,
}; };
use bevy_state::app::AppExtStates;
use bevy_state::state::State; use bevy_state::state::State;
use bevy_utils::HashMap; use std::collections::HashMap;
use crate::{ use crate::{
contract::{Action, GameState, InputsContainer}, contract::{Action, GameState, InputsContainer},
@@ -51,7 +52,29 @@ impl<A: Action, Ic: InputsContainer<A>, Gs: GameState> ControlsPlugin<A, Ic, Gs>
#[derive(Resource, Default, Debug, Deref, DerefMut)] #[derive(Resource, Default, Debug, Deref, DerefMut)]
struct TrigeredInputs(HashMap<InputType, InputValue>); struct TrigeredInputs(HashMap<InputType, InputValue>);
#[cfg(not(feature = "reflect"))]
impl<A: Action, Ic: InputsContainer<A>, Gs: GameState> Plugin for ControlsPlugin<A, Ic, Gs> { impl<A: Action, Ic: InputsContainer<A>, Gs: GameState> Plugin for ControlsPlugin<A, Ic, Gs> {
fn build(&self, app: &mut App) {
app
.insert_resource(self.controls.clone())
.init_resource::<Ic>()
.init_resource::<TrigeredInputs>()
.insert_state::<Gs>(Gs::default())
.add_systems(
PreUpdate,
Self::collect_inputs.pipe(Self::fill_players_inputs),
);
}
}
#[cfg(feature = "reflect")]
impl<A, Ic, Gs> Plugin for ControlsPlugin<A, Ic, Gs>
where
A: Action + bevy_reflect::FromReflect + bevy_reflect::GetTypeRegistration + bevy_reflect::Typed,
Ic: InputsContainer<A>,
Gs:
GameState + bevy_reflect::FromReflect + bevy_reflect::GetTypeRegistration + bevy_reflect::Typed,
{
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app
.insert_resource(self.controls.clone()) .insert_resource(self.controls.clone())
+2 -2
View File
@@ -1,16 +1,16 @@
use std::error; use std::error;
use bevy_derive::{Deref, DerefMut}; use bevy_derive::{Deref, DerefMut};
use bevy_ecs::system::Resource; use bevy_ecs::prelude::Resource;
use bevy_input::{keyboard::KeyCode, mouse::MouseButton}; use bevy_input::{keyboard::KeyCode, mouse::MouseButton};
#[cfg(feature = "inspector-egui")] #[cfg(feature = "inspector-egui")]
use bevy_inspector_egui::prelude::*; use bevy_inspector_egui::prelude::*;
#[cfg(all(feature = "reflect", feature = "serialize"))] #[cfg(all(feature = "reflect", feature = "serialize"))]
use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
use bevy_utils::HashMap;
use log::warn; use log::warn;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use bevy_platform::collections::HashMap;
use std::mem::discriminant; use std::mem::discriminant;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
#[cfg(feature = "reflect")] #[cfg(feature = "reflect")]
+2 -2
View File
@@ -1,4 +1,4 @@
/// Creates a [`HashMap`](bevy_utils::HashMap) from a list of key-value pairs. /// Creates a [`HashMap`](std::collections::HashMap) from a list of key-value pairs.
/// ///
/// Example: /// Example:
/// ```ignore /// ```ignore
@@ -9,7 +9,7 @@
#[macro_export] #[macro_export]
macro_rules! hashmap { macro_rules! hashmap {
($( $key: expr => $val: expr ),*) => {{ ($( $key: expr => $val: expr ),*) => {{
let mut map = HashMap::new(); let mut map = ::std::collections::HashMap::new();
$( $(
map.insert($key, $val); map.insert($key, $val);
)* )*
+1 -1
View File
@@ -1,3 +1,3 @@
[toolchain] [toolchain]
channel = '1.79.0' channel = '1.88.0'
components = ["rustfmt", "clippy", "rust-src"] components = ["rustfmt", "clippy", "rust-src"]