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.

Last updated

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#