;;;; A program that pushes values into the watch table from its own loop. ;;;; ;;;; Two ways in. A scalar reaches the watch entry points as ordinary C ;;;; functions, through [declare-c]. A struct, a slice or anything else goes ;;;; through the [(watch "name" v)] form, which renders it the way print does. ;;;; ;;;; The values are written every iteration and are *not* read back from here. ;;;; What reads them is the daemon's [watch] op, over the agent, while this ;;;; program is still running — which is the whole design: the program pushes ;;;; at frame rate and the editor reads memory. (import agent "vendor:agent") (declare-c watch-i64 [name str x i64] i32 "flan_dev_watch_i64") (declare-c watch-f64 [name str x f64] i32 "flan_dev_watch_f64") (declare-c watch-str [name str s str] i32 "flan_dev_watch_str") ;; The accumulator, for a value sampled from inside a hot loop. A scalar watch ;; there shows whichever iteration happened to run last, which is the case this ;; exists for; see flan_dev.c, "A number sampled thousands of times a frame". (declare-c watch-num-i64 [name str x i64] i32 "flan_dev_watch_num_i64") (defonce ticks i64) (defstruct Pos [x i32 y f64]) (defn loop-cells [] i32 (let [i 0] (while (< i 8) (watch-num-i64 "cell" (i64 (* i 3))) (set i (+ i 1))) i)) (defn step [] i64 (set ticks (+ ticks 1)) ;; Three types, because the table stores *rendered text* and the rendering ;; is per type: an i64 and an f64 do not print the same way, and a string is ;; quoted and escaped so that a newline in one cannot become a second row. (watch-i64 "ticks" ticks) (watch-f64 "half" (/ (f64 ticks) 2.0)) (watch-str "label" "sand") ;; The form: a struct, a slice, and a scalar through the same form. (watch "pos" (Pos {.x 3 .y 1.5})) (watch "row" [1 2 3]) (watch "t2" (* ticks 2)) ;; A dyn value renders through the dyn printer into the slot, and a string ;; through the form is quoted. (watch "d" {:a 1}) (watch "s" "x") ;; A hot inner loop, and the value *varies* across it — which is what makes ;; the row a test of the accumulator rather than of the plumbing. A slot that ;; only kept [last] would report 21 and no range; n, min and max are each ;; pinned by a different part of this loop. (loop-cells) ticks) (defn main [] i32 (agent/start "/tmp/flan-dev-watch-fallback.sock") ;; A watch call costs a load and a not-taken branch until somebody opens a ;; watch buffer, so spinning here writes nothing until the test arms it. (while (= (agent/wait 20) 0) (step)) (step) (while (= (agent/wait 20) 0) (step)) 0)