User can create new category on the CLI
This commit is contained in:
parent
10d7a20a79
commit
a76bfbf944
@ -24,12 +24,16 @@
|
|||||||
(if start
|
(if start
|
||||||
(floor (* 100 (local-time:timestamp-difference end start))))))
|
(floor (* 100 (local-time:timestamp-difference end start))))))
|
||||||
|
|
||||||
(defun format-elapsed-time (run-split)
|
(defun run-split-format-elapsed-time (run-split)
|
||||||
(let ((elapsed (run-split-elapsed-time run-split)))
|
(let ((elapsed (run-split-elapsed-time run-split)))
|
||||||
(if elapsed
|
(if elapsed
|
||||||
(format-time (make-time-alist elapsed))
|
(format-time (make-time-alist elapsed))
|
||||||
"-")))
|
"-")))
|
||||||
|
|
||||||
|
;;(defun best-split (category-split)
|
||||||
|
;; (mito:select-dao 'run-split
|
||||||
|
;; (sxql:order-by (:- V
|
||||||
|
|
||||||
;; Returns stuff like PB, best of each split, etc.
|
;; Returns stuff like PB, best of each split, etc.
|
||||||
(defun run-statistics (category)
|
(defun run-statistics (category)
|
||||||
`((asdf . 1)))
|
`((asdf . 1)))
|
||||||
|
47
lispruns.asd
47
lispruns.asd
@ -1,25 +1,24 @@
|
|||||||
(asdf:defsystem "lispruns"
|
(asdf:defsystem "lispruns"
|
||||||
:description "A speedrun timer using n-curses written in lisp"
|
:description "A speedrun timer using n-curses written in lisp"
|
||||||
:version "0.1"
|
:version "0.1"
|
||||||
:author "Simponic"
|
:author "Simponic"
|
||||||
:depends-on (:unix-opts
|
:depends-on (:mito
|
||||||
:mito
|
:sxql
|
||||||
:sxql
|
:cl-ppcre
|
||||||
:cl-ppcre
|
:croatoan
|
||||||
:croatoan
|
:local-time)
|
||||||
:local-time)
|
:components ((:file "util") ;; Miscellaneous helpers
|
||||||
:components ((:file "util") ;; Miscellaneous helpers
|
(:file "config") ;; For importing category configuration files
|
||||||
(:file "config") ;; For importing category configuration files
|
(:file "digits") ;; Lisp file with cool ascii digits
|
||||||
(:file "digits") ;; Lisp file with cool ascii digits
|
(:file "text" :depends-on ("digits")) ;; Helper functions for performing figlet-like actions and such
|
||||||
(:file "text" :depends-on ("digits")) ;; Helper functions for performing figlet-like actions and such
|
(:file "time") ;; Custom time forms
|
||||||
(:file "time") ;; Custom time forms
|
(:file "ui" :depends-on ("util" "text" "time")) ;; Functions to draw the UI
|
||||||
(:file "ui" :depends-on ("util" "text" "time")) ;; Functions to draw the UI
|
(:file "speedrun" :depends-on ("util")) ;; The actual timer logic
|
||||||
(:file "speedrun" :depends-on ("util")) ;; The actual timer logic
|
(:file "database/category") ;; Category DAO
|
||||||
(:file "database/category") ;; Category DAO
|
(:file "database/run") ;; Run DAO
|
||||||
(:file "database/run") ;; Run DAO
|
(:file "main" :depends-on ("database/category"
|
||||||
(:file "main" :depends-on ("database/category"
|
"database/run"
|
||||||
"database/run"
|
"util"
|
||||||
"util"
|
"config"
|
||||||
"config"
|
"ui"
|
||||||
"ui"
|
"speedrun"))))
|
||||||
"speedrun"))))
|
|
||||||
|
46
main.lisp
46
main.lisp
@ -20,7 +20,7 @@
|
|||||||
(if (ignore-errors (funcall validator input))
|
(if (ignore-errors (funcall validator input))
|
||||||
input
|
input
|
||||||
(progn
|
(progn
|
||||||
(format t "E: Invalid input. Try again.")
|
(format t "E: Invalid input. Try again.~%")
|
||||||
(get-input prompt validator)))))
|
(get-input prompt validator)))))
|
||||||
|
|
||||||
;; Options is an alist with the prompt string as the car and the value as the cdr
|
;; Options is an alist with the prompt string as the car and the value as the cdr
|
||||||
@ -53,6 +53,29 @@
|
|||||||
(progn (format t "E: Could not find option that matched query.~%")
|
(progn (format t "E: Could not find option that matched query.~%")
|
||||||
(select-option options)))))))
|
(select-option options)))))))
|
||||||
|
|
||||||
|
(defun user-create-new-category ()
|
||||||
|
(let* ((name (get-input "Category Name (e.g. \"SM64\"): " 'empty-p))
|
||||||
|
(percentage (get-input "Percentage (e.g. \"16 Star\"): " 'empty-p))
|
||||||
|
(category (mito:insert-dao (make-instance 'category :name name :percentage percentage)))
|
||||||
|
(splits (do ((spliti 1 (1+ spliti))
|
||||||
|
(inputs '() (push (get-input (format nil "Split Name [~a]~a: " spliti (if (<= spliti 1) " (blank when done adding)" ""))) inputs)))
|
||||||
|
((equal (car inputs) "")
|
||||||
|
(mapcar (lambda
|
||||||
|
(category-split-name)
|
||||||
|
(mito:insert-dao
|
||||||
|
(make-instance 'category-split
|
||||||
|
:name category-split-name
|
||||||
|
:category category)))
|
||||||
|
(reverse (cdr inputs)))))))))
|
||||||
|
|
||||||
|
(defun with-selected-category (f)
|
||||||
|
(let* ((categories (mito:select-dao 'category))
|
||||||
|
(category-alist (mapcar (lambda (category) `(,(format nil "~a - ~a" (category-name category) (category-percentage category)) . ,category)) categories)))
|
||||||
|
(if categories
|
||||||
|
(funcall f (select-option category-alist))
|
||||||
|
(format t "E: There are no categories. Try creating one or importing one"))))
|
||||||
|
|
||||||
|
|
||||||
(defun main ()
|
(defun main ()
|
||||||
(let ((choice (select-option '(("Help" . HELP)
|
(let ((choice (select-option '(("Help" . HELP)
|
||||||
("Import a category" . IMPORT-CATEGORY)
|
("Import a category" . IMPORT-CATEGORY)
|
||||||
@ -62,6 +85,7 @@
|
|||||||
("Exit" . EXIT)))))
|
("Exit" . EXIT)))))
|
||||||
(case choice
|
(case choice
|
||||||
('HELP
|
('HELP
|
||||||
|
(format t "~%")
|
||||||
(mapcar #'(lambda (x) (format t "~a~%" x)) *lispruns-logo*))
|
(mapcar #'(lambda (x) (format t "~a~%" x)) *lispruns-logo*))
|
||||||
('IMPORT-CATEGORY
|
('IMPORT-CATEGORY
|
||||||
(import-category (get-input
|
(import-category (get-input
|
||||||
@ -69,25 +93,9 @@
|
|||||||
(uiop/os:getcwd))
|
(uiop/os:getcwd))
|
||||||
'probe-file)))
|
'probe-file)))
|
||||||
('NEW-CATEGORY
|
('NEW-CATEGORY
|
||||||
(let* ((name (get-input "Category Name (e.g. \"SM64\"): " 'not-empty-string))
|
(user-create-new-category))
|
||||||
(percentage (get-input "Percentage (e.g. \"16 Star\"): " 'not-empty-string))
|
|
||||||
(category (mito:insert-dao (make-instance 'category :name name :percentage percentage)))
|
|
||||||
(splits (do ((spliti 1 (1+ spliti))
|
|
||||||
(inputs '() (push (get-input (format nil "Split [~a]: " spliti)) inputs)))
|
|
||||||
((equal (car inputs) "")
|
|
||||||
(mapcar (lambda
|
|
||||||
(category-split-name)
|
|
||||||
(mito:insert-dao
|
|
||||||
(make-instance 'category-split
|
|
||||||
:name category-split-name
|
|
||||||
:category category)))
|
|
||||||
(reverse (cdr inputs)))))))))
|
|
||||||
('START-SPEEDRUN
|
('START-SPEEDRUN
|
||||||
(let* ((categories (mito:select-dao 'category))
|
(with-selected-category 'speedrun-ui))
|
||||||
(category-alist (mapcar (lambda (category) `(,(format nil "~a - ~a" (category-name category) (category-percentage category)) . ,category)) categories)))
|
|
||||||
(if categories
|
|
||||||
(speedrun-ui (select-option category-alist))
|
|
||||||
(format t "E: There are no categories. Try creating one or importing one"))))
|
|
||||||
('EXIT
|
('EXIT
|
||||||
(quit))))
|
(quit))))
|
||||||
(format t "~%")
|
(format t "~%")
|
||||||
|
24
ui.lisp
24
ui.lisp
@ -18,6 +18,12 @@
|
|||||||
(inc yi))
|
(inc yi))
|
||||||
slices)))
|
slices)))
|
||||||
|
|
||||||
|
;; Formats a category split and a run split for the splits window
|
||||||
|
(defun make-split-line (csplit speedrun-split)
|
||||||
|
`((,(category-split-name csplit) . ,(/ 4 12))
|
||||||
|
("" . ,(/ 1 12))
|
||||||
|
(,(run-split-format-elapsed-time speedrun-split) . ,(/ 3 12))))
|
||||||
|
|
||||||
;; Creates a window with the total time and statistics
|
;; Creates a window with the total time and statistics
|
||||||
(defun timer-window (speedrun pos width height)
|
(defun timer-window (speedrun pos width height)
|
||||||
(let* ((timerglet (lispglet (format-time (make-time-alist (speedrun-elapsed speedrun)))))
|
(let* ((timerglet (lispglet (format-time (make-time-alist (speedrun-elapsed speedrun)))))
|
||||||
@ -82,6 +88,7 @@
|
|||||||
(subseq elements (car elements-to-draw-subseq) (cadr elements-to-draw-subseq))))
|
(subseq elements (car elements-to-draw-subseq) (cadr elements-to-draw-subseq))))
|
||||||
highlight-menu))
|
highlight-menu))
|
||||||
|
|
||||||
|
;; The big bad monolithic UI loop
|
||||||
(defun speedrun-ui (category)
|
(defun speedrun-ui (category)
|
||||||
(croatoan:with-screen (scr :input-blocking nil :input-echoing nil :cursor-visible nil :enable-colors t :input-buffering nil :input-blocking nil)
|
(croatoan:with-screen (scr :input-blocking nil :input-echoing nil :cursor-visible nil :enable-colors t :input-buffering nil :input-blocking nil)
|
||||||
(setf (croatoan:background scr) (make-instance 'croatoan:complex-char :color-pair (cdr (assoc 'main *colors*))))
|
(setf (croatoan:background scr) (make-instance 'croatoan:complex-char :color-pair (cdr (assoc 'main *colors*))))
|
||||||
@ -90,7 +97,9 @@
|
|||||||
(state 'TITLE)
|
(state 'TITLE)
|
||||||
(redraws '(title-instance))
|
(redraws '(title-instance))
|
||||||
(speedrun (make-speedrun category))
|
(speedrun (make-speedrun category))
|
||||||
(csplits (category-splits category)))
|
(csplits (category-splits category))
|
||||||
|
;; TODO
|
||||||
|
(pbs ()))
|
||||||
(flet ((render ()
|
(flet ((render ()
|
||||||
(case state
|
(case state
|
||||||
('TITLE
|
('TITLE
|
||||||
@ -124,16 +133,8 @@
|
|||||||
:current-element-index (speedrun-current-split-index speedrun)
|
:current-element-index (speedrun-current-split-index speedrun)
|
||||||
:height splits-height
|
:height splits-height
|
||||||
:width max-width
|
:width max-width
|
||||||
:elements (mapcar (lambda (csplit speedrun-split)
|
;; Todo: add personal bests to elements
|
||||||
`(
|
:elements (mapcar 'make-split-line csplits (speedrun-splits speedrun))))
|
||||||
(,(category-split-name csplit) . ,(/ 4 12))
|
|
||||||
("" . ,(/ 1 12))
|
|
||||||
(,(format-elapsed-time speedrun-split) . ,(/ 3 12))
|
|
||||||
))
|
|
||||||
csplits
|
|
||||||
(speedrun-splits speedrun))))
|
|
||||||
;; :elements (mapcar #'category-split-name csplits)))
|
|
||||||
;; :elements `((("FIRST SPLIT IS EPIC" . ,(/ 4 12)) ("" . ,(/ 1 12)) ("10:10:00.22" . ,(/ 3 12)) ("" . ,(/ 1 12)) ("20:00.00" . ,(/ 3 12))))))
|
|
||||||
(splits-instance (highlight-list-window split-list `(0 ,centered-x)))
|
(splits-instance (highlight-list-window split-list `(0 ,centered-x)))
|
||||||
(timer-instance (timer-window speedrun `(,splits-height ,centered-x) max-width timer-height)))
|
(timer-instance (timer-window speedrun `(,splits-height ,centered-x) max-width timer-height)))
|
||||||
(croatoan:refresh splits-instance)
|
(croatoan:refresh splits-instance)
|
||||||
@ -143,6 +144,7 @@
|
|||||||
(if (zerop (mod frame 30))
|
(if (zerop (mod frame 30))
|
||||||
(inc scroll))
|
(inc scroll))
|
||||||
(sleep (/ 1 60))))
|
(sleep (/ 1 60))))
|
||||||
|
|
||||||
(croatoan:event-case (scr event)
|
(croatoan:event-case (scr event)
|
||||||
(#\q (return-from croatoan:event-case))
|
(#\q (return-from croatoan:event-case))
|
||||||
(#\space
|
(#\space
|
||||||
|
@ -10,5 +10,5 @@
|
|||||||
(defun max-length (lists)
|
(defun max-length (lists)
|
||||||
(reduce (lambda (a x) (max a x)) (mapcar #'length lists)))
|
(reduce (lambda (a x) (max a x)) (mapcar #'length lists)))
|
||||||
|
|
||||||
(defun not-empty-string (str)
|
(defun empty-p (s)
|
||||||
(not (zerop (length str))))
|
(not (zerop (length s))))
|
||||||
|
Loading…
Reference in New Issue
Block a user