mirror of
https://github.com/bevyengine/bevy.git
synced 2026-05-06 06:06:42 -04:00
984f7203e3
# Objective - #23414 made `SystemSchedule::systems` pub, but this can lead to breaking invariants that `Schedule` expects. For example this allows mutating the access which is used to prevent race conditions in the multithreaded executor. This could also allow replacing systems, but without initializing the access as the `Schedule` is meant to keep track of which systems are unitialized. ## Solution - Make the fields of `SystemWithAccess` private to make it harder to modify the access. This is potentially a breaking change as `SystemWithAccess` is pub, but the type is not exposed in our public api's for `Schedule` in 0.18. - Make an unsafe accessor for the `systems` field and make the field private again. ## Testing - Only checked that this compiles
57 lines
1.3 KiB
Rust
57 lines
1.3 KiB
Rust
//! Demonstrates how to make a custom [`SystemExecutor`].
|
|
|
|
use bevy::{
|
|
ecs::{
|
|
error::{BevyError, ErrorContext},
|
|
schedule::{FixedBitSet, SystemExecutor, SystemSchedule},
|
|
},
|
|
prelude::*,
|
|
};
|
|
|
|
#[derive(Default)]
|
|
struct CustomExecutor;
|
|
|
|
impl SystemExecutor for CustomExecutor {
|
|
fn init(&mut self, _schedule: &SystemSchedule) {}
|
|
|
|
fn run(
|
|
&mut self,
|
|
schedule: &mut SystemSchedule,
|
|
world: &mut World,
|
|
_skip_systems: Option<&FixedBitSet>,
|
|
_error_handler: fn(BevyError, ErrorContext),
|
|
) {
|
|
#[expect(unsafe_code, reason = "CustomExecutor's require unsafe")]
|
|
// SAFETY: `run` is a trait method on `System`
|
|
for entry in unsafe { schedule.systems_mut().iter_mut() } {
|
|
let _ = entry.run((), world);
|
|
}
|
|
}
|
|
|
|
fn set_apply_final_deferred(&mut self, _value: bool) {}
|
|
}
|
|
|
|
#[derive(Resource, Default)]
|
|
struct Counter(u32);
|
|
|
|
fn increment(mut counter: ResMut<Counter>) {
|
|
counter.0 += 1;
|
|
}
|
|
|
|
fn print_counter(counter: Res<Counter>) {
|
|
println!("Counter: {}", counter.0);
|
|
}
|
|
|
|
fn main() {
|
|
let mut world = World::new();
|
|
world.init_resource::<Counter>();
|
|
|
|
let mut schedule = Schedule::default();
|
|
schedule.set_executor(CustomExecutor);
|
|
schedule.add_systems((increment, print_counter).chain());
|
|
|
|
for _ in 0..5 {
|
|
schedule.run(&mut world);
|
|
}
|
|
}
|