srecord noeq G22AutoStarter(G22Utils g22utils) > MetaWithChangeListeners is AutoCloseable { settableWithVar volatile bool enabled = true; settable volatile int initialDelay = 3; settableWithVar volatileint nScriptsRun; gettable volatile AutoStartScript currentScript; new Flag started; new Flag waited; new Flag done; new Flag ctrlPressed; L scripts = syncL(); AutoCloseable ctrlListener; record noeq AutoStartScript(G22LeftArrowScript script) > RunResultWithTimestamps { run { LASCompileResult cr = script.compileForAutoRun(); if (cr == null) cr = script.compileSaved(); reMutable cr; run(-> { G22AutoStarter.this.change(); if (cr == null) fail("Script is not saved: " + script); var parsed = cr.parsedScriptMandatory(); ret parsed!; }); nScriptsRun(nScriptsRun+1); } } void init() { if (ctrlListener != null) ret; scripts.clear(); var scripts = conceptsWhere(g22utils.concepts, G22LeftArrowScript, runOnProjectOpen := true); var sorted = sortByCalculatedFieldAlphaNumIC(scripts, s -> s.runOrder); for (script : sorted) this.scripts.add(new AutoStartScript(script)); change(); ctrlListener = tempAddGlobalCtrlKeyListener(b -> { if (b) { ctrlPressed.raise(); cancel(); } }); } void start { print("G22AutoStarter: Start"); if (enabled && started.raise()) thread { pcall { change(); temp g22utils.backgroundProcessesUI.tempAdd("Auto-Start Scripts", ); print("G22AutoStarter: Sleeping"); while (initialDelay > 0) { sleepSeconds(1); initialDelay(initialDelay-1); } waited.raise(); change(); print("G22AutoStarter: Slept"); for (script : scripts) pcall { if (!enabled) break; currentScript(script); change(); script.run(); currentScript(null); change(); } done.raise(); change(); close(); }} print("G22AutoStarter: Started"); } void cancel { setEnabled(false); } S status() { ret !enabled ? ctrlPressed! ? "Cancelled due to ctrl key" : "Cancelled" : done! ? "Done" : waited! ? "Started" : started! ? "Pre-start wait (" + formatDouble1(initialDelay) + "s)" : "Not started"; } S stats() { ret status() + ". " + scriptsRunStats(); } S scriptsRunStats() { ret "Scripts run: " + nScriptsRun() + "/" + l(scripts); } S currentScriptStats() { var s = currentScript; if (s == nul) ret ""; ret "Running: " + s.script; } close { dispose ctrlListener; } bool done() { ret done!; } void waitUntilDone { done.waitUntilUp(); } }