Prior to 4.0, scripts have been executed on the Event Dispatch Thread (EDT), which is the thread that handles the user interface. Long-running calculations should never be performed on the EDT, as it will block the UI until the calculations are complete. For instance running the script while (true) {}
in OmegaT 3.6 will freeze the whole program, requiring a force-quit.
In 4.0 all scripts are executed on a background thread, which means that long-running (or even forever-running) scripts can be safely run.
A consequence of this is that scripts that manipulate the GUI must take some care to only perform GUI manipulations on the EDT. This is required because Swing components are generally not thread-safe, and concurrent method calls can corrupt their internal state. (Learn more)
GUI manipulations are usually invoked on the EDT by calling SwingUtilities.invokeAndWait()
or .invokeLater()
. For the convenience of script writers, OmegaT will also recognize a top-level function called gui
, and will run this on the EDT. Script writers should put their GUI-manipulating code in this function and not invoke it. Recommended syntax for defining this function without extraneous console output is:
def gui() { ... }
var gui = function() { ... }
When run in a background thread it is possible to cancel scripts in the middle of execution. A Cancel button has been added to the Scripting Window for this purpose (there is not yet an interface for canceling event-based scripts).
However, OmegaT cannot unilaterally cancel a running script; the script itself must be written to check for cancelation, and exit as appropriate. For instance, if a script does some processing in a loop, it can do something like this:
while (work to do) { if (java.lang.Thread.interrupted()) { break; } // do work }
Exiting a closure-based loop such as Groovy's each
requires throwing an exception. More info: http://stackoverflow.com/a/3050218/448068
Implemented in the released version 4.0 of OmegaT.
Didier