mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 18:54:55 +00:00
Scripts: the read after a script left the folder asks for a frame when it ends
When File › Scripts runs a listed script that is no longer in the Scripts folder, the folder is read again on a thread. That read now has the window's context, so it asks for a frame when it ends and an idle window takes in the new listing (and the macOS menu bar follows it) without waiting for the next input event.
This commit is contained in:
@@ -246,7 +246,8 @@ pub fn readable(p: &Value) -> bool {
|
||||
pub fn run(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String> {
|
||||
let path = p.get("path").and_then(Value::as_str).ok_or("missing `path`")?;
|
||||
let source = app.session.installed_script(path).map_err(|e| {
|
||||
refresh(app, None);
|
||||
let ctx = app.ui_ctx.clone();
|
||||
refresh(app, ctx.as_ref());
|
||||
e.to_string()
|
||||
})?;
|
||||
app.run("script.run", json!({"source": source, "name": vectorcraft_engine::cmd::fileio::file_name(path)}))
|
||||
|
||||
@@ -200,6 +200,28 @@ fn a_script_that_left_the_folder_is_not_run_and_the_folder_is_read_again() {
|
||||
let _ = std::fs::remove_dir_all(dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_read_after_a_script_that_left_the_folder_asks_for_a_frame() {
|
||||
let dir = folder("gone-frame");
|
||||
let mut app = app(&dir);
|
||||
let gone = write(&dir, "gone.js", DRAW);
|
||||
read(&app);
|
||||
std::fs::remove_file(&gone).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
let (tx, frames) = std::sync::mpsc::channel();
|
||||
ctx.set_request_repaint_callback(move |_| {
|
||||
let _ = tx.send(());
|
||||
});
|
||||
app.ui_ctx = Some(ctx);
|
||||
assert!(menus::run_ui_command(&mut app, scripts_menu::COMMAND, &json!({ "path": gone })).unwrap().is_err());
|
||||
// With the app's copy of the context dropped, only the read's thread can still ask for a
|
||||
// frame; the channel closes without one when that thread ends without asking.
|
||||
app.ui_ctx = None;
|
||||
assert_eq!(frames.recv(), Ok(()), "the finished read asks for a frame so an idle window takes it in");
|
||||
scripts_menu::wait();
|
||||
let _ = std::fs::remove_dir_all(dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_menu_notes_a_listing_that_stopped_and_a_folder_it_cannot_read() {
|
||||
let dir = folder("notes");
|
||||
|
||||
Reference in New Issue
Block a user