AlexCharlton / cl-glfw3

Common Lisp bindings to GLFW version 3.x
BSD 2-Clause "Simplified" License
89 stars 32 forks source link

Create window by functional return of parameters #24

Closed tavurth closed 7 years ago

tavurth commented 7 years ago

I found it restricting that the arguments to with-init-window should be a hard-coded list.

(defun my-parameter-generator () 
  '(:width 100 :height 100 :title "My Test Window"))

(with-init-window-from-list (my-parameter-generator)
  (loop ...))

Or:

(with-init-window-from-list (list :width 100 :height 100 :title "My title")
  (loop ...))
AlexCharlton commented 7 years ago

Cool! Is it just me, or could these macros straight up replace with-window and with-init-window without changing their contracts?

Thanks!

tavurth commented 7 years ago

Unfortunately it would cause breaking changes to the current examples:

    (with-init-window (:title "Window test" :width 600 :height 400)
        (loop ...))

While the first parameter is a symbol, it's not resolved as a list.

I'll take a look at it later to see if I can just do (eq (type-of (car list-or-func) 'FUNCTION)) and then branch from there. Perhaps Monday evening, if you'll hold out on the merge.

AlexCharlton commented 7 years ago

Sounds good 👍

tavurth commented 7 years ago

So, passing dynamic parameters is a headache, because we use the rest parameter to catch all parameters in a list style, the macro doesn't expand well.

We're usually nesting it within several layers of other macros (with-body-in-main-thread), and it seems to fail correct compilation every time.

The examples weren't working, as they were in one global package. I fixed them by moving them to submodules, and added package-names showing where each function is getting called from (glfw, gl, tmt etc).

Added a ./examples/run-all.lisp script to test all the current examples.

tavurth commented 7 years ago

This should work, but doesn't inside the parent macros:

(defun called-before (&rest keys)
  (format t "Called before: ~A~%" keys))

(defun called-inside ()
  (format t "Called inside~%"))

(defun called-after ()
  (format t "Called after~%"))

(defun callback (&rest rest)
  '("From callback"))

(defmacro resolve-list ((&rest keys) &body body)
   `(unwind-protect
      (progn
        ,(cond

           ;; Called with a function
           ((fboundp (car keys))
             `(apply #'called-before ,keys))

           ;; Called with a list
           ((typep (car keys) 'symbol)
             `(called-before ,@keys)))

           ,@body)
        (called-after)))

(resolve-list
  (:test 123)
  (called-inside))

(resolve-list
  (callback 12 3)
  (called-inside))