39 lines
1.2 KiB
Plaintext
39 lines
1.2 KiB
Plaintext
;;;; ((Ptr T) p) and (slice-from p n) together: the bytes of one array read as
|
|
;;;; another element type, the way a C void * or a (Ptr u8) pixel buffer is
|
|
;;;; read as the structs it holds.
|
|
|
|
(defstruct Rgba [r u8 g u8 b u8 a u8])
|
|
|
|
(defonce bytes [8 u8])
|
|
|
|
(defn sum [s [const Rgba]] i32
|
|
(let [acc 0]
|
|
(dotimes [i (length s)]
|
|
(set acc (+ acc (i32 (.g (at s i))))))
|
|
acc))
|
|
|
|
(defn main [] ()
|
|
(dotimes [i 8]
|
|
(set (at bytes i) (u8 (+ i 1))))
|
|
|
|
;; Eight bytes are two Rgba. The count is an i64, not an i32.
|
|
(let [p ((Ptr Rgba) (addr (at bytes 0)))
|
|
n (i64 2)
|
|
px (slice-from p n)]
|
|
(println (length px)) ; 2
|
|
(println (.r (at px 0))) ; 1
|
|
(println (.a (at px 1))) ; 8
|
|
;; A write through the cast pointer is a write to the bytes.
|
|
(set (.b (at px 1)) 70)
|
|
(println (at bytes 6))) ; 70
|
|
|
|
;; Adding const is allowed, and the slice keeps it.
|
|
(let [c ((Ptr const Rgba) (addr (at bytes 0)))]
|
|
(println (sum (slice-from c (u8 2))))) ; 8
|
|
|
|
;; And back: the struct pointer read as bytes again.
|
|
(let [p ((Ptr Rgba) (addr (at bytes 0)))
|
|
b ((Ptr u8) p)]
|
|
(println (deref b)) ; 1
|
|
(println (length (slice-from b 8))))) ; 8
|