fn(int, float) -> bool is a type, fn name is any top-level function's value, and a call through a local, a global, a record field, a slice element, a parameter or a result of a function type is an indirect call; two function types mix only when equal, a call checks its argument count, and a value may be null (examples/functions/values.ludic). Job.parallel_for keeps its worker check. render3d's scene is registered rather than required by name: r3d_on_draw, r3d_on_casters and r3d_on_stream_fill (hooks.ludic). The two rendering examples register theirs - and had defined scene_draw_casters with no parameter while the renderer passed one, which nothing checked. render3d declares numbers float itself; smooth.ludic is converted to floats and returns when r3d_init fails instead of running on into a segfault. Noise.* check their argument count (a call one short crashed the compiler). selfhost-build says why it failed. The migration tool reads a declared float as evidence. Seed regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
17 lines
1.1 KiB
Text
17 lines
1.1 KiB
Text
# hooks.ludic - the scene a frame draws, as callbacks the program registers. They used to be
|
|
# functions every program had to define by name (scene_draw, scene_draw_casters, stream_fill),
|
|
# a contract only the linker enforced and that allowed one scene per program.
|
|
var r3d_draw_cb: fn() = null
|
|
var r3d_casters_cb: fn(floats) = null
|
|
var r3d_fill_cb: fn(Stream, int, int, int) = null
|
|
|
|
# what a frame draws, for every pass that draws the scene (the view, the reflection)
|
|
function r3d_on_draw(f: fn()) -> void { r3d_draw_cb = f }
|
|
# what casts a shadow, drawn into the light's view `light_vp`
|
|
function r3d_on_casters(f: fn(floats)) -> void { r3d_casters_cb = f }
|
|
# a streamed layer's chunk (cx, cz) at detail `band`, filled with its instances
|
|
function r3d_on_stream_fill(f: fn(Stream, int, int, int)) -> void { r3d_fill_cb = f }
|
|
|
|
function r3d_scene_draw() -> void { if r3d_draw_cb != null { r3d_draw_cb() } }
|
|
function r3d_scene_casters(light_vp: floats) -> void { if r3d_casters_cb != null { r3d_casters_cb(light_vp) } }
|
|
function r3d_stream_fill(s: Stream, cx: int, cz: int, band: int) -> void { if r3d_fill_cb != null { r3d_fill_cb(s, cx, cz, band) } }
|