(local lume (require :lib.lume)) (local common (require :core.common)) (local style (require :core.style)) (local std-handlers love.handlers) (local modes {:name-to-mode {} :mode-index 1 :names [] : std-handlers}) (fn modes.cycle [self ?name] (set self.mode-index (if ?name (lume.find self.names ?name) (+ self.mode-index 1))) (when (or (not self.mode-index) (> self.mode-index (length self.names))) (set self.mode-index 1)) (self:switch (self:current))) (fn modes.current [self] (. self.name-to-mode (. self.names self.mode-index))) (fn add-mode-cycler [handlers] (fn mode-cycler [ev key ...] (when (and (= ev :keyreleased) (= key :f1)) (modes:cycle)) (when (rawget handlers :any) (handlers.any ev key ...))) (setmetatable {:any mode-cycler} {:__index handlers})) (fn modes.draw [mode] (xpcall mode.draw (fn [msg] (love.graphics.reset) (love.graphics.setColor 1 0 0 1) (love.graphics.setNewFont 14) (love.graphics.printf (.. msg "\n" (debug.traceback)) 20 20 (- (love.graphics.getWidth) 40))))) (fn modes.switch [self mode] (set love.handlers (add-mode-cycler (if mode.handler {:any mode.handler} std-handlers))) (set love.update mode.update) (set love.draw #(self.draw mode))) (fn modes.register [self name mode] (tset self.name-to-mode name mode) (when (not (lume.any self.names #(= $1 name))) (table.insert self.names name)) (when (= (length self.names) 1) (self:cycle))) modes