pretty close to done with improvements

This commit is contained in:
Paul Liverman III 2017-07-26 22:15:35 -07:00
parent 6ce2e48317
commit 5896dd043e
3 changed files with 116 additions and 112 deletions

View File

@ -4,9 +4,6 @@ Graphical profiler for Love2D >= 0.9.2
Originally by devfirefly, heavily modified by Guard13007. Originally by devfirefly, heavily modified by Guard13007.
NOTE: This ReadMe does not currently represent the state of the library as I am
currently reworking it.
# Usage # Usage
1) Require the file: 1) Require the file:
@ -25,7 +22,7 @@ currently reworking it.
Pie:detach() Pie:detach()
end end
``` ```
4) Draw the output and pass events to your piefiller: 4) Draw the output and pass key events to your piefiller:
```lua ```lua
function love.draw() function love.draw()
Pie:draw() Pie:draw()
@ -33,9 +30,6 @@ currently reworking it.
function love.keypressed(key) function love.keypressed(key)
Pie:keypressed(key) Pie:keypressed(key)
end end
function love.mousepressed(...)
Pie:mousepressed(...)
end
``` ```
5) With sufficient output, press the `E` key to output to file. Example output: 5) With sufficient output, press the `E` key to output to file. Example output:
``` ```
@ -134,7 +128,3 @@ The best depth to search in is usually 2 and sometimes 3.
When used in large applications the output may be too much to read, however you When used in large applications the output may be too much to read, however you
most likely will only be wanting to optimize the most expensive items. (And you most likely will only be wanting to optimize the most expensive items. (And you
can always output the data to review later.) can always output the data to review later.)
# Planned features
See my ToDo list, issue #1 on GitHub.

View File

@ -1,8 +1,7 @@
profilerOn = true
drawRect = true drawRect = true
local Profiler = require("piefiller") local Profiler = require("piefiller")
local profiler = Profiler:new() local profiler = Profiler()
function iterateSmall() function iterateSmall()
for i=1,1000 do for i=1,1000 do
@ -31,11 +30,8 @@ function love.draw()
profiler:detach() -- was attached in update function profiler:detach() -- was attached in update function
if profilerOn then
-- profiler:draw({50}) -- did not appear to have a difference in 0.9.2 or 0.10.2
profiler:draw() profiler:draw()
end end
end
function love.update(dt) function love.update(dt)
profiler:attach() profiler:attach()
@ -49,24 +45,10 @@ end
function love.keypressed(key) function love.keypressed(key)
if key == "escape" then if key == "escape" then
profilerOn = not profilerOn love.event.quit()
elseif key == ";" then elseif key == ";" then
drawRect = not drawRect drawRect = not drawRect
end end
profiler:keypressed(key) profiler:keypressed(key)
end end
function love.mousepressed(...)
profiler:mousepressed(...)
end
-- temporarily allowing for old behavior in 0.10.2
function love.wheelmoved(x, y)
local X, Y = love.mouse.getPosition()
if y > 0 then
love.mousepressed(X, Y, "wu")
else
love.mousepressed(X, Y, "wd")
end
end

View File

@ -2,9 +2,8 @@ local path = ...
local piefiller = {} local piefiller = {}
local function hsvToRgb(h, s, v) local function hsvToRgb(h, s, v)
local i, f, p, q, t, r, g, b -- was polluting with globals local i, f, p, q, t, r, g, b
-- local h,s,v = h,1,1 -- was ignoring s/v values entirely
h = math.fmod(h, 360) h = math.fmod(h, 360)
if s == 0 then return {v, v, v} end if s == 0 then return {v, v, v} end
@ -40,22 +39,24 @@ local function copy(t)
return ret return ret
end end
local function setColor(...) -- was global local function setColor(...)
-- TODO factor this function out?
local args = {...} local args = {...}
love.graphics.setColor(args[1] or 255, args[2] or 255, args[3] or 255, args[4] or 255) love.graphics.setColor(args[1] or 255, args[2] or 255, args[3] or 255, args[4] or 255)
end end
-- TODO verify these do not break if using multiple profilers -- TODO verify these do not break if using multiple profilers
local color_data = {} local color_data = {}
local colors = {} -- the pool of available colors is removed from every time a new time is used local colors = {} -- NOTE the pool of available colors is removed from every time a new time is used
for i=0,300 do for i=0,300 do
table.insert( colors, hsvToRgb(i, 1, 1) ) table.insert( colors, hsvToRgb(i, 1, 1) )
end end
function piefiller:new() function piefiller:new(settings)
local self = {} local self = {}
setmetatable( self, {__index = piefiller} ) setmetatable( self, {__index = piefiller} )
self.data = {} self.data = {}
self.parsed = {} self.parsed = {}
self.last = 0 self.last = 0
@ -65,41 +66,56 @@ function piefiller:new()
self.x = 0 self.x = 0
self.y = 0 self.y = 0
self.scale = 1 self.scale = 1
self.visible = true
self.step = 1 self.step = 1
self.background = {0, 0, 0, 180}
self.keys = { self.keys = {
reset = "r", reset = "r",
increase_depth = "down", increase_depth = "down",
decrease_depth = "up", decrease_depth = "up",
-- TODO changing step_size should trigger a reset (by default, make it optional), because else the data is invalid increase_step_size = "=",
increase_step_size = "=", -- changed default to "+" button decrease_step_size = "-",
decrease_step_size = "-", -- changed default to "-" button shorten_names = "z",
shorten_names = "z", -- changed default (based on assumption WASD is common control scheme) show_hidden = "h",
show_hidden = "h", -- changed default save_to_file = "e",
save_to_file = "e", -- changed default -> e for export show_profiler = "p",
show_profiler = "p", -- added new control to show/hide the profiler, default p
} }
if settings then
for k,v in pairs(settings) do
if self[k] then
self[k] = v
end
end
if not type(self.keys) == "table" then
self.keys = {}
end
end
return self return self
end end
function piefiller:reset() function piefiller:reset()
self.data = {} self.data = {}
-- why should these be reset? only the data matters -- why should these be reset? only the data matters
self.x = 0 -- self.x = 0
self.y = 0 -- self.y = 0
self.scale = 1 -- self.scale = 1
end end
function piefiller:setKey(table_or_command,key) function piefiller:setKey(table_or_command,key)
if type(table_or_command) == "table" then if type(table_or_command) == "table" then
self.keys = table_or_command -- self.keys = table_or_command -- this was stupid and pointless actually, wtf
for i,v in pairs(table_or_command) do for i,v in pairs(table_or_command) do
if self.keys[i] then self.keys[i] = v end if self.keys[i] then self.keys[i] = v end
end end
elseif type(table_or_command) == "string" then elseif type(table_or_command) == "string" then
if not self.keys[table_or_command] then error("Invalid command: "..tostring(table_or_command)) end if not self.keys[table_or_command] then error("Invalid command: "..tostring(table_or_command)) end
self.keys[table_or_command] = key self.keys[table_or_command] = key
elseif not table_or_command then
self.keys = {}
else else
error("Expected table or string, got: "..type(table_or_command)) error("Expected table, string, false, or nil; got: "..type(table_or_command))
end end
end end
@ -202,15 +218,29 @@ function piefiller:detach(stop) -- TODO figure out what stop is useful for
if not stop then debug.sethook() end if not stop then debug.sethook() end
end end
function piefiller:getText(v)
if self.small then
return tostring(math.ceil(v.prc)).."% "..tostring(v.src)..":"..tostring(v.def)
else
if v.src:sub(1,1) == "@" then
return tostring(math.ceil(v.prc)).."% "..tostring(v.name)..tostring(v.src)..":"..tostring(v.def)
else
return tostring(math.ceil(v.prc)).."% "..tostring(v.name).."@"..tostring(v.src)..":"..tostring(v.def)
end
end
end
local largeFont = love.graphics.newFont(25) local largeFont = love.graphics.newFont(25)
function piefiller:draw(args) function piefiller:draw(args)
if not self.visible then return end
local loading local loading
local oldFont = love.graphics.getFont() local oldFont = love.graphics.getFont()
local oldLineJoin = love.graphics.getLineJoin()
local args = args or {} local args = args or {}
local rad = args.rad or 200 local rad = args.radius or 200
-- these weren't even being used local mode = args.mode or "list" -- "original" for the original style
-- local mode = args["mode"] or "simple"
-- local ret = args["return"]
local pi = math.pi local pi = math.pi
local arc = love.graphics.arc local arc = love.graphics.arc
local w,h = love.graphics.getDimensions() local w,h = love.graphics.getDimensions()
@ -219,10 +249,13 @@ function piefiller:draw(args)
love.graphics.translate(self.x,self.y) love.graphics.translate(self.x,self.y)
love.graphics.scale(self.scale) love.graphics.scale(self.scale)
love.graphics.setLineJoin("bevel")
setColor(self.background)
love.graphics.rectangle("fill", 0, 0, w, h)
if self.parsed and self.totaltime > 0 then if self.parsed and self.totaltime > 0 then
local lastangle = 0 local lastangle = 0
local font = love.graphics.getFont()
for i,v in ipairs(self.parsed) do for i,v in ipairs(self.parsed) do
local color = v.color local color = v.color
@ -230,27 +263,47 @@ function piefiller:draw(args)
local angle = math.rad(3.6*v.prc) local angle = math.rad(3.6*v.prc)
setColor(color) setColor(color)
arc("fill",cx,cy,rad,lastangle,lastangle + angle) arc("fill",cx,cy,rad,lastangle,lastangle + angle)
-- setColor(colors.black) -- not defined, actually needs to be white
setColor(255, 255, 255, 255) setColor(255, 255, 255, 255)
if v.prc > 1 then if v.prc > 1 then
arc("line",cx,cy,rad,lastangle,lastangle + angle) arc("line",cx,cy,rad,lastangle,lastangle + angle)
end end
lastangle = lastangle + angle lastangle = lastangle + angle
setColor()
end end
love.graphics.circle("line", w/2, h/2, rad) -- make sure there is an outer white border
if mode == "list" then
local x = w/2 + rad + 2
local y = h/2 - rad
local sorted = {}
for i,v in ipairs(self.parsed) do
sorted[i] = {i, v.prc}
end
table.sort(sorted,function(a,b)
return a[2] > b[2]
end)
for _,i in ipairs(sorted) do
local v = self.parsed[i[1]]
local color = v.color
local txt = self:getText(v)
setColor(color)
love.graphics.print(txt, x, y)
y = y + 15
end
elseif mode == "original" then
local font = love.graphics.getFont()
lastangle = 0 lastangle = 0
for i,v in ipairs(self.parsed) do for i,v in ipairs(self.parsed) do
local color = v.color local color = v.color
local cx,cy = w/2,h/2 local cx,cy = w/2,h/2
local angle = math.rad(3.6*v.prc) local angle = math.rad(3.6*v.prc)
local x = cx + rad * math.cos(lastangle + angle/2) local x = cx + rad * math.cos(lastangle + angle/2)
local y = cy + rad * math.sin(lastangle + angle/2) local y = cy + rad * math.sin(lastangle + angle/2)
if self.small then local txt = self:getText(v)
txt = tostring(v.src).." @: "..tostring(v.name)
else
txt = tostring(math.ceil(v.prc)).." % "..tostring(v.name).." : "..tostring(v.src).." @: "..tostring(v.def)
end
local fw = font:getWidth(txt) local fw = font:getWidth(txt)
local sx = 1 local sx = 1
if cx < x then if cx < x then
@ -262,10 +315,14 @@ function piefiller:draw(args)
elseif cy + rad/2 > y then elseif cy + rad/2 > y then
y = y - font:getHeight() y = y - font:getHeight()
end end
local ofx
love.graphics.print(txt,((x) + (-(fw+20))*sx),y) love.graphics.print(txt,((x) + (-(fw+20))*sx),y)
lastangle = lastangle + angle lastangle = lastangle + angle
end end
else
error("Invalid draw mode. Should be 'list' or 'original'.")
end
else else
loading = true loading = true
end end
@ -275,6 +332,7 @@ function piefiller:draw(args)
self.timer = 0 self.timer = 0
end end
setColor()
love.graphics.setFont(largeFont) love.graphics.setFont(largeFont)
local t = "Depth: "..self.depth.." with step: "..self.step local t = "Depth: "..self.depth.." with step: "..self.step
local fw = largeFont:getWidth(t) local fw = largeFont:getWidth(t)
@ -289,39 +347,7 @@ function piefiller:draw(args)
love.graphics.pop() love.graphics.pop()
love.graphics.setFont(oldFont) love.graphics.setFont(oldFont)
end love.graphics.setLineJoin(oldLineJoin)
function piefiller:mousepressed(x,y,b)
if b == "wu" then
local scale = self.scale - math.floor((0.05*self.scale)*1000)/1000
if scale > 0 and scale > 0.1 then
local lastzoom = self.scale
local mouse_x = x - self.x
local mouse_y = y - self.y
self.scale = scale
local newx = mouse_x * (self.scale/lastzoom)
local newy = mouse_y * (self.scale/lastzoom)
self.x = self.x + (mouse_x-newx)
self.y = self.y + (mouse_y-newy)
else
self.scale = 0.1
end
elseif b == "wd" then
local scale = self.scale + math.floor((0.05*self.scale)*1000)/1000
local scalex = self.scale
if scale > 0 and scale < 20 then
local lastzoom = self.scale
local mouse_x = x - self.x
local mouse_y = y - self.y
self.scale = scale
local newx = mouse_x * (self.scale/lastzoom)
local newy = mouse_y * (self.scale/lastzoom)
self.x = self.x + (mouse_x-newx)
self.y = self.y + (mouse_y-newy)
else
self.scale = 20
end
end
end end
function piefiller:keypressed(key) function piefiller:keypressed(key)
@ -342,14 +368,18 @@ function piefiller:keypressed(key)
self:reset() self:reset()
self.depth = self.depth - 1 self.depth = self.depth - 1
elseif command == "increase_step_size" then elseif command == "increase_step_size" then
self:reset()
self.step = self.step - 1 self.step = self.step - 1
elseif command == "decrease_step_size" then elseif command == "decrease_step_size" then
self:reset()
self.step = self.step +1 self.step = self.step +1
elseif command == "shorten_names" then elseif command == "shorten_names" then
self.small = not self.small self.small = not self.small
elseif command == "show_hidden" then elseif command == "show_hidden" then
self:reset() self:reset()
self.view_children = not self.view_children self.view_children = not self.view_children
elseif command == "show_profiler" then
self.visible = not self.visible
elseif command == "save_to_file" then elseif command == "save_to_file" then
local parsed = copy(self.parsed) local parsed = copy(self.parsed)
table.sort(parsed,function(a,b) table.sort(parsed,function(a,b)
@ -407,4 +437,6 @@ function piefiller:unpack(fn)
return data return data
end end
setmetatable( piefiller, { __call = piefiller.new } )
return piefiller return piefiller