6 Commits
v0 ... master

Author SHA1 Message Date
Paul Liverman III
b433ddc889 slight improvement 2017-07-26 23:25:45 -07:00
/Fox --develop
9215842cc8 Update README.md 2017-07-26 23:21:15 -07:00
Paul Liverman III
eb128e3ecc fixed some derpy stuff and implemented lower bounds on depth and step size 2017-07-26 23:10:29 -07:00
Paul Liverman III
8869727321 scaling mostly working 2017-07-26 23:08:50 -07:00
Paul Liverman III
c0bf02ccc1 last version retaining original draw mode, but broken when scaled 2017-07-26 22:35:13 -07:00
Paul Liverman III
5896dd043e pretty close to done with improvements 2017-07-26 22:15:35 -07:00
3 changed files with 148 additions and 138 deletions

View File

@@ -4,37 +4,33 @@ Graphical profiler for Love2D >= 0.9.2
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.
Note that a lot of functionality is undocumented right now, and that some functionality doesn't work as originally intended (such as setting the position and scale of the profiler). The default settings should get you going pretty easily, the key thing to maybe change is calling the constructor with a table with its own `scale` value.
# Usage
1) Require the file:
```lua
local piefiller = require("piefiller")
local Piefiller = require("piefiller")
```
2) Make a new instance of piefiller:
```lua
local Pie = piefiller:new()
local pie = Piefiller()
```
3) Attach the piefiller to the part of your application that you want to monitor (love.update and love.draw typically are good places):
```lua
function love.update()
Pie:attach()
pie:attach()
-- do something
Pie:detach()
pie:detach()
end
```
4) Draw the output and pass events to your piefiller:
4) Draw the output and pass key events to your piefiller:
```lua
function love.draw()
Pie:draw()
pie:draw()
end
function love.keypressed(key)
Pie:keypressed(key)
end
function love.mousepressed(...)
Pie:mousepressed(...)
pie:keypressed(key)
end
```
5) With sufficient output, press the `E` key to output to file. Example output:
@@ -84,13 +80,13 @@ show_profiler
To redefine only one of the keys:
```lua
piefiller:setKey(command, key)
pie:setKey(command, key)
```
example:
```lua
piefiller:setKey("increase_depth","up")
pie:setKey("increase_depth","up")
```
To redefine all of the keys:
@@ -98,12 +94,12 @@ To redefine all of the keys:
table = {
"increase_depth" = "up"
}
piefiller:setKey(table)
pie:setKey(table)
```
# For your own interpretation
If you wish to interpret the data on your own use `piefiller:unpack()`.
If you wish to interpret the data on your own use `pie:unpack()`.
Output is a table as such:
```lua
@@ -134,7 +130,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
most likely will only be wanting to optimize the most expensive items. (And you
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
local Profiler = require("piefiller")
local profiler = Profiler:new()
local profiler = Profiler()
function iterateSmall()
for i=1,1000 do
@@ -31,10 +30,17 @@ function love.draw()
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()
end
-- temporary
local w, h = love.graphics.getWidth(), love.graphics.getHeight()
love.graphics.setColor(255, 255, 255, 255)
love.graphics.rectangle("fill", 0, 0, w, h)
profiler:draw()
-- temporary
love.graphics.setColor(255, 255, 255, 255)
love.graphics.line(w/2, 0, w/2, h)
love.graphics.line(0, h/2, w, h/2)
end
function love.update(dt)
@@ -49,7 +55,7 @@ end
function love.keypressed(key)
if key == "escape" then
profilerOn = not profilerOn
love.event.quit()
elseif key == ";" then
drawRect = not drawRect
end
@@ -57,16 +63,12 @@ function love.keypressed(key)
profiler:keypressed(key)
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")
if y < 0 then
-- up
profiler.scale = profiler.scale - 0.1
else
love.mousepressed(X, Y, "wd")
-- down
profiler.scale = profiler.scale + 0.1
end
end

View File

@@ -2,9 +2,8 @@ local path = ...
local piefiller = {}
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)
if s == 0 then return {v, v, v} end
@@ -40,22 +39,24 @@ local function copy(t)
return ret
end
local function setColor(...) -- was global
local function setColor(...)
-- TODO factor this function out?
local args = {...}
love.graphics.setColor(args[1] or 255, args[2] or 255, args[3] or 255, args[4] or 255)
end
-- TODO verify these do not break if using multiple profilers
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
table.insert( colors, hsvToRgb(i, 1, 1) )
end
function piefiller:new()
function piefiller:new(settings)
local self = {}
setmetatable( self, {__index = piefiller} )
self.data = {}
self.parsed = {}
self.last = 0
@@ -64,42 +65,58 @@ function piefiller:new()
self.small = false
self.x = 0
self.y = 0
self.scale = 1
self.scale = 0.4
self.font = love.graphics.newFont(16 / self.scale)
self.visible = true
self.step = 1
self.background = {0, 0, 0, 180}
self.keys = {
reset = "r",
increase_depth = "down",
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 = "=", -- changed default to "+" button
decrease_step_size = "-", -- changed default to "-" button
shorten_names = "z", -- changed default (based on assumption WASD is common control scheme)
show_hidden = "h", -- changed default
save_to_file = "e", -- changed default -> e for export
show_profiler = "p", -- added new control to show/hide the profiler, default p
increase_step_size = "=",
decrease_step_size = "-",
shorten_names = "z",
show_hidden = "h",
save_to_file = "e",
show_profiler = "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
end
function piefiller:reset()
self.data = {}
-- why should these be reset? only the data matters
self.x = 0
self.y = 0
self.scale = 1
-- self.x = 0
-- self.y = 0
-- self.scale = 1
end
function piefiller:setKey(table_or_command,key)
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
if self.keys[i] then self.keys[i] = v end
end
elseif type(table_or_command) == "string" then
if not self.keys[table_or_command] then error("Invalid command: "..tostring(table_or_command)) end
self.keys[table_or_command] = key
elseif not table_or_command then
self.keys = {}
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
@@ -202,126 +219,115 @@ function piefiller:detach(stop) -- TODO figure out what stop is useful for
if not stop then debug.sethook() end
end
local largeFont = love.graphics.newFont(25)
function piefiller:getText(v)
if self.small then
if v.src:sub(1,1) == "@" then
return tostring(math.ceil(v.prc)).."% "..tostring(v.src:sub(2))..":"..tostring(v.def)
else
return tostring(math.ceil(v.prc)).."% "..tostring(v.src)..":"..tostring(v.def)
end
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)
function piefiller:draw(args)
if not self.visible then return end
local loading
local oldFont = love.graphics.getFont()
local args = args or {}
local rad = args.rad or 200
-- these weren't even being used
-- local mode = args["mode"] or "simple"
-- local ret = args["return"]
local oldLineJoin = love.graphics.getLineJoin()
local pi = math.pi
local arc = love.graphics.arc
local w,h = love.graphics.getDimensions()
local args = args or {}
local rad = args.radius or (h * self.scale - 2 / self.scale)
local mode = args.mode or "original" -- "original" for the original style
love.graphics.push()
love.graphics.translate(self.x,self.y)
love.graphics.translate(self.x, self.y)
love.graphics.scale(self.scale)
love.graphics.setLineJoin("bevel")
love.graphics.setFont(self.font)
local cx = w/2 + (rad*2 - w)/2 + 2 / self.scale
local cy = h * self.scale
local maxLength = 0
for i,v in ipairs(self.parsed) do
local s = self.font:getWidth(self:getText(v))
if s > maxLength then maxLength = s end
end
setColor(self.background)
love.graphics.rectangle("fill", 0, 0, cx * 2 + 2 / self.scale + maxLength, cy * 2)
if self.parsed and self.totaltime > 0 then
local lastangle = 0
local font = love.graphics.getFont()
for i,v in ipairs(self.parsed) do
local color = v.color
local cx,cy = w/2,h/2
local angle = math.rad(3.6*v.prc)
setColor(color)
arc("fill",cx,cy,rad,lastangle,lastangle + angle)
-- setColor(colors.black) -- not defined, actually needs to be white
setColor(255, 255, 255, 255)
if v.prc > 1 then
arc("line",cx,cy,rad,lastangle,lastangle + angle)
end
lastangle = lastangle + angle
setColor()
end
lastangle = 0
love.graphics.circle("line", cx, cy, rad) -- make sure there is an outer white border
local x = cx + rad + 2 / self.scale
local y = cy - rad
love.graphics.print("Depth: "..self.depth.." Step: "..self.step, x, y)
y = y + self.font:getHeight()
local sorted = {}
for i,v in ipairs(self.parsed) do
local color = v.color
local cx,cy = w/2,h/2
local angle = math.rad(3.6*v.prc)
local x = cx + rad * math.cos(lastangle + angle/2)
local y = cy + rad * math.sin(lastangle + angle/2)
if self.small then
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 sx = 1
if cx < x then
sx = -1
fw = 0
end
if cy + rad/2 < y then
y = y + font:getHeight()
elseif cy + rad/2 > y then
y = y - font:getHeight()
end
local ofx
love.graphics.print(txt,((x) + (-(fw+20))*sx),y)
lastangle = lastangle + angle
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 + self.font:getHeight()
end
else
loading = true
-- REFACTOR
setColor()
local t = "Loading..."
local fh = self.font:getHeight()
fw = self.font:getWidth(t)
love.graphics.print("Loading...", w/2 - fw/2, h/2)
-- END
end
-- our timing is handled in draw... why? My guess is because we aren't called in update
self.timer = self.timer + love.timer.getDelta()
if self.timer > 20 then
self.timer = 0
end
love.graphics.setFont(largeFont)
local t = "Depth: "..self.depth.." with step: "..self.step
local fw = largeFont:getWidth(t)
local fh = largeFont:getHeight()
love.graphics.print(t,w/2 - fw/2,(fh+5))
if loading then
t = "Loading..."
fw = largeFont:getWidth(t)
love.graphics.print("Loading...",w/2 - fw/2,h/2)
end
love.graphics.pop()
love.graphics.setFont(oldFont)
end
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
love.graphics.setLineJoin(oldLineJoin)
end
function piefiller:keypressed(key)
@@ -340,16 +346,24 @@ function piefiller:keypressed(key)
self.depth = self.depth + 1
elseif command == "decrease_depth" then
self:reset()
self.depth = self.depth - 1
if self.depth > 1 then
self.depth = self.depth - 1
end
elseif command == "increase_step_size" then
self.step = self.step - 1
self:reset()
self.step = self.step + 1
elseif command == "decrease_step_size" then
self.step = self.step +1
self:reset()
if self.step > 0 then
self.step = self.step - 1
end
elseif command == "shorten_names" then
self.small = not self.small
elseif command == "show_hidden" then
self:reset()
self.view_children = not self.view_children
elseif command == "show_profiler" then
self.visible = not self.visible
elseif command == "save_to_file" then
local parsed = copy(self.parsed)
table.sort(parsed,function(a,b)
@@ -407,4 +421,6 @@ function piefiller:unpack(fn)
return data
end
setmetatable( piefiller, { __call = piefiller.new } )
return piefiller