Move debug GUI out of legacy

This commit is contained in:
Cooldude2606
2026-06-26 15:22:06 +01:00
parent 95bb8ac304
commit 8b3c437847
11 changed files with 31 additions and 29 deletions
+2
View File
@@ -81,3 +81,5 @@ add(require("modules/exp_scenario/gui/rocket_info"))
add(require("modules/exp_scenario/gui/science_production"))
add(require("modules/exp_scenario/gui/surveillance"))
add(require("modules/exp_scenario/gui/task_list"))
add(require("modules/exp_scenario/gui/debug/shim"))
add(require("modules/exp_scenario/gui/debug/event_view"))
+114
View File
@@ -0,0 +1,114 @@
local Gui = require("modules/exp_scenario/gui/debug/shim")
local Model = require("modules/exp_scenario/gui/debug/model")
local Color = require("modules/exp_util/include/color")
local dump = Model.dump
local Public = {}
local ignore = {
_G = true,
assert = true,
collectgarbage = true,
error = true,
getmetatable = true,
ipairs = true,
load = true,
loadstring = true,
next = true,
pairs = true,
pcall = true,
print = true,
rawequal = true,
rawlen = true,
rawget = true,
rawset = true,
select = true,
setmetatable = true,
tonumber = true,
tostring = true,
type = true,
xpcall = true,
_VERSION = true,
["module"] = true,
require = true,
package = true,
unpack = true,
table = true,
string = true,
bit32 = true,
math = true,
debug = true,
serpent = true,
log = true,
table_size = true,
storage = true,
remote = true,
commands = true,
settings = true,
rcon = true,
script = true,
util = true,
mod_gui = true,
game = true,
rendering = true,
}
local header_name = Gui.uid_name()
local left_panel_name = Gui.uid_name()
local right_panel_name = Gui.uid_name()
Public.name = "_G"
function Public.show(container)
local main_flow = container.add{ type = "flow", direction = "horizontal" }
local left_panel = main_flow.add{ type = "scroll-pane", name = left_panel_name }
local left_panel_style = left_panel.style
left_panel_style.width = 300
for key, value in pairs(_G) do
if not ignore[key] then
local header =
left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = tostring(key) }
Gui.set_data(header, value)
end
end
local right_panel = main_flow.add{ type = "text-box", name = right_panel_name }
right_panel.read_only = true
right_panel.selectable = true
local right_panel_style = right_panel.style
right_panel_style.vertically_stretchable = true
right_panel_style.horizontally_stretchable = true
right_panel_style.maximal_width = 1000
right_panel_style.maximal_height = 1000
Gui.set_data(left_panel, { right_panel = right_panel, selected_header = nil })
end
Gui.on_click(
header_name,
function(event)
local element = event.element
local value = Gui.get_data(element)
local left_panel = element.parent.parent
local left_panel_data = Gui.get_data(left_panel)
local right_panel = left_panel_data.right_panel
local selected_header = left_panel_data.selected_header
if selected_header then
selected_header.style.font_color = Color.white
end
element.style.font_color = Color.orange
left_panel_data.selected_header = element
local content = dump(value)
right_panel.text = content
end
)
return Public
@@ -0,0 +1,174 @@
local Storage = require("modules/exp_util/storage")
local Gui = require("modules/exp_scenario/gui/debug/shim")
local Model = require("modules/exp_scenario/gui/debug/model")
local format = string.format
local insert = table.insert
local events = defines.events
-- Constants
local events_to_keep = 10
-- Local vars
local Public = {
name = "Events",
events = {}
}
local name_lookup = {}
-- GUI names
local checkbox_name = Gui.uid_name()
local filter_name = Gui.uid_name()
local clear_filter_name = Gui.uid_name()
local storage = {}
Storage.register(storage, function(tbl)
storage = tbl
end)
-- storage tables
local enabled = {}
local last_events = {}
storage.debug_event_view = {
enabled = enabled,
last_events = last_events,
filter = "",
}
function Public.on_open_debug()
local tbl = storage.debug_event_view
if tbl then
enabled = tbl.enabled
last_events = tbl.last_events
else
enabled = {}
last_events = {}
storage.debug_event_view = {
enabled = enabled,
last_events = last_events,
}
end
Public.on_open_debug = nil
end
-- Local functions
local function event_callback(event)
local id = event.name
if not enabled[id] then
return
end
local name = name_lookup[id]
if not last_events[name] then
last_events[name] = {}
end
insert(last_events[name], 1, event)
last_events[name][events_to_keep + 1] = nil
event.name = nil
local str = format("%s (id = %s): %s", name, id, Model.dump(event))
game.print(str)
log(str)
end
local function on_gui_checked_state_changed(event)
local element = event.element
local name = element.caption
local id = events[name]
local state = element.state and true or false
element.state = state
if state then
enabled[id] = true
else
enabled[id] = false
end
end
-- GUI
-- Create a table with events sorted by their names
local grid_builder = {}
for name, _ in pairs(events) do
grid_builder[#grid_builder + 1] = name
end
table.sort(grid_builder)
local function redraw_event_table(gui_table, filter)
for _, event_name in pairs(grid_builder) do
if filter == "" or event_name:find(filter) then
local index = events[event_name]
gui_table.add{ type = "flow" }.add{
name = checkbox_name,
type = "checkbox",
state = enabled[index] or false,
caption = event_name,
}
end
end
end
function Public.show(container)
local filter = storage.debug_event_view.filter
local main_frame_flow = container.add{ type = "flow", direction = "vertical" }
local filter_flow = main_frame_flow.add{ type = "flow", direction = "horizontal" }
filter_flow.add{ type = "label", caption = "filter" }
local filter_textfield = filter_flow.add{ type = "textfield", name = filter_name, text = filter }
local clear_button = filter_flow.add{ type = "button", name = clear_filter_name, caption = "clear" }
local scroll_pane = main_frame_flow.add{ type = "scroll-pane" }
local gui_table = scroll_pane.add{ type = "table", column_count = 3, draw_horizontal_lines = true }
Gui.set_data(filter_textfield, gui_table)
Gui.set_data(clear_button, { gui_table = gui_table, filter_textfield = filter_textfield })
redraw_event_table(gui_table, filter)
end
Gui.on_checked_state_changed(checkbox_name, on_gui_checked_state_changed)
Gui.on_text_changed(
filter_name,
function(event)
local element = event.element
local gui_table = Gui.get_data(element)
local filter = element.text:gsub(" ", "_")
storage.debug_event_view.filter = filter
element.text = filter
gui_table.clear()
redraw_event_table(gui_table, filter)
end
)
Gui.on_click(
clear_filter_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
local filter_textfield = data.filter_textfield
local gui_table = data.gui_table
filter_textfield.text = ""
storage.debug_event_view.filter = ""
gui_table.clear()
redraw_event_table(gui_table, "")
end
)
-- Event registers (TODO: turn to removable hooks.. maybe)
for name, id in pairs(events) do
name_lookup[id] = name
Public.events[id] = event_callback
end
return Public
@@ -0,0 +1,132 @@
local Gui = require("modules/exp_scenario/gui/debug/shim")
local Datastore = require("modules.exp_legacy.expcore.datastore")
local Color = require("modules/exp_util/include/color")
local Model = require("modules/exp_scenario/gui/debug/model")
local dump = Model.dump
local concat = table.concat
local Public = {}
local header_name = Gui.uid_name()
local left_panel_name = Gui.uid_name()
local right_panel_name = Gui.uid_name()
local input_text_box_name = Gui.uid_name()
local refresh_name = Gui.uid_name()
Public.name = "Datastore"
function Public.show(container)
local main_flow = container.add{ type = "flow", direction = "horizontal" }
local left_panel = main_flow.add{ type = "scroll-pane", name = left_panel_name }
local left_panel_style = left_panel.style
left_panel_style.width = 300
for name in pairs(table.key_sort(Datastore.debug())) do
local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = name }
Gui.set_data(header, name)
end
local right_flow = main_flow.add{ type = "flow", direction = "vertical" }
local right_top_flow = right_flow.add{ type = "flow", direction = "horizontal" }
local input_text_box = right_top_flow.add{ type = "text-box", name = input_text_box_name }
local input_text_box_style = input_text_box.style
input_text_box_style.horizontally_stretchable = true
input_text_box_style.height = 32
input_text_box_style.maximal_width = 1000
local refresh_button =
right_top_flow.add{ type = "sprite-button", name = refresh_name, sprite = "utility/reset", tooltip = "refresh" }
local refresh_button_style = refresh_button.style
refresh_button_style.width = 32
refresh_button_style.height = 32
local right_panel = right_flow.add{ type = "text-box", name = right_panel_name }
right_panel.read_only = true
right_panel.selectable = true
local right_panel_style = right_panel.style
right_panel_style.vertically_stretchable = true
right_panel_style.horizontally_stretchable = true
right_panel_style.maximal_width = 1000
right_panel_style.maximal_height = 1000
local data = {
right_panel = right_panel,
input_text_box = input_text_box,
selected_header = nil,
}
Gui.set_data(input_text_box, data)
Gui.set_data(left_panel, data)
Gui.set_data(refresh_button, data)
end
Gui.on_click(
header_name,
function(event)
local element = event.element
local table_name = Gui.get_data(element)
local left_panel = element.parent.parent
local data = Gui.get_data(left_panel)
local right_panel = data.right_panel
local selected_header = data.selected_header
local input_text_box = data.input_text_box
if selected_header then
selected_header.style.font_color = Color.white
end
element.style.font_color = Color.orange
data.selected_header = element
input_text_box.text = table_name
input_text_box.style.font_color = Color.black
local content = Datastore.debug(table_name)
local content_string = {}
for key, value in pairs(content) do
content_string[#content_string + 1] = key:gsub("^%l", string.upper) .. " = " .. dump(value)
end
right_panel.text = concat(content_string, "\n")
end
)
local function update_dump(text_input, data)
local content = Datastore.debug(text_input.text)
local content_string = {}
for key, value in pairs(content) do
content_string[#content_string + 1] = key:gsub("^%l", string.upper) .. " = " .. dump(value)
end
data.right_panel.text = concat(content_string, "\n")
end
Gui.on_text_changed(
input_text_box_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
update_dump(element, data)
end
)
Gui.on_click(
refresh_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
local input_text_box = data.input_text_box
update_dump(input_text_box, data)
end
)
return Public
@@ -0,0 +1,145 @@
local ExpElement = require("modules/exp_gui/prototype")
local ExpData = require("modules/exp_gui/data")
local ExpIter = require("modules/exp_gui/iter")
local Color = require("modules/exp_util/include/color")
local Gui = require("modules/exp_scenario/gui/debug/shim")
local Model = require("modules/exp_scenario/gui/debug/model")
local dump = Model.dump
local dump_text = Model.dump_text
local concat = table.concat
local Public = {}
local header_name = Gui.uid_name()
local left_panel_name = Gui.uid_name()
local right_panel_name = Gui.uid_name()
local input_text_box_name = Gui.uid_name()
local refresh_name = Gui.uid_name()
Public.name = "Elements"
function Public.show(container)
local main_flow = container.add{ type = "flow", direction = "horizontal" }
local left_panel = main_flow.add{ type = "scroll-pane", name = left_panel_name }
local left_panel_style = left_panel.style
left_panel_style.width = 300
--- @diagnostic disable-next-line invisible
for element_name in pairs(ExpElement._elements) do
local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = element_name }
Gui.set_data(header, element_name)
end
local right_flow = main_flow.add{ type = "flow", direction = "vertical" }
local right_top_flow = right_flow.add{ type = "flow", direction = "horizontal" }
local input_text_box = right_top_flow.add{ type = "text-box", name = input_text_box_name }
local input_text_box_style = input_text_box.style
input_text_box_style.horizontally_stretchable = true
input_text_box_style.height = 32
input_text_box_style.maximal_width = 1000
local refresh_button =
right_top_flow.add{ type = "sprite-button", name = refresh_name, sprite = "utility/reset", tooltip = "refresh" }
local refresh_button_style = refresh_button.style
refresh_button_style.width = 32
refresh_button_style.height = 32
local right_panel = right_flow.add{ type = "text-box", name = right_panel_name }
right_panel.read_only = true
right_panel.selectable = true
local right_panel_style = right_panel.style
right_panel_style.vertically_stretchable = true
right_panel_style.horizontally_stretchable = true
right_panel_style.maximal_width = 1000
right_panel_style.maximal_height = 1000
local data = {
right_panel = right_panel,
input_text_box = input_text_box,
selected_header = nil,
}
Gui.set_data(input_text_box, data)
Gui.set_data(left_panel, data)
Gui.set_data(refresh_button, data)
end
Gui.on_click(
header_name,
function(event)
local element = event.element
local element_name = Gui.get_data(element)
local left_panel = element.parent.parent
local data = Gui.get_data(left_panel)
local right_panel = data.right_panel
local selected_header = data.selected_header
local input_text_box = data.input_text_box
if selected_header then
selected_header.style.font_color = Color.white
end
element.style.font_color = Color.orange
data.selected_header = element
input_text_box.text = concat{ "ExpElement._elements[\"", element_name, "\"]" }
input_text_box.style.font_color = Color.black
--- @diagnostic disable-next-line invisible
local define = ExpElement._elements[element_name]
local content = dump({
--- @diagnostic disable-next-line invisible
debug = define._debug,
--- @diagnostic disable-next-line invisible
has_handlers = define._has_handlers,
--- @diagnostic disable-next-line invisible
track_elements = define._track_elements,
--- @diagnostic disable-next-line invisible
elements = ExpIter._scopes[element_name],
--- @diagnostic disable-next-line invisible
data = ExpData._scopes[element_name]._raw,
}) or "nil"
right_panel.text = content
end
)
local function update_dump(text_input, data, player)
local suc, ouput = dump_text(text_input.text, player)
if not suc then
text_input.style.font_color = Color.red
else
text_input.style.font_color = Color.black
data.right_panel.text = ouput
end
end
Gui.on_text_changed(
input_text_box_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
update_dump(element, data, event.player)
end
)
Gui.on_click(
refresh_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
local input_text_box = data.input_text_box
update_dump(input_text_box, data, event.player)
end
)
return Public
@@ -0,0 +1,133 @@
local Gui = require("modules/exp_scenario/gui/debug/shim")
local Model = require("modules/exp_scenario/gui/debug/model")
local Color = require("modules/exp_util/include/color")
local dump = Model.dump
local dump_text = Model.dump_text
local concat = table.concat
local Public = {}
local ignore = { tokens = true, data_store = true, datastores = true }
local header_name = Gui.uid_name()
local left_panel_name = Gui.uid_name()
local right_panel_name = Gui.uid_name()
local input_text_box_name = Gui.uid_name()
local refresh_name = Gui.uid_name()
Public.name = "storage"
function Public.show(container)
local main_flow = container.add{ type = "flow", direction = "horizontal" }
local left_panel = main_flow.add{ type = "scroll-pane", name = left_panel_name }
local left_panel_style = left_panel.style
left_panel_style.width = 300
for key, _ in pairs(storage) do
if not ignore[key] then
local header =
left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = tostring(key) }
Gui.set_data(header, key)
end
end
local right_flow = main_flow.add{ type = "flow", direction = "vertical" }
local right_top_flow = right_flow.add{ type = "flow", direction = "horizontal" }
local input_text_box = right_top_flow.add{ type = "text-box", name = input_text_box_name }
local input_text_box_style = input_text_box.style
input_text_box_style.horizontally_stretchable = true
input_text_box_style.height = 32
input_text_box_style.maximal_width = 1000
local refresh_button =
right_top_flow.add{ type = "sprite-button", name = refresh_name, sprite = "utility/reset", tooltip = "refresh" }
local refresh_button_style = refresh_button.style
refresh_button_style.width = 32
refresh_button_style.height = 32
local right_panel = right_flow.add{ type = "text-box", name = right_panel_name }
right_panel.read_only = true
right_panel.selectable = true
local right_panel_style = right_panel.style
right_panel_style.vertically_stretchable = true
right_panel_style.horizontally_stretchable = true
right_panel_style.maximal_width = 1000
right_panel_style.maximal_height = 1000
local data = {
right_panel = right_panel,
input_text_box = input_text_box,
selected_header = nil,
selected_token_id = nil,
}
Gui.set_data(input_text_box, data)
Gui.set_data(left_panel, data)
Gui.set_data(refresh_button, data)
end
Gui.on_click(
header_name,
function(event)
local element = event.element
local key = Gui.get_data(element)
local left_panel = element.parent.parent
local data = Gui.get_data(left_panel)
local right_panel = data.right_panel
local selected_header = data.selected_header
local input_text_box = data.input_text_box
if selected_header then
selected_header.style.font_color = Color.white
end
element.style.font_color = Color.orange
data.selected_header = element
input_text_box.text = concat{ "storage['", key, "']" }
input_text_box.style.font_color = Color.black
local content = dump(storage[key]) or "nil"
right_panel.text = content
end
)
local function update_dump(text_input, data, player)
local suc, ouput = dump_text(text_input.text, player)
if not suc then
text_input.style.font_color = Color.red
else
text_input.style.font_color = Color.black
data.right_panel.text = ouput
end
end
Gui.on_text_changed(
input_text_box_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
update_dump(element, data, event.player)
end
)
Gui.on_click(
refresh_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
local input_text_box = data.input_text_box
update_dump(input_text_box, data, event.player)
end
)
return Public
+113
View File
@@ -0,0 +1,113 @@
local Gui = require("modules/exp_scenario/gui/debug/shim")
local Color = require("modules/exp_util/include/color")
local Public = {}
local pages = {
require("modules/exp_scenario/gui/debug/redmew_global_view"),
require("modules/exp_scenario/gui/debug/expcore_datastore_view"),
require("modules/exp_scenario/gui/debug/expcore_gui_view"),
require("modules/exp_scenario/gui/debug/global_view"),
require("modules/exp_scenario/gui/debug/package_view"),
require("modules/exp_scenario/gui/debug/_g_view"),
require("modules/exp_scenario/gui/debug/event_view"),
}
local main_frame_name = Gui.uid_name()
local close_name = Gui.uid_name()
local tab_name = Gui.uid_name()
function Public.open_debug(player)
for i = 1, #pages do
local page = pages[i]
local callback = page.on_open_debug
if callback then
callback()
end
end
local center = player.gui.center
local frame = center[main_frame_name]
if frame then
return
end
--[[
local screen_element = player.gui.screen
frame = screen_element.add{type = 'frame', name = main_frame_name, caption = 'Debuggertron 3000'}
frame.style.size = {900, 600}
frame.auto_center = true
]]
frame = center.add{ type = "frame", name = main_frame_name, caption = "Debuggertron 3002", direction = "vertical" }
local frame_style = frame.style
frame_style.height = 600
frame_style.width = 900
local tab_flow = frame.add{ type = "flow", direction = "horizontal" }
local container = frame.add{ type = "flow" }
container.style.vertically_stretchable = true
local data = {}
for i = 1, #pages do
local page = pages[i]
local tab_button = tab_flow.add{ type = "flow" }.add{ type = "button", name = tab_name, caption = page.name }
local tab_button_style = tab_button.style
Gui.set_data(tab_button, { index = i, frame_data = data })
if i == 1 then
tab_button_style.font_color = Color.orange
data.selected_index = i
data.selected_tab_button = tab_button
data.container = container
Gui.set_data(frame, data)
page.show(container)
end
end
frame.add{ type = "button", name = close_name, caption = "Close" }
end
Gui.on_click(
tab_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
local index = data.index
local frame_data = data.frame_data
local selected_index = frame_data.selected_index
if selected_index == index then
return
end
local selected_tab_button = frame_data.selected_tab_button
selected_tab_button.style.font_color = Color.black
frame_data.selected_tab_button = element
frame_data.selected_index = index
element.style.font_color = Color.orange
local container = frame_data.container
Gui.clear(container)
pages[index].show(container)
end
)
Gui.on_click(
close_name,
function(event)
local frame = event.player.gui.center[main_frame_name]
if frame then
Gui.destroy(frame)
end
end
)
return Public
+73
View File
@@ -0,0 +1,73 @@
local Gui = require("modules/exp_scenario/gui/debug/shim") --- @dep utils.gui
local ExpUtil = require("modules/exp_util")
local concat = table.concat
local inspect = table.inspect
local pcall = pcall
local loadstring = loadstring --- @diagnostic disable-line
local rawset = rawset
local Public = {}
local inspect_process = ExpUtil.safe_value
local inspect_options = { process = inspect_process }
function Public.dump(data)
return inspect(data, inspect_options)
end
local dump = Public.dump
function Public.dump_ignore_builder(ignore)
local function process(item)
if ignore[item] then
return nil
end
return inspect_process(item)
end
local options = { process = process }
return function(data)
return inspect(data, options)
end
end
function Public.dump_function(func)
local res = { "upvalues:\n", "no longer available" }
local i = 1
--[[while true do
local n, v = debug.getupvalue(func, i)
if n == nil then
break
elseif n ~= "_ENV" then
res[#res + 1] = n
res[#res + 1] = " = "
res[#res + 1] = dump(v)
res[#res + 1] = "\n"
end
i = i + 1
end]]
return concat(res)
end
function Public.dump_text(text, player)
local func = loadstring("return " .. text)
if not func then
return false
end
local suc, var = pcall(func)
if not suc then
return false
end
return true, dump(var)
end
return Public
@@ -0,0 +1,161 @@
local Gui = require("modules/exp_scenario/gui/debug/shim") --- @dep utils.gui
local Color = require("modules/exp_util/include/color")
local Model = require("modules/exp_scenario/gui/debug/model") --- @dep modules.gui.debug.model
local dump_function = Model.dump_function
local loaded = _G.package.loaded
local Public = {}
local ignore = {
_G = true,
package = true,
coroutine = true,
table = true,
string = true,
bit32 = true,
math = true,
debug = true,
serpent = true,
["overrides.math"] = true,
util = true,
["mod-gui"] = true,
}
local file_label_name = Gui.uid_name()
local left_panel_name = Gui.uid_name()
local breadcrumbs_name = Gui.uid_name()
local top_panel_name = Gui.uid_name()
local variable_label_name = Gui.uid_name()
local text_box_name = Gui.uid_name()
Public.name = "package"
function Public.show(container)
local main_flow = container.add{ type = "flow", direction = "horizontal" }
local left_panel = main_flow.add{ type = "scroll-pane", name = left_panel_name }
local left_panel_style = left_panel.style
left_panel_style.width = 300
for name, file in pairs(loaded) do
if not ignore[name] then
local file_label =
left_panel.add{ type = "flow" }.add{ type = "label", name = file_label_name, caption = name }
Gui.set_data(file_label, file)
end
end
local right_flow = main_flow.add{ type = "flow", direction = "vertical" }
local breadcrumbs = right_flow.add{ type = "label", name = breadcrumbs_name }
local top_panel = right_flow.add{ type = "scroll-pane", name = top_panel_name }
local top_panel_style = top_panel.style
top_panel_style.height = 200
top_panel_style.maximal_width = 1000
top_panel_style.horizontally_stretchable = true
local text_box = right_flow.add{ type = "text-box", name = text_box_name }
text_box.read_only = true
text_box.selectable = true
local text_box_style = text_box.style
text_box_style.vertically_stretchable = true
text_box_style.horizontally_stretchable = true
text_box_style.maximal_width = 1000
text_box_style.maximal_height = 1000
local data = {
left_panel = left_panel,
breadcrumbs = breadcrumbs,
top_panel = top_panel,
text_box = text_box,
selected_file_label = nil,
selected_variable_label = nil,
}
Gui.set_data(left_panel, data)
Gui.set_data(top_panel, data)
end
Gui.on_click(
file_label_name,
function(event)
local element = event.element
local file = Gui.get_data(element)
local left_panel = element.parent.parent
local data = Gui.get_data(left_panel)
local selected_file_label = data.selected_file_label
if selected_file_label then
selected_file_label.style.font_color = Color.white
end
element.style.font_color = Color.orange
data.selected_file_label = element
local top_panel = data.top_panel
local text_box = data.text_box
Gui.clear(top_panel)
local file_type = type(file)
if file_type == "table" then
for k, v in pairs(file) do
local label =
top_panel.add{ type = "flow" }.add{ type = "label", name = variable_label_name, caption = k }
Gui.set_data(label, v)
end
elseif file_type == "function" then
text_box.text = dump_function(file)
else
text_box.text = tostring(file)
end
end
)
Gui.on_click(
variable_label_name,
function(event)
local element = event.element
local variable = Gui.get_data(element)
local top_panel = element.parent.parent
local data = Gui.get_data(top_panel)
local text_box = data.text_box
local variable_type = type(variable)
if variable_type == "table" then
Gui.clear(top_panel)
for k, v in pairs(variable) do
local label =
top_panel.add{ type = "flow" }.add{ type = "label", name = variable_label_name, caption = k }
Gui.set_data(label, v)
end
return
end
local selected_label = data.selected_variable_label
if selected_label and selected_label.valid then
selected_label.style.font_color = Color.white
end
element.style.font_color = Color.orange
data.selected_variable_label = element
if variable_type == "function" then
text_box.text = dump_function(variable)
else
text_box.text = tostring(variable)
end
end
)
return Public
@@ -0,0 +1,129 @@
local Gui = require("modules/exp_scenario/gui/debug/shim") --- @dep utils.gui
local Storage = require("modules/exp_util/storage")
local Color = require("modules/exp_util/include/color")
local Model = require("modules/exp_scenario/gui/debug/model") --- @dep modules.gui.debug.model
local dump = Model.dump
local dump_text = Model.dump_text
local concat = table.concat
local Public = {}
local header_name = Gui.uid_name()
local left_panel_name = Gui.uid_name()
local right_panel_name = Gui.uid_name()
local input_text_box_name = Gui.uid_name()
local refresh_name = Gui.uid_name()
Public.name = "Storage"
function Public.show(container)
local main_flow = container.add{ type = "flow", direction = "horizontal" }
local left_panel = main_flow.add{ type = "scroll-pane", name = left_panel_name }
local left_panel_style = left_panel.style
left_panel_style.width = 300
--- @diagnostic disable-next-line invisible
for token_id in pairs(Storage._registered) do
local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = token_id }
Gui.set_data(header, token_id)
end
local right_flow = main_flow.add{ type = "flow", direction = "vertical" }
local right_top_flow = right_flow.add{ type = "flow", direction = "horizontal" }
local input_text_box = right_top_flow.add{ type = "text-box", name = input_text_box_name }
local input_text_box_style = input_text_box.style
input_text_box_style.horizontally_stretchable = true
input_text_box_style.height = 32
input_text_box_style.maximal_width = 1000
local refresh_button =
right_top_flow.add{ type = "sprite-button", name = refresh_name, sprite = "utility/reset", tooltip = "refresh" }
local refresh_button_style = refresh_button.style
refresh_button_style.width = 32
refresh_button_style.height = 32
local right_panel = right_flow.add{ type = "text-box", name = right_panel_name }
right_panel.read_only = true
right_panel.selectable = true
local right_panel_style = right_panel.style
right_panel_style.vertically_stretchable = true
right_panel_style.horizontally_stretchable = true
right_panel_style.maximal_width = 1000
right_panel_style.maximal_height = 1000
local data = {
right_panel = right_panel,
input_text_box = input_text_box,
selected_header = nil,
}
Gui.set_data(input_text_box, data)
Gui.set_data(left_panel, data)
Gui.set_data(refresh_button, data)
end
Gui.on_click(
header_name,
function(event)
local element = event.element
local token_id = Gui.get_data(element)
local left_panel = element.parent.parent
local data = Gui.get_data(left_panel)
local right_panel = data.right_panel
local selected_header = data.selected_header
local input_text_box = data.input_text_box
if selected_header then
selected_header.style.font_color = Color.white
end
element.style.font_color = Color.orange
data.selected_header = element
input_text_box.text = concat{ "storage.exp_storage['", token_id, "']" }
input_text_box.style.font_color = Color.black
local content = dump(storage.exp_storage[token_id]) or "nil"
right_panel.text = content
end
)
local function update_dump(text_input, data, player)
local suc, ouput = dump_text(text_input.text, player)
if not suc then
text_input.style.font_color = Color.red
else
text_input.style.font_color = Color.black
data.right_panel.text = ouput
end
end
Gui.on_text_changed(
input_text_box_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
update_dump(element, data, event.player)
end
)
Gui.on_click(
refresh_name,
function(event)
local element = event.element
local data = Gui.get_data(element)
local input_text_box = data.input_text_box
update_dump(input_text_box, data, event.player)
end
)
return Public
+132
View File
@@ -0,0 +1,132 @@
local Storage = require("modules/exp_util/storage")
local mod_gui = require "mod-gui"
local Gui = {}
local data = {}
local uid = 0
Storage.register(
data,
function(tbl)
data = tbl
end
)
function Gui.uid_name()
uid = uid + 1
return "Redmew_" .. uid
end
-- Associates data with the LuaGuiElement. If data is nil then removes the data
function Gui.set_data(element, value)
data[element.player_index * 0x100000000 + element.index] = value
end
-- Gets the Associated data with this LuaGuiElement if any.
function Gui.get_data(element)
return data[element.player_index * 0x100000000 + element.index]
end
-- Removes data associated with LuaGuiElement and its children recursively.
function Gui.remove_data_recursively(element)
Gui.set_data(element, nil)
local children = element.children
if not children then
return
end
for _, child in ipairs(children) do
if child.valid then
Gui.remove_data_recursively(child)
end
end
end
function Gui.remove_children_data(element)
local children = element.children
if not children then
return
end
for _, child in ipairs(children) do
if child.valid then
Gui.set_data(child, nil)
Gui.remove_children_data(child)
end
end
end
function Gui.destroy(element)
Gui.remove_data_recursively(element)
element.destroy()
end
function Gui.clear(element)
Gui.remove_children_data(element)
element.clear()
end
Gui.events = {}
local function handler_factory(event_name)
return function(element_name, handler)
Gui.events[defines.events[event_name]] = function(event)
if event.element and event.element.valid and event.element.name == element_name then
event.player = game.players[event.player_index]
handler(event)
end
end
end
end
-- Register a handler for the on_gui_checked_state_changed event for LuaGuiElements with element_name.
-- Can only have one handler per element name.
-- Guarantees that the element and the player are valid when calling the handler.
-- Adds a player field to the event table.
Gui.on_checked_state_changed = handler_factory("on_gui_checked_state_changed")
-- Register a handler for the on_gui_click event for LuaGuiElements with element_name.
-- Can only have one handler per element name.
-- Guarantees that the element and the player are valid when calling the handler.
-- Adds a player field to the event table.
Gui.on_click = handler_factory("on_gui_click")
-- Register a handler for the on_gui_closed event for a custom LuaGuiElements with element_name.
-- Can only have one handler per element name.
-- Guarantees that the element and the player are valid when calling the handler.
-- Adds a player field to the event table.
Gui.on_custom_close = handler_factory("on_gui_closed")
-- Register a handler for the on_gui_elem_changed event for LuaGuiElements with element_name.
-- Can only have one handler per element name.
-- Guarantees that the element and the player are valid when calling the handler.
-- Adds a player field to the event table.
Gui.on_elem_changed = handler_factory("on_gui_elem_changed")
-- Register a handler for the on_gui_selection_state_changed event for LuaGuiElements with element_name.
-- Can only have one handler per element name.
-- Guarantees that the element and the player are valid when calling the handler.
-- Adds a player field to the event table.
Gui.on_selection_state_changed = handler_factory("on_gui_selection_state_changed")
-- Register a handler for the on_gui_text_changed event for LuaGuiElements with element_name.
-- Can only have one handler per element name.
-- Guarantees that the element and the player are valid when calling the handler.
-- Adds a player field to the event table.
Gui.on_text_changed = handler_factory("on_gui_text_changed")
-- Register a handler for the on_gui_value_changed event for LuaGuiElements with element_name.
-- Can only have one handler per element name.
-- Guarantees that the element and the player are valid when calling the handler.
-- Adds a player field to the event table.
Gui.on_value_changed = handler_factory("on_gui_value_changed")
--- Returns the flow where top elements can be added and will be effected by google visibility
-- For the toggle to work it must be registed with Gui.allow_player_to_toggle_top_element_visibility(element_name)
-- @tparam LuaPlayer player pointer to the player who has the gui
-- @treturn LuaGuiElement the top element flow
Gui.get_top_element_flow = mod_gui.get_button_flow
return Gui