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
;;;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;; FLORA-SEARCH-AURORA
;; A simple TUI-game made for the text-flavoured LibreJam of 2023-06!
;; See: https://jamgaroo.xyz/jams/2
;;;; FLORA-SEARCH-AURORA
;;;; A simple TUI-game made for the text-flavoured LibreJam of 2023-06!
;;;; See: https://jamgaroo.xyz/jams/2
(ql:quickload '(alexandria assoc-utils cl-charms cl-tiled str))
@ -32,18 +32,42 @@
(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 ()
"A pathetic fascimile of a main loop. Look, I'm still tinkering!"
(let ((matrix (make-screen-matrix))
(items `(((LABEL . "PLAY") (SELECTION . 100) (SELECTED . T))
((LABEL . "QUIT") (SELECTION . 100) (FUNCTION . ,(lambda () (print "AAAAAA"))))
((LABEL . "ESCAPE"))
((LABEL . "RUN AWAY") (SELECTION . -100)))))
(let* ((options-menu
`(((LABEL . "IDK") (SELECTION . 100) (SELECTED . T)
(FUNCTION . ,(lambda () (print "¯\_(ツ)_/¯"))))
((LABEL . "GO BACK") (FUNCTION . ,(lambda () nil)))))
(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:enable-raw-input :interpret-control-characters 't)
(clear-screen)
(print-screen-matrix matrix)
(ui-loop matrix items))))
(state-loop (list (lambda (matrix) (menu-loop matrix main-menu)))))))
;; (print-screen-matrix
; (render-menu-strip matrix items 2 5
;; :max-item-width 20 :height 3)))

34
ui.lisp
View File

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