Hotswapping
This commit is contained in:
parent
2f4fbad405
commit
c30480520f
@ -55,7 +55,8 @@ element.__index = element
|
||||
setmetatable(element,{
|
||||
__call = function(cls, ...)
|
||||
local self
|
||||
if type(...)=='function' then
|
||||
local func, loader = ...
|
||||
if type(func)=='function' then
|
||||
self = setmetatable({}, element)
|
||||
self.renderer = ...
|
||||
self.classless = true
|
||||
@ -64,7 +65,14 @@ setmetatable(element,{
|
||||
self.classless = false
|
||||
end
|
||||
|
||||
self:new(...)
|
||||
if loader then
|
||||
local function f(newFunc)
|
||||
self:reLoader(newFunc)
|
||||
end
|
||||
loader(f)
|
||||
end
|
||||
|
||||
self:new()
|
||||
|
||||
return self
|
||||
end
|
||||
@ -77,6 +85,7 @@ function element:updater() end
|
||||
|
||||
function element:constructor() end
|
||||
|
||||
|
||||
--Control functions
|
||||
--The new function that should be used for element creation
|
||||
function element:new()
|
||||
@ -109,6 +118,12 @@ function element:new()
|
||||
end
|
||||
end
|
||||
|
||||
--Hotswapping code
|
||||
function element:reLoader(newFunc)
|
||||
self.renderer = newFunc
|
||||
self.context:bubbleUpdate()
|
||||
end
|
||||
|
||||
--Called once dimensions are validated
|
||||
function element:setup()
|
||||
self.state =
|
||||
@ -156,13 +171,12 @@ function element:setup()
|
||||
--Classless rendering
|
||||
if self.classless then
|
||||
self.classlessData.loadEffect = function (func)
|
||||
if self.classlessData.loadCaptured then
|
||||
return unpack(self.classlessData.loadCaptured)
|
||||
else
|
||||
if self.classlessData.loaded and self.classlessData.loadCaptured then
|
||||
return self.classlessData.loadCaptured
|
||||
elseif not self.classlessData.loaded then
|
||||
self.classlessData.loadCaptured = func()
|
||||
if type(self.classlessData.loadCaptured) == 'table' then
|
||||
return unpack(self.classlessData.loadCaptured)
|
||||
elseif self.classlessData.loadCaptured then
|
||||
self.classlessData.loaded = true
|
||||
if self.classlessData.loadCaptured then
|
||||
return self.classlessData.loadCaptured
|
||||
end
|
||||
end
|
||||
@ -184,7 +198,11 @@ function element:setup()
|
||||
self.classlessState[indice].state = set
|
||||
self.context:bubbleUpdate()
|
||||
end
|
||||
return self.classlessState[indice].state, self.classlessState[indice].setState
|
||||
|
||||
self.classlessState[indice].getState = function()
|
||||
return self.classlessState[indice].state
|
||||
end
|
||||
return self.classlessState[indice].state, self.classlessState[indice].setState, self.classlessState[indice].getState
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -193,15 +211,28 @@ end
|
||||
function element:classlessRender()
|
||||
self.inputContext:set()
|
||||
self.settings.indice = 0
|
||||
if type(self.renderer)=='function' then
|
||||
local denv = getfenv(self.renderer)
|
||||
denv['useState'] = self.classlessData.useState
|
||||
denv['loadEffect'] = self.classlessData.loadEffect
|
||||
|
||||
local denv = getfenv(self.renderer)
|
||||
denv['useState'] = self.classlessData.useState
|
||||
denv['loadEffect'] = self.classlessData.loadEffect
|
||||
local status,err = pcall(self.renderer,self.parameters, self.view.w, self.view.h)
|
||||
|
||||
self.renderer(self.parameters, self.view.w, self.view.h)
|
||||
if not status then
|
||||
love.graphics.setColor(1,0,0)
|
||||
love.graphics.rectangle('line',0,0,self.view.w,self.view.h)
|
||||
love.graphics.setColor(1,1,1)
|
||||
love.graphics.printf("Error: "..err,0,0,self.view.w)
|
||||
end
|
||||
|
||||
denv['useState'] = nil
|
||||
denv['loadEffect'] = nil
|
||||
denv['useState'] = nil
|
||||
denv['loadEffect'] = nil
|
||||
elseif type(self.renderer)=='string' then
|
||||
love.graphics.setColor(1,0,0)
|
||||
love.graphics.rectangle('line',0,0,self.view.w,self.view.h)
|
||||
love.graphics.setColor(1,1,1)
|
||||
love.graphics.printf("Error: "..self.renderer,0,0,self.view.w)
|
||||
end
|
||||
self.inputContext:unset()
|
||||
end
|
||||
|
||||
|
||||
106
debugLoader.lua
Normal file
106
debugLoader.lua
Normal file
@ -0,0 +1,106 @@
|
||||
|
||||
local path = string.sub(..., 1, string.len(...) - string.len(".debugLoader"))
|
||||
local helium = require(path..'.dummy')
|
||||
local elements = {}
|
||||
local debugLoader = {}
|
||||
--Return level: 1--string; 2--chunk; 3--return value; default: element factory
|
||||
local function loader(path)
|
||||
local succ = true
|
||||
|
||||
--File string
|
||||
local fileContents, err = love.filesystem.read(path)
|
||||
|
||||
if fileContents==nil then
|
||||
print('Error loading ',path,':',tostring(err),', will continue watching!')
|
||||
succ = false
|
||||
end
|
||||
|
||||
local t, lastLoaded
|
||||
if succ then
|
||||
t = love.filesystem.getInfo(path)
|
||||
lastLoaded = t['modtime']
|
||||
end
|
||||
|
||||
--Chunk
|
||||
local status, err
|
||||
if succ then
|
||||
status, err = pcall(loadstring,fileContents)
|
||||
end
|
||||
|
||||
if status==false or status==nil then
|
||||
print('Error compiling ',path,':',tostring(err),', will continue watching!')
|
||||
succ = false
|
||||
end
|
||||
|
||||
--Return values
|
||||
local ret
|
||||
if succ then
|
||||
succ, ret = pcall(err,path)
|
||||
if not succ then
|
||||
print('Error calling ',path,':',tostring(ret))
|
||||
end
|
||||
end
|
||||
|
||||
return fileContents, err, ret, lastLoaded
|
||||
end
|
||||
|
||||
debugLoader.loader = function(path,returnLevel)
|
||||
local level = returnLevel or 6
|
||||
if elements[path] then
|
||||
return elements[path][level]
|
||||
end
|
||||
|
||||
local setfuncs = {}
|
||||
|
||||
local fileContents, func, ret, lastLoaded = loader(path)
|
||||
local reloader = function(setFunc)
|
||||
setfuncs[#setfuncs+1] = setFunc
|
||||
end
|
||||
|
||||
local factory = function()
|
||||
return helium.element(ret, reloader)
|
||||
end
|
||||
|
||||
elements[path] = { fileContents, func, ret, path, lastLoaded, factory, setfuncs = setfuncs }
|
||||
return elements[path][level]
|
||||
end
|
||||
|
||||
local counter = 0
|
||||
function debugLoader.update(dt)
|
||||
counter = counter+dt
|
||||
if counter>2 then
|
||||
for ind, elem in pairs(elements) do
|
||||
--Get the current last save time
|
||||
local t = love.filesystem.getInfo(elem[4])
|
||||
local ll = t['modtime']
|
||||
if ll ~= elem[5] then
|
||||
--If last save time differs then start reload sequence
|
||||
local _, _, ret, lastLoaded = loader(elem[4])
|
||||
|
||||
|
||||
local setfuncs = {}
|
||||
|
||||
local reloader = function(setFunc)
|
||||
setfuncs[#setfuncs+1] = setFunc
|
||||
end
|
||||
|
||||
local factory = function()
|
||||
return helium.element(ret, reloader)
|
||||
end
|
||||
|
||||
elem[5] = lastLoaded
|
||||
|
||||
elem[6] = factory
|
||||
|
||||
for i, func in ipairs(elem.setfuncs) do
|
||||
func(ret)
|
||||
end
|
||||
end
|
||||
end
|
||||
counter = 0
|
||||
end
|
||||
end
|
||||
|
||||
HeliumLoader = debugLoader.loader
|
||||
|
||||
return debugLoader
|
||||
4
init.lua
4
init.lua
@ -8,6 +8,7 @@ local helium = require(path..".dummy")
|
||||
helium.utils = require(path..".utils")
|
||||
helium.element = require(path..".core.element")
|
||||
helium.input = require(path..".core.input")
|
||||
helium.debugLoader = require(path..".debugLoader")
|
||||
helium.elementBuffer = {}
|
||||
|
||||
function helium.render()
|
||||
@ -99,7 +100,8 @@ function love.run()
|
||||
|
||||
-- Call update and draw
|
||||
if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
|
||||
helium.update()
|
||||
helium.update(dt)
|
||||
helium.debugLoader.update(dt)
|
||||
|
||||
if love.graphics and love.graphics.isActive() then
|
||||
love.graphics.clear(love.graphics.getBackgroundColor())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user