Added protected mode

This commit is contained in:
rxi
2014-03-07 20:20:18 +00:00
parent 01c744dc84
commit d948392aa6
2 changed files with 108 additions and 0 deletions

View File

@@ -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.

View File

@@ -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