melee-roguelite/wrap.fnl
Phil Hagelberg c257139d17 Wrap mode handlers in xpcall+error-mode.
When an error occurs in a mode handler, change to error-mode. Within
error-mode, display the traceback and allow the user to exit, (which
the default love error handler does) but also allows returning back to
the previous mode. The assumption is that this would be done after
using the repl to ,reload the module containing the bug which caused
the error.
2021-09-11 19:33:56 -07:00

45 lines
1.3 KiB
Fennel

(local fennel (require :lib.fennel))
(local repl (require :lib.stdio))
(local canvas (let [(w h) (love.window.getMode)]
(love.graphics.newCanvas w h)))
(var scale 1)
;; set the first mode
(var (mode mode-name) nil)
(fn set-mode [new-mode-name ...]
(set (mode mode-name) (values (require new-mode-name) new-mode-name))
(when mode.activate
(match (pcall mode.activate ...)
(false msg) (print mode-name "activate error" msg))))
(fn love.load []
(set-mode :mode-intro)
(canvas:setFilter "nearest" "nearest")
(repl.start))
(fn safely [f]
(xpcall f #(set-mode :error-mode mode-name $ (fennel.traceback))))
(fn love.draw []
;; the canvas allows you to get sharp pixel-art style scaling; if you
;; don't want that, just skip that and call mode.draw directly.
(love.graphics.setCanvas canvas)
(love.graphics.clear)
(love.graphics.setColor 1 1 1)
(safely mode.draw)
(love.graphics.setCanvas)
(love.graphics.setColor 1 1 1)
(love.graphics.draw canvas 0 0 0 scale scale))
(fn love.update [dt]
(when mode.update
(safely #(mode.update dt set-mode))))
(fn love.keypressed [key]
(if (and (love.keyboard.isDown "lctrl" "rctrl" "capslock") (= key "q"))
(love.event.quit)
;; add what each keypress should do in each mode
(safely #(mode.keypressed key set-mode))))