fix broken hot reload pattern, handle exceptions in game updates

This commit is contained in:
Jeremy Penner 2021-03-30 19:24:52 -04:00
parent 4f96c63d00
commit fec30be7dd
9 changed files with 67 additions and 26 deletions

View file

@ -160,6 +160,8 @@
; handle key events
(when (focus view tag x y w h {:i 1 :iAnchor 1 :blink (love.timer.getTime)})
(local f view.imstate.focus)
(when (> f.i (+ (length text) 1)) (set f.i (+ (length text) 1)))
(when (> f.iAnchor (+ (length text) 1)) (set f.iAnchor (+ (length text) 1)))
(when view.imstate.text
(set textNew (replace-selection view textNew view.imstate.text)))
(each [_ key (ipairs (or view.imstate.keys []))]

View file

@ -3,11 +3,24 @@
(local style (require :core.style))
(local lume (require :lib.lume))
(local repl {})
(local repl (util.hot-table ...))
(fn repl.text-height [text ?font]
(let [font (or ?font style.font)
(_ newlines) (text:gsub "\n" "\n")]
(* (font:get_height) (+ newlines 1))))
(fn repl.inspect-table [tbl view x y-start w]
(var y y-start)
(var h 0)
(each [k v (pairs tbl)]
(let [kstr (fv k)
wk 1]
nil))
)
(fn repl.inspect [v view x y w]
(renderer.draw_text style.font (fv v) x y style.text)
(style.font:get_height))
(repl.text-height (fv v)))
(fn repl.inspector [{: vals} view x y]
(var h 0)
@ -20,7 +33,7 @@
(listener:append line)))
(fn repl.run [{: listeners}]
(local inspector (util.fn repl :inspector))
(local inspector #(repl.inspector $...))
(fennel.repl {:readChunk coroutine.yield
:onValues #(repl.notify listeners {:draw inspector :vals $1})
:onError (fn [errType err luaSource] (repl.notify listeners {:draw inspector :vals [err]}))
@ -39,11 +52,11 @@
(fn repl.new []
(local result
{:listeners []
:listen (util.fn repl :listen)
:unlisten (util.fn repl :unlisten)
:submit (util.fn repl :submit)
:listen #(repl.listen $...)
:unlisten #(repl.unlisten $...)
:submit #(repl.submit $...)
:coro (coroutine.create repl.run)})
(coroutine.resume result.coro result)
result)
repl
repl.hot

View file

@ -33,7 +33,7 @@
(local cmd (or ?cmd self.cmd))
(when (= ?cmd nil)
(set self.cmd ""))
(self:append {:draw (util.fn ReplView :draw-cmd) : cmd})
(self:append {:draw #(self.draw-cmd $...) : cmd})
(self.conn:submit cmd))
(fn ReplView.draw [self]

View file

@ -1,7 +1,8 @@
(local util (require :lib.util))
(local dim (require :game.dim))
(local Bomb {})
(local Bomb (util.hot-table ...))
(fn draw-ticking [bomb x y]
(love.graphics.setColor 0.4 0.4 0.4)
(love.graphics.circle :fill x y (/ dim.tilesize 2))
@ -39,9 +40,9 @@
:exploding (rules.clear-bomb bomb))))
(fn Bomb.new []
{:state :ticking :timer 3 :solid true :draw (util.fn Bomb :draw) :update (util.fn Bomb :update)})
{:state :ticking :timer 3 :solid true :draw #(Bomb.draw $...) :update #(Bomb.update $...)})
(fn Bomb.new-explosion []
{:state :exploding :timer 0.5 :deadly true :draw (util.fn Bomb :draw) :update (util.fn Bomb :update)})
{:state :exploding :timer 0.5 :deadly true :draw #(Bomb.draw $...) :update #(Bomb.update $...)})
Bomb
Bomb.hot

View file

@ -4,7 +4,7 @@
(local {: edge : vec*} (util.require :game.helpers))
(local map (require :game.tilemap))
(local bomberman {})
(local bomberman (util.hot-table ...))
(set bomberman.keymap {:up :w :down :s :left :a :right :d :bomb :x})
(fn bomberman.draw [entity]
@ -30,6 +30,6 @@
(rules.place-bomb (map.world-to-tile entity.pos))))
(fn bomberman.new [pos]
{: pos :vel [0 0] :draw (util.fn bomberman :draw) :update (util.fn bomberman :update)})
{: pos :vel [0 0] :draw #(bomberman.draw $...) :update #(bomberman.update $...)})
bomberman
bomberman.hot

View file

@ -2,15 +2,35 @@
(local map (require :game.tilemap))
(local rules (require :game.rules))
(fn update [dt]
(fn game-update [dt]
(map.update-entitymap state.bombs dt rules)
(each [_ entity (ipairs state.entities)]
(entity:update dt rules)))
(fn draw []
(fn exception-update [dt]
(when (love.keyboard.isDown :f2)
(set state.update-exception nil)))
(fn update [dt]
(if state.update-exception
(exception-update dt)
(xpcall #(game-update dt) (fn [msg]
(set state.update-exception (.. msg "\n" (debug.traceback)))))))
(fn game-draw []
(map.draw-tilemaps 0 0 [state.bombs state.map])
(each [_ entity (ipairs state.entities)]
(entity:draw)))
(fn exception-draw []
(love.graphics.setColor 1 0 0 1)
(love.graphics.setNewFont 14)
(love.graphics.printf (.. "Press F2 when resolved\n" state.update-exception) 20 20 (- (love.graphics.getWidth) 40)))
(fn draw []
(if state.update-exception
(exception-draw)
(game-draw)))
{: update : draw}

View file

@ -1,7 +1,7 @@
(local dim (require :game.dim))
(local util (require :lib.util))
(local tileset {})
(local tileset (util.hot-table ...))
(fn rect [x y color]
(love.graphics.setColor (table.unpack color))
(love.graphics.rectangle :fill
@ -35,7 +35,7 @@
:breakable true}
{:name :dot
:edible true}
] (util.fn tileset :bombertile-draw)))
] #(tileset.bombertile-draw $...)))
tileset
tileset.hot

View file

@ -53,6 +53,16 @@
(fn swappable-require [modname]
(swappable (require modname)))
(fn hot-table [modname]
(local tbl {})
(fn find-table []
(let [loaded-pkg (. package.loaded modname)]
(if (= (type loaded-pkg) :table) loaded-pkg) tbl))
(setmetatable {:hot tbl} {
:__index (fn [_ key] (. (find-table) key))
:__newindex (fn [_ key val] (tset (find-table) key val))
}))
(fn readjson [filename]
(local f (io.open filename :r))
(local text (f:read "*a"))
@ -91,6 +101,6 @@
{: int8-to-bytes : int16-to-bytes : int24-to-bytes : bytes-to-uint8 : bytes-to-uint16 : bytes-to-uint24
: splice : lo : hi
: reload : hotswap : swappable :require swappable-require :fn mk-swappable-fn
: reload : hotswap : swappable :require swappable-require : hot-table
: readjson : writejson : waitfor : in-coro : multival}

View file

@ -1,11 +1,6 @@
TODO:
* all usages of util.fn are wrong!! you can't use the table as locally defined as it will disappear!!! aargh
* tile editor (geometric shapes for now?)
DEBUG TOOLS:
#1 problem: update failing crashes the editor
- store exception and stop running game; patch and restart
Repl-y thing:
appends objects to a list (inspectable?)