flan/test/programs/virtual-controls-headless.flan
Joseph Ferano 2e203f64b8 bytes copies, bytes-view aliases, and a dev-session segfault parks
The INSERTIONSORT crash, all three rulings (FIX.org 2026-09-20):

- (bytes s) allocates a writable copy through the allocator surface —
  context or (bytes s a), StorageExhausted with retry, a registry note in
  dev builds (flan_bytes_dup, lowered like vec-new). (bytes-view s) is the
  old zero-cost reinterpret, renamed, read-only by convention; every
  in-repo reader swept over to it. (string b) unchanged.
- String constants were already read-only on both backends at -O0; now
  pinned — bytes-copy.flan rows on LLVM/-O0/--x86, and dies_segv rows
  asserting the write-through-view trap on both backends.
- A dev build installs a SIGSEGV/SIGBUS handler by the same dev-only
  constructor slot that arms the registry: one line naming the address and
  the innermost frame, then the trap-hook park — stopped, not dead, the
  daemon serving. No agent: message and re-raise. Release builds untouched.
  Pinned by trap_park over dev-segv.flan.
2026-09-20 23:12:42 +07:00

60 lines
2.8 KiB
Plaintext

;;;; core-input-virtual-controls.flan's other half: no window, a scripted
;;;; pointer, hash where the player ended up.
;;;;
;;;; The same split sand.flan and sand-headless.flan already have, and it is
;;;; available here for the same reason: the interesting part of that example —
;;;; which D-pad button is under the pointer, and what a held button does to
;;;; the player — is arithmetic over numbers, so it runs with no window, no GL
;;;; context and no libraylib. The link follows what the program reaches:
;;;; nothing below calls into raylib, so no shim is compiled and no -lraylib is
;;;; passed, and the example's own drawing functions are never emitted — which
;;;; was checked with ldd on the built binary: libm and libc and nothing else.
;;;; The example's `main` is not exported, so the only main is this one.
;;;;
;;;; Unlike sand-headless there is no wasm32 case for it yet. Nothing here
;;;; should stop one, for exactly the reason above — but it has not been run,
;;;; so it is not claimed.
;;;;
;;;; It is the only one of the ten ported examples with a headless case, and
;;;; the honest reason is that it is the only one that earns it. The other nine
;;;; are input read straight into drawing calls: a test of them would assert
;;;; that raylib answers 0 for every input with no window open, which is also
;;;; what a binding with its arguments crossed would answer.
;;;;
;;;; What this DOES pin: that the four buttons are where the geometry says they
;;;; are, that the diamond hit test uses x and y the right way round, and that
;;;; the four directions move the player the four different ways. A crossed
;;;; axis anywhere in nearest-button or move-player changes the hash.
(import vc "../../examples/core-input-virtual-controls.flan")
(import rl "vendor:raylib")
;; A sixtieth of a second, fixed. The real program uses get-frame-time, which
;; is exactly the thing a headless run has no answer for.
(defconst dt f32 0.0166666)
;; A lawnmower sweep over the pad's corner of the screen, two pixels at a time.
;; It crosses all four buttons and the dead space between them, so every branch
;; of nearest-button is taken and button-none is taken most of all.
(defconst sweep-x0 20)
(defconst sweep-x1 180)
(defconst sweep-y0 280)
(defconst sweep-y1 420)
(defconst sweep-step 2)
(defn main [] i32
(vc/reset-player)
(let [y sweep-y0]
(while (<= y sweep-y1)
(let [x sweep-x0]
(while (<= x sweep-x1)
(let [p (rl/Vector2 {.x (f32 x) .y (f32 y)})]
(vc/move-player (vc/nearest-button p) dt))
(set x (+ x sweep-step))))
(set y (+ y sweep-step))))
;; write-stdout and i64->bytes are builtins (lib/check.ml), not prelude
;; functions, so this does not go through the printers.
(write-stdout (i64->bytes (i64 (vc/hash-player))))
(write-stdout (bytes-view "\n"))
0)