ludic/examples/library/process.ludic
Orkuncakilkaya 43d5eb5b88 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>
2026-09-17 13:32:23 +03:00

42 lines
1.6 KiB
Text

# process.ludic — Process.* : start a child, poll it without waiting, read its exit code.
#
# let h = Process.spawn("/path/to/game", ["--profile", "Maroon Lake"])
# handler Update { # each frame, never blocking
# let code = Process.poll(h) # -1 while it runs, then the exit code
# if code >= 0 { Process.free(h) }
# }
#
# No shell is involved: every argument arrives in the child exactly as given. This run
# uses /bin/sh as the child (so it is a POSIX check) and prints:
# 3 1 7 137 -1 255
program ProcessDemo {
function bi(b: bool) -> int { if b { return 1 }; return 0 }
entry {
# a child that takes a second and exits 3: poll answers -1 many times, then 3
let a = Process.spawn("/bin/sh", ["-c", "sleep 1; exit 3"])
var polls = 0
var code = Process.poll(a)
while code < 0 { polls += 1; code = Process.poll(a) }
Process.free(a)
# arguments are passed through untouched - spaces, quotes and all
let b = Process.spawn("/bin/sh", ["-c", "test \"$1\" = 'a b\"c' && exit 7; exit 1", "sh", "a b\"c"])
var cb = Process.poll(b)
while cb < 0 { cb = Process.poll(b) }
Process.free(b)
# a long child, killed: 128 + SIGKILL
let c = Process.spawn("/bin/sleep", ["30"])
let running = Process.poll(c)
Process.kill(c)
var cc = Process.poll(c)
while cc < 0 { cc = Process.poll(c) }
Process.free(c)
# a program that is not there, and a handle that is not one
let d = Process.spawn("/definitely/not/here", new []string)
print(`{code} {bi(polls > 100)} {cb} {cc} {d} {Process.poll(99)}`)
if running != -1 { print("sleep was not running") }
}
}