(asdf:oos 'asdf:load-op 'ltk) (asdf:oos 'asdf:load-op 'cgn) (use-package :ltk) (use-package :cgn) (let ((n 0)) (defstruct range ;; A range (scale) (id (incf n)) name start stop (inc 1)) (defstruct action ;; An action button (id (incf n)) name fn) ) (defparameter *things* (make-hash-table)) (defparameter *inputs* '()) (defun things () (maphash #'(lambda (key value) (format t "~a = ~a ~%" key value)) *things*)) (defun reset-inputs () (setf *inputs* '())) (defun reset-things () (setf *things* (make-hash-table))) (defmacro defmodel (name parameters &body body) (reset-things) (let ((params1 (mapcar #'second parameters)) (side-effects (mapcar #'(lambda (x) (fx (first x) (second x) (cddr x))) parameters)) inputs) ;; Collect the inputs (maphash #'(lambda (k v) (if (not (equal (type-of v) 'action)) (setf inputs (append inputs (list v))))) *things*) `(progn (defun ,name ,params1) ,@body ,@side-effects))) (defun range-to-scale (range &optional master) (with-ltk () (let ((tmp (make-instance 'scale :from (range-start range) :to (range-stop range) :master master :orientation 'horizontal :resolution (range-inc range)))) (pack tmp)))) (defun fx (isa name range) (case isa (:range (fx-range name range)) (:action (fx-action name range)) (t nil))) (defun fx-range (name range) ;; Create a new range with a given name and up to 3 additional ;; parameters for start, stop, and resolution. (let ((tmp (make-range :name name :start (first range) :stop (second range)))) (if (= 3 (length range)) (setf (range-inc tmp) (third range))) (setf (gethash name *things*) tmp) t)) (defun fx-action (name action) ;; Create a new action button. Takes two parameters: a name ;; and a function. (let ((tmp (make-action :name name :fn (car action)))) (setf (gethash name *things*) tmp) t)) ; (defun evett-gnuplot () t) (defun evett-plots () t) (defmodel evett ((:range lambda 1 700) (:range in 1 5) (:range fvalue 0.1 0.25 0.1) (:action gen3d #'evett-gnuplot) (:action gen #'evett-plots)) (+ in))