Threads
Which of your menu code runs on the game's main thread, what may be called from other threads, and where blocking work belongs.
On this page
Everything the library calls on your screens runs on the game's main (client) thread. Blocking work belongs
in runAsync.
The rules#
| Code | Thread |
|---|---|
Builders (MenuScreen.builder(…)…build(), every widget builder) |
any |
MultiversionUi.register |
any; Forge may construct mods in parallel |
ScreenFactory.create and buttonLabel |
main |
Suppliers: labels, values, enabled, visible, tooltips, rows, validators |
main |
Actions: onPress, onChange, onSelect, onToggle, dialog answers |
main |
runAsync's task |
a background thread of your menu's own |
runAsync's onDone |
main |
UiHost methods other than runOnMainThread |
call them on main |
UiHost.runOnMainThread, StatusLine.show and clear, MultiversionUi.reloadGameOptions |
any |
MultiversionUi.menuScreen |
main |
Don't block the main thread#
An action that reads a file, waits for a lock or calls the network freezes the game until it returns. Run it
with host.runAsync(task, onDone). Meanwhile the screen shows Working… and ignores input, and onDone
gets the result back on the main thread. See Slow work: files and network.
One worker per mod#
A registered menu's runAsync tasks run on a thread of their own, one at a time, in the order they were
started. A task that hangs holds up only that mod's menu. Other mods' menus, and the game, keep running.
Getting back to the main thread#
From your own threads or callbacks, host.runOnMainThread(task) runs task on the main thread soon. It doesn't
refresh the screen afterwards, so call host.refresh() inside the task if it changed what the screen shows.
Next steps#
- Failure isolation: what happens when code on either thread throws.