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}