2022-05-24 12:57:15 -04:00
|
|
|
(defclass speedrun ()
|
|
|
|
((state
|
|
|
|
;; RUNNING, STOPPED
|
|
|
|
:initarg :state
|
|
|
|
:accessor speedrun-state)
|
|
|
|
(title
|
|
|
|
:initarg :title
|
|
|
|
:accessor speedrun-title)
|
|
|
|
;; Whatever internal time units decided by SBCL (get-internal-real-time)
|
|
|
|
;; (local-time:now) *could* be used, but by my testing it's around 6 times slower
|
|
|
|
;; so why not
|
|
|
|
(start-timestamp
|
|
|
|
:initarg :start-timestamp
|
|
|
|
:accessor speedrun-start-timestamp)
|
|
|
|
(elapsed ;; milliseconds
|
|
|
|
:initarg :elapsed
|
|
|
|
:accessor speedrun-elapsed)
|
|
|
|
(splits
|
|
|
|
:initarg :splits
|
|
|
|
:accessor speedrun-splits)
|
|
|
|
(run-dao
|
|
|
|
:initarg :run-dao
|
|
|
|
:accessor speedrun-run-dao)
|
|
|
|
(current-split-index
|
|
|
|
:initarg :current-split-index
|
|
|
|
:accessor speedrun-current-split-index)))
|
|
|
|
|
|
|
|
(defun make-speedrun (category)
|
|
|
|
(let* ((run (make-instance 'run :category category))
|
|
|
|
(splits (mapcar (lambda (category-split)
|
|
|
|
(make-instance 'run-split :category-split category-split :run run))
|
|
|
|
(category-splits category))))
|
|
|
|
(make-instance 'speedrun
|
|
|
|
:state 'STOPPED
|
|
|
|
:title (category-name category)
|
|
|
|
:splits splits
|
|
|
|
:current-split-index 0
|
|
|
|
:elapsed 0.0
|
|
|
|
:run-dao run)))
|
|
|
|
|
|
|
|
(defun current-split (speedrun)
|
|
|
|
(nth (speedrun-current-split-index speedrun) (speedrun-splits speedrun)))
|
|
|
|
|
|
|
|
;; Updates the current total elapsed time of the speedrun if it's running
|
|
|
|
(defun update-time (speedrun)
|
|
|
|
(if (eq (speedrun-state speedrun) 'RUNNING)
|
2022-05-31 18:59:29 -04:00
|
|
|
(setf (speedrun-elapsed speedrun) (floor (* 100 (/ (- (get-internal-real-time) (speedrun-start-timestamp speedrun)) internal-time-units-per-second))))))
|
2022-05-24 12:57:15 -04:00
|
|
|
|
|
|
|
;; Initializes a speedrun to start running the timer
|
|
|
|
(defun start-speedrun (speedrun)
|
|
|
|
(setf (speedrun-state speedrun) 'RUNNING
|
|
|
|
(speedrun-start-timestamp speedrun) (get-internal-real-time)
|
|
|
|
(run-split-start-time (current-split speedrun)) (local-time:now)))
|
|
|
|
|
2022-05-31 01:45:29 -04:00
|
|
|
;; Saves the speedrun into the database
|
|
|
|
(defun save-speedrun (speedrun)
|
|
|
|
(mapcar #'mito:save-dao (cons (speedrun-run-dao speedrun) (speedrun-splits speedrun))))
|
|
|
|
|
2022-05-30 00:31:48 -04:00
|
|
|
;; Set the state of the speedrun to be stopped if there are no more splits.
|
|
|
|
;; Or, set the current split to the next one in the list.
|
2022-05-24 12:57:15 -04:00
|
|
|
(defun next-split (speedrun)
|
|
|
|
(let ((now (local-time:now)))
|
2022-05-31 01:45:29 -04:00
|
|
|
(unless (equal (speedrun-state speedrun) 'STOPPED)
|
|
|
|
(setf (run-split-end-time (current-split speedrun)) now)
|
|
|
|
(if (equal (speedrun-current-split-index speedrun) (1- (length (speedrun-splits speedrun))))
|
|
|
|
(progn
|
2022-05-31 18:59:29 -04:00
|
|
|
(setf
|
|
|
|
(speedrun-elapsed speedrun) (apply '+ (mapcar 'run-split-elapsed-time (speedrun-splits speedrun)))
|
|
|
|
(speedrun-state speedrun) 'STOPPED)
|
2022-05-31 01:45:29 -04:00
|
|
|
(save-speedrun speedrun))
|
|
|
|
(progn
|
|
|
|
(inc (speedrun-current-split-index speedrun))
|
|
|
|
(setf (run-split-start-time (current-split speedrun)) now))))))
|
2022-05-24 12:57:15 -04:00
|
|
|
|