hotpatching_systems/hotpatching_systems.rs
1//! This example demonstrates how to hot patch systems.
2//!
3//! It needs to be run with the dioxus CLI:
4//! ```sh
5//! dx serve --hot-patch --example hotpatching_systems --features hotpatching
6//! ```
7//!
8//! All systems are automatically hot patchable.
9//!
10//! You can change the text in the `update_text` system, or the color in the
11//! `on_click` system, and those changes will be hotpatched into the running
12//! application.
13//!
14//! It's also possible to make any function hot patchable by wrapping it with
15//! `bevy::dev_tools::hotpatch::call`.
16
17use std::time::Duration;
18
19use bevy::{color::palettes, prelude::*};
20
21fn main() {
22 let (sender, receiver) = crossbeam_channel::unbounded::<()>();
23
24 // This function is here to demonstrate how to make something hot patchable outside of a system
25 // It uses a thread for simplicity but could be an async task, an asset loader, ...
26 start_thread(receiver);
27
28 App::new()
29 .add_plugins(DefaultPlugins)
30 .insert_resource(TaskSender(sender))
31 .add_systems(Startup, setup)
32 .add_systems(Update, update_text)
33 .run();
34}
35
36fn update_text(mut text: Single<&mut Text>) {
37 // Anything in the body of a system can be changed.
38 // Changes to this string should be immediately visible in the example.
39 text.0 = "before".to_string();
40}
41
42fn on_click(
43 _click: On<Pointer<Click>>,
44 mut color: Single<&mut TextColor>,
45 task_sender: Res<TaskSender>,
46) {
47 // Observers are also hot patchable.
48 // If you change this color and click on the text in the example, it will have the new color.
49 color.0 = palettes::tailwind::RED_600.into();
50
51 let _ = task_sender.0.send(());
52}
53
54#[derive(Resource)]
55struct TaskSender(crossbeam_channel::Sender<()>);
56
57fn setup(mut commands: Commands) {
58 commands.spawn(Camera2d);
59
60 commands
61 .spawn((
62 Node {
63 width: percent(100),
64 height: percent(100),
65 align_items: AlignItems::Center,
66 justify_content: JustifyContent::Center,
67 flex_direction: FlexDirection::Column,
68 ..default()
69 },
70 children![(
71 Text::default(),
72 TextFont {
73 font_size: 100.0,
74 ..default()
75 },
76 )],
77 ))
78 .observe(on_click);
79}
80
81fn start_thread(receiver: crossbeam_channel::Receiver<()>) {
82 std::thread::spawn(move || {
83 while receiver.recv().is_ok() {
84 let start = bevy::platform::time::Instant::now();
85
86 // You can also make any part outside of a system hot patchable by wrapping it
87 // In this part, only the duration is hot patchable:
88 let duration = bevy::app::hotpatch::call(|| Duration::from_secs(2));
89
90 std::thread::sleep(duration);
91 info!("done after {:?}", start.elapsed());
92 }
93 });
94}