Browse Source

Added Introspection handler for dynarrays

* Any dynarray of structs now be written with Introspection. I'm
really pleased with how easy it was to implement this
* Added struct-size which was essential for this application
* write-introspect-struct-s-expr now returns success/failure
windows-imgui
Macoy Madson 5 months ago
parent
commit
91645c1559
  1. 56
      src/DynamicArray.cake
  2. 41
      src/Introspection.cake
  3. 6
      test/src/GameLibTests.cake

56
src/DynamicArray.cake

@ -151,6 +151,37 @@
(token-splice-rest format-arguments tokens)))
(return true))
(comptime-cond
('Introspection
(import "Introspection.cake")
;; This is so awesome
(introspect-override-register-handler 'write-s-expr
(metadata-field-has-tag field "'dynarray")
write-dynarray-ptr
(var dynarray-ptr-write (* (* void))
(offset-pointer-to-type struct-to-write value-offset (* (* void))))
(if (and (deref dynarray-ptr-write)
(dynarray-length (deref dynarray-ptr-write)))
(scope
(fprintf out-file " (dynarray ")
(var num-elements int (dynarray-length (deref dynarray-ptr-write)))
(each-in-range num-elements i
(var current-element (* void)
(offset-pointer-to-type (deref dynarray-ptr-write)
(* i (path (path field > field-type-metadata) > struct-size))
(* void)))
(unless (write-introspect-struct-s-expr
(path field > field-type-metadata)
current-element out-file
;; TODO: Pay attention to parent output settings
(? (= i (- num-elements 1)) write-introspect-struct-default
write-introspect-struct-add-newline))
(return false)))
(fprintf out-file ")"))
(fprintf out-file " null"))
(return true))))
(comptime-cond
('auto-test
(c-import "stdio.h")
@ -220,4 +251,27 @@
(dynarray-free my-uninitialized-string)
(dynarray-free my-string)
(dynarray-free my-quick-string)
(return 0))))
(return 0))
(comptime-cond
('Introspection
(import "Introspection.cake")
(def-introspect-struct array-data
value float)
(def-introspect-struct my-dynarray-struct
items (* array-data) (override 'dynarray))
(defun test--dynamic-array-introspection (&return int)
(var baseline my-dynarray-struct (array 0))
(dynarray-set-length (field baseline items) 10)
(each-item-addr-in-dynarray (field baseline items) i data (* array-data)
(set (path data > value) (type-cast i float)))
(unless (write-introspect-struct-s-expr my-dynarray-struct--metadata
(addr baseline) stderr
write-introspect-struct-add-newline)
(return 1))
(dynarray-free (field baseline items))
(return 0))))))

41
src/Introspection.cake

@ -10,6 +10,10 @@
;; Comptime
;;
;; Allows modules to conditionally define introspection overrides in GameLib without requiring
;; everything use Introspection
(comptime-define-symbol 'Introspection)
(defun-comptime is-type-string (tokens (& (const (<> (in std vector) Token)))
start-type-token-index int
;; Will distinguish which sub-type of string it is
@ -301,7 +305,8 @@
(var (token-splice-addr metadata-name) metadata-struct
(array (token-splice-addr struct-name-to-str)
(token-splice-addr metadata-fields-name)
(array-size (token-splice-addr metadata-fields-name))))
(array-size (token-splice-addr metadata-fields-name))
(sizeof (type (token-splice struct-name)))))
;; Allow access to the metadata without having to declare all the types in the header
(forward-declare (struct metadata-struct)) ;; TODO Would be nice to not do this for every struct
@ -622,7 +627,9 @@
name (* (const char))
;; type introspect-struct-type ;; Almost always field-by-field, but TODO let them override the whole process
members (* (const metadata-field))
num-members size_t)
num-members size_t
struct-size size_t)
;;
;; Runtime
@ -673,7 +680,8 @@
(defun write-introspect-struct-s-expr (struct-metadata (* (const metadata-struct))
struct-to-write (* (const void))
out-file (* FILE)
write-options write-introspect-struct-options)
write-options write-introspect-struct-options
&return bool)
(fprintf out-file "(%s" (path struct-metadata > name))
(each-in-range (path struct-metadata > num-members) i
@ -731,11 +739,13 @@
((= (path field > type) introspect-type-override)
(introspect-field-dispatch field value-offset
(write-s-expr-handle-override (introspect-override-invocation-args 'write-s-expr))))
(unless (write-s-expr-handle-override (introspect-override-invocation-args 'write-s-expr))
(return false))))
(true
(fprintf out-file " <unknown>")
(fprintf stderr "warning: attempted to write field of unknown type %d\n" (path field > type))))
;; (fprintf out-file " <unknown>")
(fprintf stderr "error: attempted to write field of unknown type %d\n" (path field > type))
(return false)))
(when (path field > count)
(fprintf out-file ")"))
@ -744,7 +754,8 @@
(fprintf out-file ")")
(when (= write-options write-introspect-struct-add-newline)
(fprintf out-file "\n")))
(fprintf out-file "\n"))
(return true))
(def-function-signature-global allocate-string-function (num-bytes size_t &return (* void)))
(def-function-signature-global free-string-function (string-to-free (* void)))
@ -1337,14 +1348,17 @@
null))
(fprintf stderr "Struct A baseline:\n")
(write-introspect-struct-s-expr my-struct--metadata (addr a) stderr
write-introspect-struct-add-newline)
(unless (write-introspect-struct-s-expr my-struct--metadata (addr a) stderr
write-introspect-struct-add-newline)
(return 1))
(scope ;; Write to a file
(var out-file (* FILE) (fopen "TestSerialize.cakedata" "w"))
(unless out-file (return 1))
(write-introspect-struct-s-expr my-struct--metadata (addr a) out-file
write-introspect-struct-add-newline)
(unless (write-introspect-struct-s-expr my-struct--metadata (addr a) out-file
write-introspect-struct-add-newline)
(fclose out-file)
(return 1))
(fclose out-file))
(scope ;; Now read it back
@ -1363,8 +1377,9 @@
(fclose in-file))
(fprintf stderr "Read-in struct:\n")
(write-introspect-struct-s-expr my-struct--metadata (addr read-struct) stderr
write-introspect-struct-add-newline)
(unless (write-introspect-struct-s-expr my-struct--metadata (addr read-struct) stderr
write-introspect-struct-add-newline)
(return 1))
;; (set (field read-struct value) 0)
(unless (= 0 (compare-introspect-struct-print-result my-struct--metadata

6
test/src/GameLibTests.cake

@ -37,8 +37,8 @@
(true
"src/Config_Linux.cake")))
;; (var test-minimal bool true)
(var test-minimal bool false)
(var test-minimal bool true)
;; (var test-minimal bool false)
;; (var test-opengl-only bool true)
(var test-opengl-only bool false)
@ -52,7 +52,7 @@
"Auto Test (data structures only)"
(array platform-config
"../src/AutoTest.cake" "../src/Dictionary.cake"
"../src/DynamicArray.cake" "../src/Introspection.cake")))
"../src/Introspection.cake" "../src/DynamicArray.cake")))
(test-opengl-only
(gamelib-run-test

Loading…
Cancel
Save