diff --git a/control/state.lua b/control/state.lua index a64dfed..25e5426 100644 --- a/control/state.lua +++ b/control/state.lua @@ -10,7 +10,6 @@ return function (base) return fakeBase[index] or base[index] end, __newindex = function(t, index, val) - print(index, val) if fakeBase[index] ~= val then fakeBase[index] = val activeContext:bubbleUpdate() diff --git a/core/atlas.lua b/core/atlas.lua index 0d4c617..2ddedef 100644 --- a/core/atlas.lua +++ b/core/atlas.lua @@ -1,40 +1,63 @@ local atlas = {} -local createdAtlas -local intermediaryCanvas +local atlases atlas.__index = atlas local BLOCK_SIZE = 5 function atlas.load() - if not createdAtlas then + if not atlases then atlas.init() end end -function atlas.getRatio() - return createdAtlas.taken_area/createdAtlas.ideal_area +function atlas.getRatio(index) + return atlases[index].taken_area/atlases[index].ideal_area end -function atlas.getFreeArea() - return createdAtlas.ideal_area - createdAtlas.taken_area +function atlas.getFreeArea(index) + return atlases[index].ideal_area - atlases[index].taken_area end local sw, sh = love.graphics.getDimensions() function atlas.init() - - createdAtlas = atlas.new(sw*2, sh) - intermediaryCanvas = love.graphics.newCanvas(sw, sh) - atlas.createdAtlas = createdAtlas - atlas.interCanvas = intermediaryCanvas + atlases = {} + atlases[1] = atlas.new(sw, sh) + atlases[2] = atlas.new(sw, sh) + atlas.atlases = atlases end +local selfRenderTime = false + +function atlas.setBench(time) + selfRenderTime = time +end + +local coefficient = 1.5 function atlas.assign(element) + local avg, sum, canvasID = 0, 0, element.context:getCanvasIndex(true) or 1 + + for i, e in ipairs(element.renderBench) do + sum = sum + e + end + + avg = sum/#element.renderBench + + local areaBelow = atlas.getFreeArea(canvasID) + local area = element.view.h*element.view.w + + local areaCoef = (2-(atlas.getRatio(canvasID)) )-(area/(areaBelow/(4+3*atlas.getRatio(canvasID)))) + local speedCoef = avg/selfRenderTime + + if not ((areaCoef+speedCoef)>coefficient) then + return + end + local elW = element.view.w local elH = element.view.h - local canvas, quad, interQuad = createdAtlas:assignElement(element) - if not canvas and createdAtlas.ideal_area < createdAtlas.taken_area*4 then + local canvas, quad, interQuad = atlases[canvasID]:assignElement(element) + if not canvas and atlases[canvasID].ideal_area < atlases[canvasID].taken_area*4 then --print('refragmenting ;3') - createdAtlas:refragment() - canvas, quad, interQuad = createdAtlas:assignElement(element) + atlases[canvasID]:refragment() + canvas, quad, interQuad = atlases[canvasID]:assignElement(element) if not canvas then --print('ran out of space') end @@ -45,7 +68,8 @@ function atlas.assign(element) end function atlas.unassign(element) - createdAtlas:unassignElement(element) + local canvasID = element.context:getCanvasIndex(true) or 1 + atlases[canvasID]:unassignElement(element) end function atlas.unassignAll() diff --git a/core/element.lua b/core/element.lua index 53caa64..0a3af32 100644 --- a/core/element.lua +++ b/core/element.lua @@ -149,48 +149,24 @@ function element:createProxies() self.context = context.new(self) end ---Random coefficients, if these reach 1.5 then canvas is made -local selfRenderTime = false -local screenSize = 1/4 -local coefficient = 1.5 - +local selfRenderTime function element.setBench(time) selfRenderTime = time end -function element:calculateCanvasCoeficient() - local avg, sum = 0, 0 - - for i, e in ipairs(self.renderBench) do - sum = sum + e - end - - avg = sum/#self.renderBench - - local sW, sH = love.graphics.getDimensions() - local areaBelow = helium.atlas.getFreeArea() - local area = self.view.h*self.view.w - - local areaCoef = (2-(helium.atlas.getRatio()) )-(area/(areaBelow/(4+3*helium.atlas.getRatio()))) - local speedCoef = avg/selfRenderTime - - - - return (areaCoef+speedCoef)>coefficient -end - local newCanvas, newQuad = love.graphics.newCanvas, love.graphics.newQuad function element:createCanvas() - self.settings.canvasW = self.view.w - self.settings.canvasH = self.view.h - self.canvas, self.quad, self.interQuad = helium.atlas.assign(self) + self.canvas, self.quad = helium.atlas.assign(self) if not self.canvas then self.settings.failedCanvas = true self.settings.hasCanvas = false return end + + self.settings.canvasW = self.view.w + self.settings.canvasH = self.view.h self.settings.hasCanvas = true end @@ -230,13 +206,6 @@ function element:setup() end local setColor, rectangle, setFont, printf = love.graphics.setColor, love.graphics.rectangle, love.graphics.setFont, love.graphics.printf -function element:errorRender(msg) - setColor(1, 0, 0) - rectangle('line', 0, 0, self.view.w, self.view.h) - setColor(1, 1, 1) - printf("Error: "..msg, 0, 0, self.view.w) -end - local calcT function element:internalRender() @@ -245,6 +214,7 @@ function element:internalRender() end self.renderer() + if self.settings.testRenderPasses > 0 and selfRenderTime then self.settings.testRenderPasses = self.settings.testRenderPasses-1 local selfTime = love.timer.getTime()-calcT @@ -267,7 +237,6 @@ end function element:externalRender() local cnvs = getCanvas() love.graphics.push('all') - love.graphics.translate(self.view.x, self.view.y) if not self.settings.isSetup then self:setup() @@ -278,18 +247,21 @@ function element:externalRender() if self.settings.hasCanvas then setCanvas(self.canvas) --need scissors - --love.graphics.clear(0,0,0,0) love.graphics.push('all') love.graphics.origin() - local ox, oy = self.quad:getViewport() + local ox, oy, w, h = self.quad:getViewport() love.graphics.translate(ox, oy) + love.graphics.setScissor(ox, oy, w, h) + love.graphics.clear(0,0,0,0) self:renderWrapper() self.settings.needsRendering = false - love.graphics.pop() else + love.graphics.translate(self.view.x, self.view.y) + local x, y = love.graphics.transformPoint(0, 0) + love.graphics.setScissor(x, y, self.view.w, self.view.h) self:renderWrapper() end end @@ -297,19 +269,9 @@ function element:externalRender() setCanvas(cnvs) if self.settings.hasCanvas then - if self.canvas == cnvs then - love.graphics.push('all') - love.graphics.origin() - setColor(1,1,1,1) - setCanvas(helium.atlas.interCanvas) - draw(self.canvas, self.quad, 0, 0) - love.graphics.pop() - setCanvas(cnvs) - draw(helium.atlas.interCanvas, self.interQuad, 0, 0) - else - setColor(1,1,1,1) - draw(self.canvas, self.quad, 0, 0) - end + love.graphics.translate(self.view.x, self.view.y) + setColor(1, 1, 1, 1) + draw(self.canvas, self.quad, 0, 0) end love.graphics.pop() @@ -318,14 +280,9 @@ end function element:externalUpdate() self.context:zIndex() if not self.settings.failedCanvas and self.settings.testRenderPasses == 0 and not self.settings.hasCanvas then + self:createCanvas() - if self:calculateCanvasCoeficient() then - self:createCanvas() - - self.settings.pendingUpdate = true - else - self.settings.failedCanvas = true - end + self.settings.pendingUpdate = true end if self.settings.pendingUpdate then @@ -381,7 +338,7 @@ function element:draw(x, y, w, h) self.settings.remove = false self.settings.firstDraw = false if cx then - self.settings.testRenderPasses = self.settings.testRenderPasses-5 + self.settings.testRenderPasses = self.settings.testRenderPasses+5 end end end diff --git a/core/input.lua b/core/input.lua index 7b696cf..8a1b818 100644 --- a/core/input.lua +++ b/core/input.lua @@ -93,7 +93,7 @@ function subscription.create(x, y, w, h, eventType, callback, doff) input.subscriptions[eventType] = {} end - table.insert(input.subscriptions[eventType],1,sub) + table.insert(input.subscriptions[eventType], 1, sub) input.sortZ() diff --git a/core/stack.lua b/core/stack.lua index 468a602..7380619 100644 --- a/core/stack.lua +++ b/core/stack.lua @@ -99,6 +99,21 @@ function context:destroy() end end +function context:getCanvasIndex(forCanvas) + if self.parentCtx then + if self.element.settings.hasCanvas then + return self.parentCtx:getCanvasIndex() == 1 and 2 or 1 + else + if forCanvas then + return self.parentCtx:getCanvasIndex() == 1 and 2 or 1 + end + end + else + --No parent path (element becomes the first one cached) + return self.element.settings.hasCanvas and 1 or nil + end +end + function context:getChildrenCount() return #self.childrenContexts end diff --git a/init.lua b/init.lua index 6f8b2cc..2ea75e8 100644 --- a/init.lua +++ b/init.lua @@ -51,6 +51,7 @@ function helium.draw() end helium.element.setBench((love.timer.getTime()-startTime)/5) + helium.atlas.setBench((love.timer.getTime()-startTime)/5) first = false --love.graphics.setScissor() diff --git a/shell/button.lua b/shell/button.lua new file mode 100644 index 0000000..6254a33 --- /dev/null +++ b/shell/button.lua @@ -0,0 +1,10 @@ +local path = string.sub(..., 1, string.len(...) - string.len(".shell.button")) +local state = require(path.. ".control.state") +local input = require(path.. ".core.input") + +return function(onClick, onRelease, onEnter, onExit, x, y, w, h) + local button = {} + input('clicked') + + return button +end \ No newline at end of file