Create general “state”-system

… by which an individual state's loop can plug
in another superceding loop function. Ex.,
a menu giving way to a sub-menu.
This commit is contained in:
Jaidyn Ann 2023-06-08 21:57:51 -05:00
parent e6e4410a91
commit 21cfca30d2
2 changed files with 56 additions and 34 deletions

View File

@ -13,9 +13,9 @@
;;;; You should have received a copy of the GNU General Public License ;;;; You should have received a copy of the GNU General Public License
;;;; along with this program. If not, see <https://www.gnu.org/licenses/>. ;;;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;; FLORA-SEARCH-AURORA ;;;; FLORA-SEARCH-AURORA
;; A simple TUI-game made for the text-flavoured LibreJam of 2023-06! ;;;; A simple TUI-game made for the text-flavoured LibreJam of 2023-06!
;; See: https://jamgaroo.xyz/jams/2 ;;;; See: https://jamgaroo.xyz/jams/2
(ql:quickload '(alexandria assoc-utils cl-charms cl-tiled str)) (ql:quickload '(alexandria assoc-utils cl-charms cl-tiled str))
@ -32,18 +32,42 @@
(in-package :flora-search-aurora) (in-package :flora-search-aurora)
(defun state-loop (loops &optional (last-matrix (make-screen-matrix)) (matrix (make-screen-matrix)))
(when loops
(let ((loop-result
(apply (car loops) (list matrix))))
(print-screen-matrix (matrix-delta last-matrix matrix))
(force-output)
(state-loop
(cond ((functionp loop-result)
(cons loop-result loops))
((not loop-result)
(cdr loops))
('t loops))
matrix))))
(defun main () (defun main ()
"A pathetic fascimile of a main loop. Look, I'm still tinkering!" "A pathetic fascimile of a main loop. Look, I'm still tinkering!"
(let ((matrix (make-screen-matrix)) (let* ((options-menu
(items `(((LABEL . "PLAY") (SELECTION . 100) (SELECTED . T)) `(((LABEL . "IDK") (SELECTION . 100) (SELECTED . T)
((LABEL . "QUIT") (SELECTION . 100) (FUNCTION . ,(lambda () (print "AAAAAA")))) (FUNCTION . ,(lambda () (print "¯\_(ツ)_/¯"))))
((LABEL . "ESCAPE")) ((LABEL . "GO BACK") (FUNCTION . ,(lambda () nil)))))
((LABEL . "RUN AWAY") (SELECTION . -100))))) (main-menu
`(((LABEL . "CRY OUT") (SELECTED . T) (FUNCTION . ,(lambda () (print "AAAAAA"))))
((LABEL . "RUN AWAY") (FUNCTION . ,(lambda () nil)))
((LABEL . "SUBMENU")
(SELECTION . -100)
(FUNCTION
. ,(lambda ()
(lambda (matrix)
(menu-loop matrix options-menu))))))))
(cl-charms:with-curses () (cl-charms:with-curses ()
(cl-charms:enable-raw-input :interpret-control-characters 't) (cl-charms:enable-raw-input :interpret-control-characters 't)
(clear-screen) (clear-screen)
(print-screen-matrix matrix) (state-loop (list (lambda (matrix) (menu-loop matrix main-menu)))))))
(ui-loop matrix items))))
;; (print-screen-matrix ;; (print-screen-matrix
; (render-menu-strip matrix items 2 5 ; (render-menu-strip matrix items 2 5
;; :max-item-width 20 :height 3))) ;; :max-item-width 20 :height 3)))

34
ui.lisp
View File

@ -19,7 +19,7 @@
(defpackage :flora-search-aurora.ui (defpackage :flora-search-aurora.ui
(:use :cl :flora-search-aurora.display :flora-search-aurora.input :assoc-utils) (:use :cl :flora-search-aurora.display :flora-search-aurora.input :assoc-utils)
(:export #:ui-loop #:render-menu-strip :label :selection :selected)) (:export #:menu-loop #:render-menu-strip :label :selection :selected))
(in-package :flora-search-aurora.ui) (in-package :flora-search-aurora.ui)
@ -27,29 +27,24 @@
;;; ——————————————————————————————————— ;;; ———————————————————————————————————
;;; Menu loops ;;; Menu loops
;;; ——————————————————————————————————— ;;; ———————————————————————————————————
(defun ui-loop (last-matrix menu-alist) (defun menu-loop (matrix menu-alist)
"The state loop to be used for displaying/processing/input-managing "The state loop to be used for displaying/processing/input-managing
with menus." with menus."
(let* ((matrix (make-screen-matrix))
(new-menu (ui-update matrix menu-alist)))
(ui-draw matrix last-matrix)
(sleep .02) (sleep .02)
(ui-loop matrix new-menu))) (menu-loop-draw matrix menu-alist)
(menu-loop-update menu-alist))
(defun ui-draw (matrix last-matrix) (defun menu-loop-draw (matrix menu-alist)
"The draw loop for menus." "Drawing for."
(print-screen-matrix (matrix-delta last-matrix matrix)) (render-menu-strip matrix menu-alist 0 0))
(finish-output))
(defun ui-update (matrix menu-alist) (defun menu-loop-update (menu-alist)
"The update loop for menus. It processes all input, state, etc, and "The update loop for menus. It processes all input, state, etc, and
returns the new state of the menu." returns the new state of the menu."
(render-menu-strip matrix menu-alist 0 0)
(progress-menu-items menu-alist) (progress-menu-items menu-alist)
(process-menu-input menu-alist) (process-menu-input menu-alist))
menu-alist)
@ -171,15 +166,18 @@ That is, 0 for non-selected items and 100 for selected items."
(defun process-menu-input (menu-alist) (defun process-menu-input (menu-alist)
"Get and process any keyboard input, modifying the menu alist as necessary." "Get and process any keyboard input, modifying the menu alist as necessary."
(when (listen) (if (listen)
(let* ((input (normalize-char-plist (read-char-plist))) (let* ((input (normalize-char-plist (read-char-plist)))
(selected-item (nth (selected-menu-item-position menu-alist) (selected-item (nth (selected-menu-item-position menu-alist)
menu-alist))) menu-alist))
(func (cdr (assoc 'function selected-item))))
(case (getf input :char) (case (getf input :char)
(#\→ (select-right-menu-item menu-alist)) (#\→ (select-right-menu-item menu-alist))
(#\← (select-left-menu-item menu-alist))) (#\← (select-left-menu-item menu-alist)))
(if (eq (getf input :char) #\return) (if (and func (eq (getf input :char) #\return))
(ignore-errors (apply (cdr (assoc 'function selected-item)) '())))))) (apply func '())
't))
't))
(defun select-menu-item (menu-alist position) (defun select-menu-item (menu-alist position)