3 个版本
0.1.2 | 2023 年 7 月 16 日 |
---|---|
0.1.1 | 2023 年 7 月 10 日 |
0.1.0 | 2023 年 7 月 10 日 |
#711 in 开发工具
9KB
127 行
hot_potato:热重载你的 Rust 代码
此包允许你在开发过程中动态重载函数体和修改魔法值,从而实现快速更改而无需整个重启和导航到当前可交互项。
请注意,这仅在您的开发环境中有效 - 而不是在已发布的构建中!
强烈建议将所有土豆代码从发布构建中删除!此包旨在方便设计和开发,不适合在已部署的构建中使用。
目录
快速入门
(请参阅test_project以获取基本实现)
- 将
hot_potato
添加到您的项目中
cargo add hot_potato
- 创建您想要热重载的函数,并使用
potato
进行注释
use hot_potato::potato;
/// t: time [0.0;1.0]
#[potato]
fn interpolate(t: f32) -> f32 {
// linear interpolation for now
t
}
- 在启动时加载函数
use hot_potato::build_and_reload_potatoes;
fn main() {
build_and_reload_potatoes().expect("error loading potatoes");
...
}
- 创建一个重载触发器(热键、UI 小部件或输入等)
fn main() {
// some quick and dirty loop
loop {
// make sure this is called at least once before any potato func is called!
build_and_reload_potatoes().expect("error loading potatoes");
for i in 0..=5 {
let t = i as f32 / 5.0;
println!("{t} -> {}", interpolate(t));
}
println!("Press enter to hot-reload");
// just waits for input and then starts the loop anew...
std::io::stdin().read_line(&mut String::new()).unwrap();
}
}
- 在您的
Cargo.toml
中配置 lib 目标
[lib]
path = "src/main.rs"
crate-type = ["cdylib"]
[[bin]]
name = "test_project"
path = "src/main.rs"
lib 目标用于热重载,而 bin 目标是您的默认运行编译目标。
- 使用
cargo run
运行
尝试编辑插值函数并触发重载
/// t: time [0.0;1.0]
#[potato]
fn interpolate(t: f32) -> f32 {
// quadratic
t * t
}
/// t: time [0.0;1.0]
#[potato]
fn interpolate(t: f32) -> f32 {
// ease in-out
x * x * (3.0 - 2.0 * x)
}
魔法值调整
在这种情况下,我们想要显示一个具有特定颜色的窗口小部件,但我们并不完全满意。
请注意,您仍然需要一个初始的 build_and_reload_potatoes
,但在值调整后不需要这样的重载。
伪代码,请参阅test_project以获取一些真实代码
// We are not quite happy with our color...
// Instead of starting the whole app anew every time we change it slightly,
// or having to change our code in a way that we pass around those values
// and having to change that back later, we can just glue those magic parameters to
// that function and change them from anywhere
#[potato(r: u8 = 0xFF, g: u8 = 0x00, b: u8 = 0xFF)]
fn show_colored_thing(text: &str, ui: &mut UIContext) -> f32 {
let mut widget = Widget::new();
widget.title = Some(text);
widget.bg_color = Color::from_rgba(r, g, b, 0xFF);
ui.popup(widget);
}
// Somewhere in an debug ui handler that has an "apply&test" button.
// Also lets just pretend we have 3 debug ui sliders for rgb.
fn on_click_apply(red: Slider, green: Slider, blue: Slider, ui: &mut UIContext) {
show_colored_thing.set::<u8>("r", (red.get_slider_value() * 255.0) as u8);
show_colored_thing.set::<u8>("g", (green.get_slider_value() * 255.0) as u8);
show_colored_thing.set::<u8>("b", (blue.get_slider_value() * 255.0) as u8);
}
// Somewhere we also have an "open popup" button
fn on_click_open(ui: &mut UIContext) {
show_colored_thing("Test RGB popup", ui);
}
功能
它能做什么
- 几乎可以热重载任何函数体
- 快速调整魔法值
它不能做什么
- 热重载函数签名更改或任意代码
- 热重载特质方法或泛型
- 给你做三明治
警告:函数签名更改和类似的随意操作将导致未定义的行为,很可能是 STATUS_ACCESS_VIOLATION
或类似的崩溃。
依赖项
~1–6.5MB
~34K SLoC