mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 01:57:53 -06:00
Merge #1867: Fix scheduled ScriptUI tasks in host sessions (@dorfee)
This commit is contained in:
+18
-4
@@ -82,7 +82,7 @@ impl Exporter for FileExporter {
|
||||
|
||||
/// A new session with media, import, expressions, scripting and export enabled.
|
||||
pub fn session() -> Session {
|
||||
Session {
|
||||
let mut s = Session {
|
||||
// The desktop app, the CLI and the MCP server share installed Roto Brush models.
|
||||
models_dir: config_dir().map(|d| d.join("models")),
|
||||
exporter: Some(Arc::new(FileExporter::default())),
|
||||
@@ -90,11 +90,11 @@ pub fn session() -> Session {
|
||||
importer: Some(Arc::new(MediaImporter)),
|
||||
expr: Some(Arc::new(effectcraft_expr::Expressions)),
|
||||
expr_check: Some(effectcraft_expr::check_syntax),
|
||||
script: Some(effectcraft_script::runner),
|
||||
script_ui: effectcraft_engine::scriptui::ScriptUi { dispatch: Some(effectcraft_script::dispatch_ui), ..Default::default() },
|
||||
plugin_loader: effectcraft_plugin::wasm_available().then_some(effectcraft_plugin::loader as effectcraft_engine::PluginLoader),
|
||||
..Default::default()
|
||||
}
|
||||
};
|
||||
effectcraft_script::install(&mut s);
|
||||
s
|
||||
}
|
||||
|
||||
/// The platform config directory for EffectCraft (`EFFECTCRAFT_CONFIG_DIR` overrides):
|
||||
@@ -109,6 +109,20 @@ pub fn config_dir() -> Option<std::path::PathBuf> {
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn host_runs_tasks_scheduled_by_panel_handlers() {
|
||||
let mut s = super::session();
|
||||
let result = s.execute("script.run", json!({"code": "var w=new Window('palette','Timer regression'); var b=w.add('button',undefined,'Import'); b.onClick=function(){app.scheduleTask(\"app.project.items.addComp('Scheduled',64,64,1,1,25)\",0,false);};w.show();"})).unwrap();
|
||||
assert_eq!(result["ok"], true, "{result}");
|
||||
s.execute("scriptui.click", json!({"window":"Timer regression","widget":"Import"})).unwrap();
|
||||
assert!(s.project.items.is_empty());
|
||||
let tick = s.execute("script.runTasks", json!({})).unwrap();
|
||||
assert_eq!(tick["ran"], 1, "{tick}");
|
||||
assert_eq!(tick["errors"], json!([]), "{tick}");
|
||||
assert!(s.project.items.values().any(|item| item.name == "Scheduled"));
|
||||
s.execute("scriptui.close", json!({"window":"Timer regression"})).unwrap();
|
||||
}
|
||||
|
||||
/// Layer ▸ Camera ▸ Link Focus Distance to Point of Interest / to Layer: the expressions
|
||||
/// evaluate to the camera's focus on the target.
|
||||
#[test]
|
||||
|
||||
@@ -1784,7 +1784,11 @@ impl EffectcraftApp {
|
||||
if self.session.script_ui.task_hosts.is_empty() {
|
||||
return;
|
||||
}
|
||||
let previous_comp = self.session.active_comp_id();
|
||||
let Some(r) = effectcraft_engine::scriptui::ScriptUi::run_tasks(&mut self.session) else { return };
|
||||
if self.session.active_comp_id().is_some() && self.session.active_comp_id() != previous_comp {
|
||||
self.ui.start_screen = false;
|
||||
}
|
||||
if let Some(msg) = r["errors"].as_array().and_then(|e| e.first()).and_then(|e| e["message"].as_str()) {
|
||||
self.toast = Some((format!("Scheduled script task: {msg}"), ctx.input(|i| i.time)));
|
||||
} else if let Some(line) = r["output"].as_array().and_then(|o| o.last()).and_then(|l| l.as_str()) {
|
||||
|
||||
@@ -271,3 +271,18 @@ fn click_at(h: &mut Harness<'_, EffectcraftApp>, c: egui::Pos2) {
|
||||
}
|
||||
h.run_steps(3);
|
||||
}
|
||||
#[test]
|
||||
fn scheduled_import_reveals_its_composition_without_manual_clicks() {
|
||||
let mut s = effectcraft_host::session();
|
||||
let result = s.execute("script.run", json!({"code": "var w=new Window('palette','Automatic import');var b=w.add('button',undefined,'Open');b.onClick=function(){app.scheduleTask(\"var c=app.project.items.addComp('Imported',64,64,1,1,25);c.openInViewer();\",0,false);};w.show();"})).unwrap();
|
||||
assert_eq!(result["ok"], true, "{result}");
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_| EffectcraftApp::new(s));
|
||||
h.state_mut().ui.start_screen = true;
|
||||
h.run_steps(2);
|
||||
h.state_mut().session.execute("scriptui.click", json!({"window":"Automatic import","widget":"Open"})).unwrap();
|
||||
h.run_steps(4);
|
||||
let active = h.state().session.active_comp_id().unwrap();
|
||||
assert_eq!(h.state().session.project.items.get(&active).unwrap().name, "Imported");
|
||||
assert!(!h.state().ui.start_screen, "Home must not hide a composition opened by the scheduled import");
|
||||
h.state_mut().session.execute("scriptui.close", json!({"window":"Automatic import"})).unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user