Blitz3D+ Language Reference

Jobs and Worker Functions

Extended mode can run finite CPU and read-only file work on an isolated background thread. Jobs are independent of windows, graphics, and the GUI event queue. The main program polls or waits, then explicitly transfers a serialized Bank result. For a practical introduction and game-loop patterns, see Using Background Jobs.

Declaration and submission

Worker Function BuildData(inputBank)
    outputBank = CreateBank(4)
    PokeInt outputBank, 0, PeekInt(inputBank, 0) * 2
    Return outputBank
End Function

job = StartJob(BuildData, inputBank, revision)

A public entry accepts one Integer slot containing its input Bank and returns one Integer slot containing a worker-created Bank. StartJob copies the input before returning, so the caller may immediately modify, resize, or free its source. Passing zero supplies an empty read-only Bank. Ordinary code cannot call a Worker Function directly.

Isolation rules

Worker locals may use Int, Float, Long, Double, String, fixed arrays, local Types, Lists, Maps, Sets, Queues, Stacks, Banks, deterministic math and random commands, and read-only files/directories/streams. Worker helpers must also be declared with Worker Function.

Workers cannot access main globals or dynamic arrays, ordinary Functions or Methods, engine/world/entity/graphics, physics, audio, input, GUI, timers, sockets, multiplayer services, UserLibs, DLL calls, writable files, process environment mutation, DATA/READ/Restore, Gosub, or nested Jobs and waits. A runtime command is main-only unless the runtime explicitly classifies it as worker-safe.

Cancellation, progress, and results

Cancellation is cooperative. The compiler inserts safe points at worker and helper entry and on every generated loop backedge. JobCancelled() remains available for an algorithm that wants a graceful branch. SetJobProgress publishes advisory done/total/stage snapshots.

Use PollJob in a game loop. WaitJob and WaitAnyJob use synchronization but do not render, pump GUI events, or invoke generated callbacks. Compare JobTag with the application's current revision before applying a result. TakeJobResult transfers a successful Bank once; FreeJob releases the handle and any unclaimed data.

States

JOB_QUEUED = 1
JOB_RUNNING = 2
JOB_SUCCEEDED = 3
JOB_FAILED = 4
JOB_CANCELLED = 5

Failures remain within the Job. JobError and its file, line, and function queries return bounded main-thread copies. Worker debug hooks never open the GUI debugger from the background thread.

Complete example

Open the complete Worker Function example.

Worker Function DoubleValue(inputBank)
    outputBank = CreateBank(4)
    PokeInt outputBank, 0, PeekInt(inputBank, 0) * 2
    SetJobProgress 1L, 1L, "Complete"
    Return outputBank
End Function

inputBank = CreateBank(4)
PokeInt inputBank, 0, 21
job = StartJob(DoubleValue, inputBank, 1L)
FreeBank inputBank

While Not JobFinished(job)
    Delay 1
Wend
If JobState(job) <> JOB_SUCCEEDED Then RuntimeError JobError(job)
resultBank = TakeJobResult(job)
If PeekInt(resultBank, 0) <> 42 Then RuntimeError "Unexpected result"
FreeBank resultBank
FreeJob job
End