local NodeManager = class('NodeManager', { state = 'running', stateTime = 0, currentNode = nil, }) function NodeManager:init(config) self.config = config self.nodes = {} self.nodeConfs = {} self.currentNode = nil print('Initializing NodeManager') end function NodeManager:load() self:configChanged() end function NodeManager:resize(w, h) self.secondaryCanvas = love.graphics.newCanvas(w, h) end function NodeManager:configChanged() local cnt = {} local newNodes = {} local newNodeConfs = {} for _, c_ in ipairs(self.config.nodes) do local nodeConfig = lume.clone(c_) local hash = inspect(nodeConfig) if cnt[hash] == nil then cnt[hash] = 0 end cnt[hash] = cnt[hash] + 1 hash = hash .. '-' .. tostring(cnt[hash]) local nodeName = nodeConfig[1] table.remove(nodeConfig, 1) if self.nodeConfs[hash] then print('Using existing node:', self.nodeConfs[hash], hash) newNodes[#newNodes + 1] = self.nodeConfs[hash] else print('Creating new node.', nodeName, inspect(nodeConfig)) local status, err = pcall(function() newNodes[#newNodes + 1] = require(nodeName)(nodeConfig) end) if err then print("Error occured while loading", nodeName, err) return end end newNodeConfs[hash] = newNodes[#newNodes] end self.nodes = newNodes self.nodeConfs = newNodeConfs end function NodeManager:render() if not self.currentNode then self.currentNode = self.nodes[1] end if not self.currentNode then return end -- love.graphics.print('state: ' .. self.state .. '; counter: ' .. tostring(self.stateTime), 50, 50) self.currentNode:render() if self.state == 'transitioning' and self.currentNode ~= self.nextNode and self.nextNode then self.secondaryCanvas:renderTo(function() self.nextNode:render() end) love.graphics.setColor(1.0, 1.0, 1.0, 1.0 * (self.stateTime / self.config.transitionTime)) love.graphics.draw(self.secondaryCanvas, 0, 0) end love.graphics.setColor(1.0, 1.0, 1.0, 0.3) if self.config.showProgress and self.state == 'running' then local stateTime stateTime = self.currentNode.displayTime or self.config.displayTime local h = 5 love.graphics.rectangle("fill", 0, love.graphics.getHeight() - h, (self.stateTime / stateTime) * love.graphics.getWidth(), h) end end function NodeManager:update(dt) if not self.currentNode then self.currentNode = self.nodes[1] end if not self.currentNode then return end self.stateTime = self.stateTime + dt if self.state == 'transitioning' and self.stateTime >= self.config.transitionTime then self.stateTime = 0 self.state = 'running' self.currentNode:afterExit() -- self.currentNode, self.nextNode = self.nextNode, self.nodes[(lume.find(self.nodes, self.nextNode) or 1) % #self.nodes + 1] self.currentNode = self.nextNode self.currentNode:afterEnter() elseif self.state == 'running' and self.stateTime >= (self.currentNode.displayTime or self.config.displayTime) then self.stateTime = 0 self.state = 'transitioning' self.currentNode:beforeExit() self.nextNode = self.nodes[(lume.find(self.nodes, self.currentNode) or 1) % #self.nodes + 1] self.nextNode:beforeEnter() end self.currentNode:update(dt) if self.state == 'transitioning' and self.currentNode ~= self.nextNode and self.nextNode then self.nextNode:update(dt) end end return NodeManager