mirror of
https://github.com/TangentFoxy/lurker.git
synced 2025-07-27 18:42:18 +00:00
Added protected mode
This commit is contained in:
@@ -45,6 +45,14 @@ hotswap occurs and is passed the name of the file which was swapped.
|
||||
lurker.postswap = function(f) print("File " .. f .. " was swapped") end
|
||||
```
|
||||
|
||||
### lurker.protected
|
||||
Dictates whether lurker should run in protected mode; this is `true` by
|
||||
default. If protected mode is disabled then LÖVE's usual error screen is used
|
||||
when an error occurs in a LÖVE callback function; if it is enabled then
|
||||
lurker's error state (which continues watching for file changes and can resume
|
||||
execution) is used. Changes to this variable should be made before any calls to
|
||||
lurker.update() are made.
|
||||
|
||||
### lurker.interval
|
||||
The interval in seconds for how often the scan of the directory is performed.
|
||||
This is `.5` by default.
|
||||
|
100
lurker.lua
100
lurker.lua
@@ -17,6 +17,10 @@ local isdir = love.filesystem.isDirectory
|
||||
local time = love.timer.getTime or os.time
|
||||
local lastmodified = love.filesystem.getLastModified
|
||||
|
||||
local lovecallbacknames = { "update", "load", "draw", "mousepressed",
|
||||
"mousereleased", "keypressed", "keyreleased",
|
||||
"focus", "quit" }
|
||||
|
||||
|
||||
function lurker.init()
|
||||
lurker.print("Initing lurker")
|
||||
@@ -24,8 +28,12 @@ function lurker.init()
|
||||
lurker.preswap = function() end
|
||||
lurker.postswap = function() end
|
||||
lurker.interval = .5
|
||||
lurker.protected = true
|
||||
lurker.last = 0
|
||||
lurker.files = {}
|
||||
lurker.funcwrappers = {}
|
||||
lurker.lovefuncs = {}
|
||||
lurker.state = "init"
|
||||
lume.each(lurker.getchanged(), lurker.resetfile)
|
||||
return lurker
|
||||
end
|
||||
@@ -53,7 +61,85 @@ function lurker.listdir(path, recursive, skipdotfiles)
|
||||
end
|
||||
|
||||
|
||||
function lurker.initwrappers()
|
||||
for _, v in pairs(lovecallbacknames) do
|
||||
lurker.funcwrappers[v] = function(...)
|
||||
args = {...}
|
||||
xpcall(function()
|
||||
return lurker.lovefuncs[v] and lurker.lovefuncs[v](unpack(args))
|
||||
end, lurker.onerror)
|
||||
end
|
||||
lurker.lovefuncs[v] = love[v]
|
||||
end
|
||||
lurker.updatewrappers()
|
||||
end
|
||||
|
||||
|
||||
function lurker.updatewrappers()
|
||||
for _, v in pairs(lovecallbacknames) do
|
||||
if love[v] ~= lurker.funcwrappers[v] then
|
||||
lurker.lovefuncs[v] = love[v]
|
||||
love[v] = lurker.funcwrappers[v]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function lurker.onerror(e)
|
||||
lurker.print("An error occurred; switching to error state")
|
||||
lurker.state = "error"
|
||||
for _, v in pairs(lovecallbacknames) do
|
||||
love[v] = function() end
|
||||
end
|
||||
love.update = lurker.update
|
||||
|
||||
local stacktrace = debug.traceback():gsub("\t", "")
|
||||
local msg = lume.format("{1}\n\n{2}", {e, stacktrace})
|
||||
local colors = { 0xFF1E1E2C, 0xFFF0A3A3, 0xFF92B5B0, 0xFF66666A, 0xFFCDCDCD }
|
||||
love.graphics.reset()
|
||||
love.graphics.setFont(love.graphics.newFont(12))
|
||||
|
||||
love.draw = function()
|
||||
local pad = 25
|
||||
local width = love.graphics.getWidth()
|
||||
local function drawhr(pos, color1, color2)
|
||||
local animpos = lume.smooth(pad, width - pad - 8, lume.pingpong(time()))
|
||||
if color1 then love.graphics.setColor(lume.rgba(color1)) end
|
||||
love.graphics.rectangle("fill", pad, pos, width - pad*2, 1)
|
||||
if color2 then love.graphics.setColor(lume.rgba(color2)) end
|
||||
love.graphics.rectangle("fill", animpos, pos, 8, 1)
|
||||
end
|
||||
local function drawtext(str, x, y, color)
|
||||
love.graphics.setColor(lume.rgba(color))
|
||||
love.graphics.print(str, x, y)
|
||||
end
|
||||
love.graphics.setBackgroundColor(lume.rgba(colors[1]))
|
||||
love.graphics.clear()
|
||||
drawtext("An error has occurred", pad, pad, colors[2])
|
||||
drawtext("lurker", width - love.graphics.getFont():getWidth("lurker") -
|
||||
pad, pad, colors[4])
|
||||
drawhr(pad + 32, colors[4], colors[5])
|
||||
drawtext("If you fix the problem and update the file the program will " ..
|
||||
"resume", pad, pad + 46, colors[3])
|
||||
drawhr(pad + 72, colors[4], colors[5])
|
||||
drawtext(msg, pad, pad + 90, colors[5])
|
||||
love.graphics.reset()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function lurker.onfirstframe()
|
||||
if lurker.protected then
|
||||
lurker.initwrappers()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function lurker.update()
|
||||
if lurker.state == "init" then
|
||||
lurker.onfirstframe()
|
||||
lurker.state = "normal"
|
||||
end
|
||||
local diff = time() - lurker.last
|
||||
if diff > lurker.interval then
|
||||
lurker.last = lurker.last + diff
|
||||
@@ -80,9 +166,20 @@ function lurker.resetfile(f)
|
||||
end
|
||||
|
||||
|
||||
function lurker.exiterrorstate()
|
||||
lurker.state = "normal"
|
||||
for _, v in pairs(lovecallbacknames) do
|
||||
love[v] = lurker.funcwrappers[v]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function lurker.scan()
|
||||
for _, f in pairs(lurker.getchanged()) do
|
||||
lurker.print("Hotswapping '{f}'...", {f = f})
|
||||
if lurker.state == "error" then
|
||||
lurker.exiterrorstate()
|
||||
end
|
||||
lurker.preswap(f)
|
||||
local modname = lurker.modname(f)
|
||||
local t, ok, err = lume.time(lume.hotswap, modname)
|
||||
@@ -93,6 +190,9 @@ function lurker.scan()
|
||||
end
|
||||
lurker.resetfile(f)
|
||||
lurker.postswap(f)
|
||||
if lurker.protected then
|
||||
lurker.updatewrappers()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Reference in New Issue
Block a user