Added functions:

unpack,  setKeys, parse
Renamed dettach to detach
This commit is contained in:
devfirefly 2015-11-09 16:33:02 +00:00 committed by Ilikepotatoes Theyarelikerlygood
parent 75c6150e03
commit fa55cd6764
2 changed files with 143 additions and 106 deletions

View File

@ -23,29 +23,22 @@ end
function love.draw() function love.draw()
if drawRect then if drawRect then
drawRectangles() drawRectangles()
Prof:dettach() Prof:detach()
end end
if ProfOn then if ProfOn then
Prof:draw({50}) Prof:draw({50})
end end
end end
function hay()
end
function love.update(dt) function love.update(dt)
Prof:attach() Prof:attach()
iterateSmall() iterateSmall()
iterateLarge() iterateLarge()
if drawRect then if drawRect then
Prof:dettach(true) Prof:detach(true)
else else
Prof:dettach() Prof:detach()
end
if hey then
hay()
hay()
hay()
hay()
end end
local data = Prof:unpack()
end end
function love.keypressed(key) function love.keypressed(key)
if key == "esc" then if key == "esc" then

View File

@ -1,5 +1,5 @@
local path = ... local path = ...
local profiler = {} local piefiller = {}
local function hsvToRgb(h, s, v) local function hsvToRgb(h, s, v)
local h,s,v = h,1,1 local h,s,v = h,1,1
local h,s,v = math.fmod(h,360),s,v local h,s,v = math.fmod(h,360),s,v
@ -40,10 +40,11 @@ function setColor(...)
end end
local color_data = {} local color_data = {}
local colors = {} local colors = {}
function profiler:new() function piefiller:new()
local self = {} local self = {}
setmetatable(self,{__index = profiler}) setmetatable(self,{__index = piefiller})
self.data = {} self.data = {}
self.parsed = {}
self.last = 0 self.last = 0
self.timer = 0 self.timer = 0
self:reset() self:reset()
@ -53,9 +54,19 @@ function profiler:new()
self.y = 0 self.y = 0
self.scale = 1 self.scale = 1
self.step = 1 self.step = 1
self.keys = {
reset = "r",
increase_depth = "down",
decrease_depth = "up",
increase_step_size = ",",
decrease_step_size = ".",
shorten_names = "s",
show_hidden = "c",
save_to_file = "p",
}
return self return self
end end
function profiler:reset() function piefiller:reset()
self.data = {} self.data = {}
self.x = 0 self.x = 0
self.y = 0 self.y = 0
@ -64,7 +75,32 @@ function profiler:reset()
table.insert(colors,hsvToRgb(i,100,100)) table.insert(colors,hsvToRgb(i,100,100))
end end
end end
function profiler:attach() function piefiller:setKey(table_or_mode,key)
if type(table_or_mode) == "table" then
self.keys = table_or_mode
elseif type(table_or_mode) == "string" then
if not self.keys[table_or_mode] then error("Invalid mode: "..tostring(table_or_mode)) end
self.keys[table_or_mode] = key
else
error("Expected table or string got:"..type(table_or_mode))
end
end
function piefiller:parse(caller,parent)
return {
parent = parent,
func = caller.func,
count = 0,
time = 0,
child_time = 0,
named_child_time = 0,
children = {},
children_time = {},
info = caller,
kids = {},
}
end
function piefiller:attach()
self.last = os.clock() self.last = os.clock()
local function hook() local function hook()
local depth = self.depth local depth = self.depth
@ -79,18 +115,7 @@ function profiler:attach()
local name = caller.func local name = caller.func
local lc = self.data[last_caller.func] local lc = self.data[last_caller.func]
if not lc.kids[name] then if not lc.kids[name] then
lc.kids[name] = { lc.kids[name] = self:parse(caller,last_caller)
parent = last_caller,
func = caller.func,
count = 0,
time = 0,
child_time = 0,
named_child_time = 0,
children = {},
children_time = {},
info = caller,
kids = {},
}
end end
local kid = lc.kids[name] local kid = lc.kids[name]
kid.count = kid.count + 1 kid.count = kid.count + 1
@ -99,17 +124,7 @@ function profiler:attach()
local name = caller.func local name = caller.func
local raw = self.data[name] local raw = self.data[name]
if not raw then if not raw then
self.data[name] = { self.data[name] = self:parse(caller,last_caller)
func = caller.func,
count = 0,
time = 0,
child_time = 0,
named_child_time = 0,
children = {},
children_time = {},
info = caller,
kids = {},
}
end end
raw = self.data[name] raw = self.data[name]
raw.count = raw.count + 1 raw.count = raw.count + 1
@ -128,7 +143,7 @@ function profiler:attach()
end end
debug.sethook(hook,"",step) debug.sethook(hook,"",step)
end end
function profiler:dettach(mode) function piefiller:detach(stop)
local totaltime = 0 local totaltime = 0
local parsed = {} local parsed = {}
local no = 0 local no = 0
@ -143,6 +158,7 @@ function profiler:dettach(mode)
parsed[i].def = v.info.linedefined parsed[i].def = v.info.linedefined
parsed[i].cur = v.info.currentline parsed[i].cur = v.info.currentline
parsed[i].item = v parsed[i].item = v
parsed[i].caller = v.info
if not color_data[v.func] then if not color_data[v.func] then
local i = math.random(#colors) local i = math.random(#colors)
color_data[v.func] = colors[i] color_data[v.func] = colors[i]
@ -157,35 +173,25 @@ function profiler:dettach(mode)
end end
self.parsed = parsed self.parsed = parsed
self.totaltime = totaltime self.totaltime = totaltime
if not mode then debug.sethook() end if not stop then debug.sethook() end
end end
local largeFont = love.graphics.newFont(25) local largeFont = love.graphics.newFont(25)
function profiler:draw(args) function piefiller:draw(args)
local loading local loading
local oldFont = love.graphics.getFont() local oldFont = love.graphics.getFont()
local w,h = love.graphics.getDimensions()
love.graphics.push()
love.graphics.translate(self.x,self.y)
love.graphics.scale(self.scale)
local args = args or {} local args = args or {}
local rad = args["rad"] or 200 local rad = args["rad"] or 200
local mode = args["mode"] or "simple" local mode = args["mode"] or "simple"
local ret = args["return"] local ret = args["return"]
local pi = math.pi local pi = math.pi
if ret then local arc = love.graphics.arc
local lastangle = 0 local w,h = love.graphics.getDimensions()
local pieChart = {}
for i,v in ipairs(self.parsed) do love.graphics.push()
local angle = 3.6*v.prc
local segment = { love.graphics.translate(self.x,self.y)
name = v.name or v.linedefined, love.graphics.scale(self.scale)
angle = angle,
start = lastangle,
finish = lastangle + angle,
}
lastangle = lastangle + angle
end
end
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() local font = love.graphics.getFont()
@ -194,10 +200,10 @@ function profiler:draw(args)
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)
setColor(color) setColor(color)
love.graphics.arc("fill",cx,cy,rad,lastangle,lastangle + angle) arc("fill",cx,cy,rad,lastangle,lastangle + angle)
setColor(colors.black) setColor(colors.black)
if v.prc > 1 then if v.prc > 1 then
love.graphics.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() setColor()
@ -247,10 +253,12 @@ function profiler:draw(args)
fw = largeFont:getWidth(t) fw = largeFont:getWidth(t)
love.graphics.print("Loading...",w/2 - fw/2,h/2) love.graphics.print("Loading...",w/2 - fw/2,h/2)
end end
love.graphics.pop() love.graphics.pop()
love.graphics.setFont(oldFont) love.graphics.setFont(oldFont)
end end
function profiler:mousepressed(x,y,b) function piefiller:mousepressed(x,y,b)
if b == "wu" then if b == "wu" then
local scale = self.scale - math.floor((0.05*self.scale)*1000)/1000 local scale = self.scale - math.floor((0.05*self.scale)*1000)/1000
if scale > 0 and scale > 0.1 then if scale > 0 and scale > 0.1 then
@ -282,48 +290,84 @@ function profiler:mousepressed(x,y,b)
end end
end end
end end
function profiler:keypressed(key) function piefiller:keypressed(key)
if key == "r" then local mode
self:reset() for i,v in pairs(self.keys) do
elseif key == "up" then if key == v then
self:reset() mode = i
self.depth = self.depth - 1 break
elseif key == "down" then end
self:reset() end
self.depth = self.depth + 1 if mode then
elseif key == "," then if mode == "reset" then
self.step = self.step - 1 self:reset()
elseif key == "." then elseif mode == "increase_depth" then
self.step = self.step +1 self:reset()
elseif key == "s" then self.depth = self.depth + 1
self.small = not self.small elseif mode == "decrease_depth" then
elseif key == "c" then self:reset()
self:reset() self.depth = self.depth - 1
self.view_children = not self.view_children elseif mode == "increase_step_size" then
elseif key == "p" then self.step = self.step - 1
local parsed = copy(self.parsed) elseif mode == "decrease_step_size" then
table.sort(parsed,function(a,b) self.step = self.step +1
return a.prc > b.prc elseif mode == "shorten_names" then
end) self.small = not self.small
local d = {"Depth: "..self.depth.." with step: "..self.step.."\r\n".."Total time: "..self.totaltime.."\r\n"} elseif mode == "show_hidden" then
self:reset()
for i,v in ipairs(parsed) do self.view_children = not self.view_children
local instance = { elseif mode == "save_to_file" then
"-----"..(v.name or "def@"..v.def).."-----", local parsed = copy(self.parsed)
"source:"..v.src..":"..v.def, table.sort(parsed,function(a,b)
"current line: "..v.cur, return a.prc > b.prc
"time: "..v.time, end)
"percentage: "..math.ceil(v.prc).." %", local d = {"Depth: "..self.depth.." with step: "..self.step.."\r\n".."Total time: "..self.totaltime.."\r\n"}
"----------------",
} for i,v in ipairs(parsed) do
for i,v in ipairs(instance) do local instance = {
instance[i] = v.."\r\n" "-----"..(v.name or "def@"..v.def).."-----",
end "source:"..v.src..":"..v.def,
table.insert(d,table.concat(instance)) "current line: "..v.cur,
"time: "..v.time,
"percentage: "..math.ceil(v.prc).." %",
"----------------",
}
for i,v in ipairs(instance) do
instance[i] = v.."\r\n"
end
table.insert(d,table.concat(instance))
end
local data = table.concat(d)
love.filesystem.write("Profile",data)
love.system.openURL(love.filesystem.getRealDirectory("Profile"))
end end
local data = table.concat(d)
love.filesystem.write("Profile",data)
love.system.openURL(love.filesystem.getRealDirectory("Profile"))
end end
end end
return profiler function piefiller:unpack(fn)
local data = {
items = {},
about = {
depth = self.depth,
step = self.step,
totalTime = self.totaltime,
},
}
for i,v in ipairs(self.parsed) do
local a = {
name = v.name,
line_defined = v.def,
current_line = v.cur,
source = v.src,
time_taken = v.time,
precentage = v.prc,
caller = v.caller,
}
if fn then
assert(type(fn) == "function","Expected function got:"..type(fn))
fn(a)
end
table.insert(data.items,a)
end
return data
end
return piefiller