feat(launcher): Process.*, Http.save_to/received/expected, App.window_hide/show

Process.spawn/poll/kill/free - non-blocking child processes with no shell: posix_spawn on
macOS (process.ll), CreateProcessW with MSVC-quoted arguments and no console window on
Windows (process_win.ll), linked only when a program uses Process.*.

Http.save_to streams a response body into a file (NSURLSession with a run-time delegate
class on macOS, the WinHTTP read loop on Windows); Http.received / Http.expected report
progress while it is pending. Freeing a pending request cancels it and parks the slot
until the worker has finished.

App.window_hide / App.window_show take the game's window off the screen and back without
closing it; the run goes on while hidden. Docs, examples, tests and a changeset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-17 13:32:23 +03:00
parent c1db0d71ed
commit 43d5eb5b88
31 changed files with 89274 additions and 86727 deletions

View file

@ -254,6 +254,8 @@ function p_postfix() -> Node {
if e.a.kind == E_ID and e.a.s == "Http" { g_uses_http = true }
# Udp.* — any Udp method splices the datagram runtime (and links udp.ll / udp_win.ll).
if e.a.kind == E_ID and e.a.s == "Udp" { g_uses_udp = true }
# Process.* — any Process method splices the child-process runtime (process.ll / process_win.ll).
if e.a.kind == E_ID and e.a.s == "Process" { g_uses_process = true }
# Gl.* — any Gl method splices the OpenGL runtime (and links the GL backend).
if e.a.kind == E_ID and e.a.s == "Gl" { g_uses_gl = true }
# Vk.* — any Vk method splices the Vulkan runtime (and links its loader)
@ -680,6 +682,7 @@ var g_uses_fx: bool = false # Fx.sparks/number/clear -> splice fx.ludic; f
var g_uses_audio: bool = false # Audio.* (#22) -> splice audio.ludic; a windowed build also links audio.ll + AVFoundation
var g_uses_http: bool = false # Http.* (#6) -> splice http.ludic; links http.ll + Foundation (macOS)
var g_uses_udp: bool = false # Udp.* -> splice udp.ludic; links udp.ll (macOS) / udp_win.ll + ws2_32
var g_uses_process: bool = false # Process.* -> splice process.ludic; links process.ll (macOS) / process_win.ll
var g_uses_gl: bool = false # Gl.* -> splice gl.ludic (+ generated gl_api.ludic); links gl.ll + gl_thunks.ll + OpenGL
var g_uses_vk: bool = false # Vk.* -> splice vk.ludic (+ generated vk_api.ludic); links vk_thunks.ll + the platform loader
# issue #64: functions marked @System(Phase) in a prebuilt binary module — the
@ -1197,6 +1200,13 @@ function maybe_splice_runtime() -> void {
do_import("runtime/native/udp.ludic")
cur_dir = saved
}
# Process.*: splice the child-process library. Spawning is native (process.ll /
# process_win.ll); the argv array and the Windows command line are built in Ludic.
if g_uses_process {
cur_dir = ""
do_import("runtime/native/process.ludic")
cur_dir = saved
}
# Gl.*: splice the OpenGL surface (gl.ludic + the generated gl_api.ludic). The
# native calls are the linked GL entry points themselves; the window attach is
# is_windowed()-guarded, so a headless build renders into an offscreen context.