RollFor/src/DebugBuffer.lua
2025-03-30 23:09:58 +02:00

258 lines
5.4 KiB
Lua

RollFor = RollFor or {}
local m = RollFor
if m.DebugBuffer then return end
local M = {}
M.modules = {}
local getn = m.getn
-- Keeping a global index so we can later reconstruct the order of messages when printing only a subset of modules.
local message_index = 0
local pp = m.pretty_print
---@class DebugMessage
---@field index number
---@field text string
local colors = {
"ff8080", -- soft pink
"8aeb9f", -- mint green
"80b8ff", -- light blue
"ffb380", -- peach
"b880ff", -- lavender
"80ffb3", -- seafoam green
"ffa680", -- light orange
"80ffb3", -- pale turquoise
"b880ff", -- light purple
"ffb3b3", -- baby pink
"80e2ff", -- sky blue
"ffb380", -- cream
"b3ff80", -- lime cream
"ff80b3", -- rose pink
"80ffa6" -- pale mint
}
---@param text string
local function make_message( text )
message_index = message_index + 1
---@type DebugMessage
return { index = message_index, text = text }
end
---@class DebugBuffer
---@field add fun( message: string )
---@field show fun()
---@field enable fun( console: boolean )
---@field disable fun()
---@field toggle fun()
function M.new( module_name, max_size )
local messages = {} ---@type DebugMessage[]
local head = 0
local count = 0
local debug_enabled = false
local console_enabled = false
local function add( message )
head = head + 1
if head > max_size then
head = 1
end
messages[ head ] = make_message( message )
if count < max_size then
count = count + 1
end
if debug_enabled then
if console_enabled then
print( string.format( "[%s]: %s", module_name, message ) )
else
pp( message, m.colors.grey, module_name )
end
end
end
local function get()
local result = {}
local start = head - count + 1
if start < 1 then
start = start + max_size
end
for i = 1, count do
local idx = start + i - 1
if idx > max_size then
idx = idx - max_size
end
table.insert( result, messages[ idx ] )
end
return result
end
local function show()
for _, message in ipairs( get() ) do
pp( message.text, m.colors.grey, message.module_name )
end
end
local function print_debug_status()
if console_enabled then
print( string.format( "\n[%s]: Debug %s.", module_name, debug_enabled and "enabled" or "disabled" ) )
else
pp( string.format( "Debug %s.", debug_enabled and m.msg.enabled or m.msg.disabled, m.colors.grey, module_name ), m.colors.grey, module_name )
end
end
local function enable( console )
debug_enabled = true
console_enabled = console
print_debug_status()
end
local function disable()
debug_enabled = false
console_enabled = false
print_debug_status()
end
local function toggle()
debug_enabled = not debug_enabled
print_debug_status()
end
local result = {
add = add,
get = get,
show = show,
enable = enable,
disable = disable,
toggle = toggle,
is_enabled = function() return debug_enabled end
}
M.modules[ module_name ] = result
return result
end
M.disable_all = function()
for _, module in pairs( M.modules ) do
module.disable()
end
end
local function get_colors( module_names )
local result = {}
local color_count = getn( colors )
local color_index = math.random( color_count ) - 1
for _, module_name in ipairs( module_names ) do
if color_index == color_count then
color_index = 0
else
color_index = color_index + 1
end
result[ module_name ] = colors[ color_index ]
end
return result
end
---@param module_names string[]
local function show( module_names )
local c = get_colors( module_names )
local result = {}
for _, module_name in ipairs( module_names ) do
local mod = m[ module_name ]
if mod and mod.debug then
local dbg = mod.debug
local messages = dbg.get() ---@type DebugMessage[]
for _, message in ipairs( messages ) do
table.insert( result, { module_name = module_name, index = message.index, text = message.text } )
end
end
end
table.sort( result, function( a, b ) return a.index < b.index end )
if getn( result ) == 0 then
pp( "No debug messages.", m.colors.grey )
return
end
local msg = function( tag )
return string.format(
"Debug messages %s (%s %s):",
tag,
m.colors.blue( "RollFor" ),
m.colors.hl( "v" .. m.get_addon_version().str )
)
end
pp( msg( "start" ) )
for _, message in ipairs( result ) do
pp( message.text, m.colors.grey, m.colorize( c[ message.module_name ], message.module_name ) )
end
pp( msg( "end" ) )
end
function M.on_command( args )
---@param modules string
local function parse_module_names( modules )
local result = {}
for module_name in string.gmatch( modules, "%S+" ) do
table.insert( result, module_name )
end
return result
end
if args == "debug show" then
show( { "RollController", "LootController" } )
return
end
for command, modules in string.gmatch( args, "debug (.-) (.*)" ) do
local module_names = parse_module_names( modules )
if command == "show" then
show( module_names )
return
end
for _, module_name in ipairs( module_names ) do
local mod = m[ module_name ]
if mod and mod.debug then
local dbg = mod.debug
local f = dbg[ command ]
if f then f() end
end
end
return
end
end
m.DebugBuffer = M
return M