1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-08 00:39:30 +02:00
ComfyFactorio/utils/gui.lua

337 lines
9.7 KiB
Lua
Raw Normal View History

2019-02-26 21:25:59 +02:00
local Token = require 'utils.token'
2018-09-19 06:51:25 +02:00
local Event = require 'utils.event'
2019-02-26 21:25:59 +02:00
local Global = require 'utils.global'
2020-12-14 20:36:37 +02:00
local SpamProtection = require 'utils.spam_protection'
2021-10-23 00:04:48 +02:00
local mod_gui = require('__core__/lualib/mod-gui')
2018-09-19 06:51:25 +02:00
2020-07-25 17:22:04 +02:00
local tostring = tostring
local next = next
2018-09-19 06:51:25 +02:00
local Gui = {}
2019-02-26 21:25:59 +02:00
local data = {}
2020-07-25 17:22:04 +02:00
local element_map = {}
2021-05-23 17:03:52 +02:00
local settings = {}
2018-09-19 06:51:25 +02:00
2020-07-25 17:22:04 +02:00
Gui.token =
Global.register(
2021-05-23 17:03:52 +02:00
{data = data, element_map = element_map, settings = settings},
2019-02-26 21:25:59 +02:00
function(tbl)
2020-07-25 17:22:04 +02:00
data = tbl.data
element_map = tbl.element_map
2021-05-23 17:03:52 +02:00
settings = tbl.settings
2018-09-19 06:51:25 +02:00
end
2019-02-26 21:25:59 +02:00
)
local on_visible_handlers = {}
local on_pre_hidden_handlers = {}
function Gui.uid_name()
2021-04-04 13:51:27 +02:00
return tostring(Token.uid())
2018-09-19 06:51:25 +02:00
end
2020-08-31 20:37:27 +02:00
function Gui.uid()
return Token.uid()
end
2018-09-19 06:51:25 +02:00
-- Associates data with the LuaGuiElement. If data is nil then removes the data
2019-02-26 21:25:59 +02:00
function Gui.set_data(element, value)
2020-07-25 17:22:04 +02:00
local player_index = element.player_index
local values = data[player_index]
if value == nil then
if not values then
return
end
2021-04-04 13:51:27 +02:00
values[element.index] = nil
2020-07-25 17:22:04 +02:00
if next(values) == nil then
data[player_index] = nil
end
else
if not values then
values = {}
data[player_index] = values
end
2021-04-04 13:51:27 +02:00
values[element.index] = value
2020-07-25 17:22:04 +02:00
end
2018-09-19 06:51:25 +02:00
end
2020-07-25 17:22:04 +02:00
local set_data = Gui.set_data
2018-09-19 06:51:25 +02:00
-- Gets the Associated data with this LuaGuiElement if any.
function Gui.get_data(element)
2021-06-06 20:14:26 +02:00
if not element then
return
end
2020-07-25 17:22:04 +02:00
local player_index = element.player_index
local values = data[player_index]
if not values then
return nil
end
return values[element.index]
2018-09-19 06:51:25 +02:00
end
2020-07-25 17:22:04 +02:00
local remove_data_recursively
2019-02-26 21:25:59 +02:00
-- Removes data associated with LuaGuiElement and its children recursively.
function Gui.remove_data_recursively(element)
2020-07-25 17:22:04 +02:00
set_data(element, nil)
2018-09-19 06:51:25 +02:00
local children = element.children
if not children then
return
end
2020-07-25 17:22:04 +02:00
for _, child in next, children do
2018-09-19 06:51:25 +02:00
if child.valid then
2020-07-25 17:22:04 +02:00
remove_data_recursively(child)
2018-09-19 06:51:25 +02:00
end
end
end
2020-07-25 17:22:04 +02:00
remove_data_recursively = Gui.remove_data_recursively
2018-09-19 06:51:25 +02:00
2020-07-25 17:22:04 +02:00
local remove_children_data
2018-09-19 06:51:25 +02:00
function Gui.remove_children_data(element)
local children = element.children
if not children then
return
end
2020-07-25 17:22:04 +02:00
for _, child in next, children do
2018-09-19 06:51:25 +02:00
if child.valid then
2020-07-25 17:22:04 +02:00
set_data(child, nil)
remove_children_data(child)
2018-09-19 06:51:25 +02:00
end
end
end
2020-07-25 17:22:04 +02:00
remove_children_data = Gui.remove_children_data
2018-09-19 06:51:25 +02:00
function Gui.destroy(element)
2020-07-25 17:22:04 +02:00
remove_data_recursively(element)
2018-09-19 06:51:25 +02:00
element.destroy()
end
function Gui.clear(element)
2020-07-25 17:22:04 +02:00
remove_children_data(element)
2018-09-19 06:51:25 +02:00
element.clear()
end
2021-05-23 17:03:52 +02:00
local function clear_invalid_data()
if settings.disable_clear_invalid_data then
return
end
for _, player in pairs(game.players) do
2020-09-12 19:16:38 +02:00
local player_index = player.index
local values = data[player_index]
if values then
2021-05-23 17:03:52 +02:00
for k, element in next, values do
2020-09-12 19:16:38 +02:00
if type(element) == 'table' then
for key, obj in next, element do
if type(obj) == 'table' and obj.valid ~= nil then
if not obj.valid then
element[key] = nil
end
end
end
2021-05-23 17:03:52 +02:00
if type(element) == 'userdata' and not element.valid then
values[k] = nil
end
2020-09-12 19:16:38 +02:00
end
end
end
end
end
Event.on_nth_tick(300, clear_invalid_data)
2018-09-19 06:51:25 +02:00
local function handler_factory(event_id)
local handlers
local function on_event(event)
local element = event.element
if not element or not element.valid then
return
end
local handler = handlers[element.name]
if not handler then
return
end
2020-07-25 17:22:04 +02:00
local player = game.get_player(event.player_index)
2020-12-14 20:36:37 +02:00
if not (player and player.valid) then
2018-09-19 06:51:25 +02:00
return
end
2021-01-12 22:52:45 +02:00
if not event.text then
local is_spamming = SpamProtection.is_spamming(player, nil, 'UtilsGUI Handler')
if is_spamming then
return
end
2020-12-14 20:36:37 +02:00
end
2018-09-19 06:51:25 +02:00
event.player = player
handler(event)
end
return function(element_name, handler)
if not handlers then
handlers = {}
Event.add(event_id, on_event)
end
handlers[element_name] = handler
end
end
2019-02-26 21:25:59 +02:00
local function custom_handler_factory(handlers)
return function(element_name, handler)
handlers[element_name] = handler
end
end
2021-03-24 21:14:55 +02:00
--luacheck: ignore custom_raise
2019-02-26 21:25:59 +02:00
local function custom_raise(handlers, element, player)
local handler = handlers[element.name]
if not handler then
return
end
handler({element = element, player = player})
end
2021-05-23 17:03:52 +02:00
-- Disabled the handler so it does not clean then data table of invalid data.
function Gui.set_disable_clear_invalid_data(value)
settings.disable_clear_invalid_data = value or false
end
-- Gets state if the cleaner handler is active or false
function Gui.get_disable_clear_invalid_data()
return settings.disable_clear_invalid_data
end
2018-09-19 06:51:25 +02:00
-- 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(defines.events.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(defines.events.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(defines.events.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(defines.events.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(defines.events.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(defines.events.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(defines.events.on_gui_value_changed)
2019-02-26 21:25:59 +02:00
-- Register a handler for when the player shows the top LuaGuiElements with element_name.
-- Assuming the element_name has been added with Gui.allow_player_to_toggle_top_element_visibility.
-- 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_player_show_top = custom_handler_factory(on_visible_handlers)
-- Register a handler for when the player hides the top LuaGuiElements with element_name.
-- Assuming the element_name has been added with Gui.allow_player_to_toggle_top_element_visibility.
-- 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_pre_player_hide_top = custom_handler_factory(on_pre_hidden_handlers)
2021-04-04 13:51:27 +02:00
if _DEBUG then
local concat = table.concat
local names = {}
Gui.names = names
function Gui.uid_name()
local info = debug.getinfo(2, 'Sl')
local filepath = info.source:match('^.+/currently%-playing/(.+)$'):sub(1, -5)
local line = info.currentline
2019-02-26 21:25:59 +02:00
2021-04-04 13:51:27 +02:00
local token = tostring(Token.uid())
local name = concat {token, ' - ', filepath, ':line:', line}
names[token] = name
return token
end
function Gui.set_data(element, value)
local player_index = element.player_index
local values = data[player_index]
if value == nil then
if not values then
return
end
local index = element.index
values[index] = nil
element_map[index] = nil
if next(values) == nil then
data[player_index] = nil
end
else
if not values then
values = {}
data[player_index] = values
end
local index = element.index
values[index] = value
element_map[index] = element
end
end
set_data = Gui.set_data
function Gui.data()
return data
end
function Gui.element_map()
return element_map
end
2021-03-28 17:01:39 +02:00
end
2021-04-04 13:51:27 +02:00
2021-10-23 00:04:48 +02:00
Gui.get_button_flow = mod_gui.get_button_flow
Gui.mod_button = mod_gui.get_button_flow
2018-09-19 06:51:25 +02:00
return Gui