From 7332ca3c488f9fd34d406284f06969037cc36b2e Mon Sep 17 00:00:00 2001 From: Alice I Cecile Date: Tue, 15 Jul 2025 15:29:24 -0700 Subject: [PATCH] Basic structure for the Command variant --- crates/bevy_time/Cargo.toml | 3 +- crates/bevy_time/src/delayed_commands.rs | 79 ++++++++++++++++++++++++ crates/bevy_time/src/lib.rs | 6 ++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 crates/bevy_time/src/delayed_commands.rs diff --git a/crates/bevy_time/Cargo.toml b/crates/bevy_time/Cargo.toml index 7c8e840ace2ba..3ae9fc5cca03d 100644 --- a/crates/bevy_time/Cargo.toml +++ b/crates/bevy_time/Cargo.toml @@ -50,8 +50,9 @@ critical-section = [ # bevy bevy_app = { path = "../bevy_app", version = "0.17.0-dev", default-features = false } bevy_ecs = { path = "../bevy_ecs", version = "0.17.0-dev", default-features = false } -bevy_reflect = { path = "../bevy_reflect", version = "0.17.0-dev", default-features = false, optional = true } +bevy_log = { path = "../bevy_log", version = "0.17.0-dev", default-features = false } bevy_platform = { path = "../bevy_platform", version = "0.17.0-dev", default-features = false } +bevy_reflect = { path = "../bevy_reflect", version = "0.17.0-dev", default-features = false, optional = true } # other crossbeam-channel = { version = "0.5.0", default-features = false, features = [ diff --git a/crates/bevy_time/src/delayed_commands.rs b/crates/bevy_time/src/delayed_commands.rs new file mode 100644 index 0000000000000..b702bee75c4a9 --- /dev/null +++ b/crates/bevy_time/src/delayed_commands.rs @@ -0,0 +1,79 @@ +use crate::Time; +use alloc::boxed::Box; +use bevy_ecs::prelude::*; +use bevy_log::warn; +use core::time::Duration; + +/// A [`Command`] that will be executed after a specified delay has elapsed. +/// +/// This can be helpful for scheduling actions at some point in the future. +/// +/// This works by moving the supplied command into a component that is spawned on an entity. +/// Delayed command entities are ticked via [`tick_delayed_commands`], +/// which is typically run in [`First`] as part of [`TimePlugin`]. +#[derive(Component)] +pub struct DelayedCommand { + pub delay: Duration, + pub command: Box, +} + +impl DelayedCommand { + pub fn new(delay: Duration, command: impl Command + Send + Sync + 'static) -> Self { + Self { + delay, + command: Box::new(command), + } + } +} + +impl Command for DelayedCommand { + /// Spawns a new entity with the [`DelayedCommand`] as a component. + fn apply(self, world: &mut World) { + world.spawn(self); + } +} + +pub fn tick_delayed_commands( + mut commands: Commands, + time: Res