├── LICENSE ├── README.md ├── debugGraph.lua └── main.lua /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 4 | software, either in source code form or as a compiled binary, for any purpose, 5 | commercial or non-commercial, and by any means. 6 | 7 | In jurisdictions that recognize copyright laws, the author or authors of this 8 | software dedicate any and all copyright interest in the software to the public 9 | domain. We make this dedication for the benefit of the public at large and to 10 | the detriment of our heirs and successors. We intend this dedication to be an 11 | overt act of relinquishment in perpetuity of all present and future rights to 12 | this software under copyright law. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTBILITY, FITNESS 16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT, IN NO EVENT SHALL THE AUTHORS BE 17 | LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF 18 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 19 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | For more information, please refer to 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Löve Debug Graph 2 | ------------------ 3 | 4 | A Löve2D graph tool for drawing FPS, memory or custom graphs. 5 | 6 | ![](http://i.imgur.com/YiliXZQ.png) 7 | 8 | ## Usage 9 | 10 | ```lua 11 | debugGraph = require 'debugGraph' 12 | 13 | -- https://love2d.org/wiki/General_math 14 | -- Returns 'n' rounded to the nearest 'deci'th (defaulting whole numbers). 15 | function math.round(n, deci) 16 | deci = 10^(deci or 0) 17 | return math.floor(n*deci+.5)/deci 18 | end 19 | 20 | function love.load() 21 | fpsGraph = debugGraph:new('fps', 0, 0) 22 | memGraph = debugGraph:new('mem', 0, 30) 23 | dtGraph = debugGraph:new('custom', 0, 60) 24 | end 25 | 26 | function love.update(dt) 27 | 28 | -- Update the graphs 29 | fpsGraph:update(dt) 30 | memGraph:update(dt) 31 | 32 | -- Update our custom graph 33 | dtGraph:update(dt, math.floor(dt * 1000)) 34 | dtGraph.label = 'DT: ' .. math.round(dt, 4) 35 | end 36 | 37 | function love.draw() 38 | -- Draw graphs 39 | fpsGraph:draw() 40 | memGraph:draw() 41 | dtGraph:draw() 42 | end 43 | 44 | function love.keypressed(key) 45 | if key == 'escape' then 46 | love.event.quit() 47 | end 48 | end 49 | ``` 50 | 51 | ## Configuration 52 | 53 | Key | Default | Description 54 | ---------|---------------|---------------------------- 55 | x | 0 | The X position of the graph 56 | y | 0 | The Y position of the graph 57 | width | 50 | The graph width 58 | height | 30 | The graph height 59 | delay | 0.5 | The update delay in seconds 60 | label | #graph type# | The graph label 61 | font | Vera Sans 8px | The label font 62 | -------------------------------------------------------------------------------- /debugGraph.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | UNLICENSE 3 | 4 | This is free and unencumbered software released into the public domain. 5 | 6 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 7 | software, either in source code form or as a compiled binary, for any purpose, 8 | commercial or non-commercial, and by any means. 9 | 10 | In jurisdictions that recognize copyright laws, the author or authors of this 11 | software dedicate any and all copyright interest in the software to the public 12 | domain. We make this dedication for the benefit of the public at large and to 13 | the detriment of our heirs and successors. We intend this dedication to be an 14 | overt act of relinquishment in perpetuity of all present and future rights to 15 | this software under copyright law. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTBILITY, FITNESS 19 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT, IN NO EVENT SHALL THE AUTHORS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF 21 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | ]] 26 | 27 | -- Code based on https://github.com/icrawler/FPSGraph 28 | 29 | local debugGraph = {} 30 | 31 | function debugGraph:new(type, x, y, width, height, delay, label, font) 32 | if ({mem=0, fps=0, custom=0})[type] == nil then 33 | error('Acceptable types: mem, fps, custom') 34 | end 35 | 36 | local instance = { 37 | x = x or 0, -- X position 38 | y = y or 0, -- Y position 39 | width = width or 50, -- Graph width 40 | height = height or 30, -- Graph height 41 | delay = delay or 0.5, -- Update delay 42 | label = label or type, -- Graph label 43 | font = font or love.graphics.newFont(8), 44 | data = {}, 45 | _max = 0, 46 | _time = 0, 47 | _type = type, 48 | } 49 | 50 | -- Build base data 51 | for i = 0, math.floor(instance.width / 2) do 52 | table.insert(instance.data, 0) 53 | end 54 | 55 | -- Updating the graph 56 | function instance:update(dt, val) 57 | local lastTime = self._time 58 | self._time = (self._time + dt) % self.delay 59 | 60 | -- Check if the minimum amount of time has past 61 | if dt > self.delay or lastTime > self._time then 62 | -- Fetch data if needed 63 | if val == nil then 64 | if self._type == 'fps' then 65 | -- Collect fps info and update the label 66 | val = 0.75 * 1 / dt + 0.25 * love.timer.getFPS() 67 | self.label = "FPS: " .. math.floor(val * 10) / 10 68 | elseif self._type == 'mem' then 69 | -- Collect memory info and update the label 70 | val = collectgarbage('count') 71 | self.label = "Memory (KB): " .. math.floor(val * 10) / 10 72 | else 73 | -- If the val is nil then we'll just skip this time 74 | return 75 | end 76 | end 77 | 78 | 79 | -- pop the old data and push new data 80 | table.remove(self.data, 1) 81 | table.insert(self.data, val) 82 | 83 | -- Find the highest value 84 | local max = 0 85 | for i=1, #self.data do 86 | local v = self.data[i] 87 | if v > max then 88 | max = v 89 | end 90 | end 91 | 92 | self._max = max 93 | end 94 | end 95 | 96 | function instance:draw() 97 | -- Store the currently set font and change the font to our own 98 | local fontCache = love.graphics.getFont() 99 | love.graphics.setFont(self.font) 100 | 101 | local max = math.ceil(self._max/10) * 10 + 20 102 | local len = #self.data 103 | local steps = self.width / len 104 | 105 | -- Build the line data 106 | local lineData = {} 107 | for i=1, len do 108 | -- Build the X and Y of the point 109 | local x = steps * (i - 1) + self.x 110 | local y = self.height * (-self.data[i] / max + 1) + self.y 111 | 112 | -- Append it to the line 113 | table.insert(lineData, x) 114 | table.insert(lineData, y) 115 | end 116 | 117 | -- Draw the line 118 | love.graphics.line(unpack(lineData)) 119 | 120 | -- Print the label 121 | if self.label ~= '' then 122 | love.graphics.print(self.label, self.x, self.y + self.height - self.font:getHeight()) 123 | end 124 | 125 | -- Reset the font 126 | love.graphics.setFont(fontCache) 127 | end 128 | 129 | return instance 130 | end 131 | 132 | return debugGraph 133 | -------------------------------------------------------------------------------- /main.lua: -------------------------------------------------------------------------------- 1 | -- Import the library 2 | debugGraph = require 'debugGraph' 3 | 4 | -- https://love2d.org/wiki/General_math 5 | -- Returns 'n' rounded to the nearest 'deci'th (defaulting whole numbers). 6 | function math.round(n, deci) 7 | deci = 10^(deci or 0) 8 | return math.floor(n*deci+.5)/deci 9 | end 10 | 11 | function love.load() 12 | fpsGraph = debugGraph:new('fps', 0, 0) 13 | memGraph = debugGraph:new('mem', 0, 30) 14 | dtGraph = debugGraph:new('custom', 0, 60) 15 | end 16 | 17 | function love.update(dt) 18 | 19 | -- Update the graphs 20 | fpsGraph:update(dt) 21 | memGraph:update(dt) 22 | 23 | -- Update our custom graph 24 | dtGraph:update(dt, math.floor(dt * 1000)) 25 | dtGraph.label = 'DT: ' .. math.round(dt, 4) 26 | end 27 | 28 | function love.draw() 29 | -- Draw graphs 30 | fpsGraph:draw() 31 | memGraph:draw() 32 | dtGraph:draw() 33 | end 34 | 35 | function love.keypressed(key) 36 | if key == 'escape' then 37 | love.event.quit() 38 | end 39 | end 40 | --------------------------------------------------------------------------------