From 51480e4ca5e2716450d1889fb43181e1fe275431 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Sun, 1 Oct 2023 22:40:49 +0100 Subject: [PATCH] Update core files --- expcore/gui/core_defines.lua | 10 +++-- expcore/gui/left_flow.lua | 1 + expcore/gui/prototype.lua | 74 +++++++++++++++++++++++++----------- expcore/gui/top_flow.lua | 4 +- 4 files changed, 62 insertions(+), 27 deletions(-) diff --git a/expcore/gui/core_defines.lua b/expcore/gui/core_defines.lua index 50e3ec09..272adab7 100644 --- a/expcore/gui/core_defines.lua +++ b/expcore/gui/core_defines.lua @@ -16,7 +16,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/preset', style = 'tool_button', - tooltip = {'gui_util.button_tooltip'} + tooltip = {'gui_util.button_tooltip'}, + name = Gui.unique_static_name } :style{ padding = -2, @@ -35,7 +36,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/preset', style = 'tool_button', - tooltip = {'gui_util.button_tooltip'} + tooltip = {'gui_util.button_tooltip'}, + name = Gui.unique_static_name } :style{ padding = -2, @@ -54,7 +56,8 @@ Gui.element{ type = 'sprite-button', sprite = 'utility/close_black', style = 'tool_button', - tooltip = {'expcore-gui.left-button-tooltip'} + tooltip = {'expcore-gui.left-button-tooltip'}, + name = Gui.unique_static_name } :style{ padding = -3, @@ -83,5 +86,4 @@ Event.add(defines.events.on_player_created, function(event) show_top.visible = false hide_left.visible = false Gui.draw_left_flow(player) - end) \ No newline at end of file diff --git a/expcore/gui/left_flow.lua b/expcore/gui/left_flow.lua index 42f02655..5f780304 100644 --- a/expcore/gui/left_flow.lua +++ b/expcore/gui/left_flow.lua @@ -38,6 +38,7 @@ example_flow_with_button:add_to_left_flow(true) ]] function Gui._prototype_element:add_to_left_flow(open_on_join) + if not self.name then error("Elements for the top flow must have a static name") end Gui.left_elements[self.name] = open_on_join or false return self end diff --git a/expcore/gui/prototype.lua b/expcore/gui/prototype.lua index 8bd7a644..ed77f293 100644 --- a/expcore/gui/prototype.lua +++ b/expcore/gui/prototype.lua @@ -8,24 +8,31 @@ local Event = require 'utils.event' --- @dep utils.event local Gui = { --- The current highest uid that is being used by a define, will not increase during runtime uid = 0, + --- Used to automatically assign a unique static name to an element + unique_static_name = {}, --- String indexed table used to avoid conflict with custom event names, similar to how defines.events works events = {}, --- Uid indexed array that stores all the factory functions that were defined, no new values will be added during runtime defines = {}, - --- An string indexed table of all the defines which are used by the core of the gui system, used for internal refrence + --- An string indexed table of all the defines which are used by the core of the gui system, used for internal reference core_defines = {}, - --- Used to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debuging + --- Used to store the file names where elements were defined, this can be useful to find the uid of an element, mostly for debugging file_paths = {}, - --- Used to store extra infomation about elements as they get defined such as the params used and event handlers registered to them + --- Used to store extra information about elements as they get defined such as the params used and event handlers registered to them debug_info = {}, --- The prototype used to store the functions of an element define _prototype_element = {}, --- The prototype metatable applied to new element defines _mt_element = { __call = function(self, parent, ...) - local element = self._draw(self.name, parent, ...) + local element = self._draw(self, parent, ...) if self._style then self._style(element.style, element, ...) end - return element + return self:triggers_events(element) + end, + __index = function(self, key) + if self._draw_data then + return self._draw_data[key] + end end } } @@ -76,32 +83,35 @@ end) ]] function Gui.element(element_define) + _C.error_if_runtime() -- Set the metatable to allow access to register events local element = setmetatable({}, Gui._mt_element) -- Increment the uid counter local uid = Gui.uid + 1 Gui.uid = uid - local name = tostring(uid) - element.name = name - Gui.debug_info[name] = { draw = 'None', style = 'None', events = {} } + element.uid = uid + Gui.debug_info[uid] = { draw = 'None', style = 'None', events = {} } - -- Add the defination function + -- Add the definition function if type(element_define) == 'table' then - Gui.debug_info[name].draw = element_define - element_define.name = name + Gui.debug_info[uid].draw = element_define + if element_define.name == Gui.unique_static_name then + element_define.name = "ExpGui_"..tostring(uid) + end + element._draw_data = element_define element._draw = function(_, parent) return parent.add(element_define) end else - Gui.debug_info[name].draw = 'Function' + Gui.debug_info[uid].draw = 'Function' element._draw = element_define end -- Add the define to the base module local file_path = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5) - Gui.file_paths[name] = file_path - Gui.defines[name] = element + Gui.file_paths[uid] = file_path + Gui.defines[uid] = element -- Return the element so event handers can be accessed return element @@ -143,16 +153,16 @@ end) ]] function Gui._prototype_element:style(style_define) - -- Add the defination function + -- Add the definition function if type(style_define) == 'table' then - Gui.debug_info[self.name].style = style_define + Gui.debug_info[self.uid].style = style_define self._style = function(style) for key, value in pairs(style_define) do style[key] = value end end else - Gui.debug_info[self.name].style = 'Function' + Gui.debug_info[self.uid].style = 'Function' self._style = style_define end @@ -160,6 +170,21 @@ function Gui._prototype_element:style(style_define) return self end +--[[-- Used to link an element to an element define such that any event on the element will call the handlers on the element define +@tparam LuaGuiElement element The element that will trigger calls to the event handlers +@treturn LuaGuiElement The element passed as the argument to allow for cleaner returns +]] +function Gui._prototype_element:triggers_events(element) + local event_triggers = element.tags.ExpGuiTriggers + if not event_triggers then + event_triggers = { self.uid } + else + table.insert(event_triggers, self.uid) + end + -- To modify a set of tags, the whole table needs to be written back to the respective property. + element.tags.ExpGuiTriggers = event_triggers +end + --[[-- Set the handler which will be called for a custom event, only one handler can be used per event per element @tparam string event_name the name of the event you want to handler to be called on, often from Gui.events @tparam function handler the handler that you want to be called when the event is raised @@ -172,7 +197,7 @@ end) ]] function Gui._prototype_element:on_custom_event(event_name, handler) - table.insert(Gui.debug_info[self.name].events, event_name) + table.insert(Gui.debug_info[self.uid].events, event_name) Gui.events[event_name] = event_name self[event_name] = handler return self @@ -222,13 +247,18 @@ local function event_handler_factory(event_name) Event.add(event_name, function(event) local element = event.element if not element or not element.valid then return end - local element_define = Gui.defines[element.name] - if not element_define then return end - element_define:raise_custom_event(event) + local event_triggers = element.tags.ExpGuiTriggers + if not event_triggers then return end + for _, uid in event_triggers do + local element_define = Gui.defines[uid] + if not element_define then + element_define:raise_custom_event(event) + end + end end) return function(self, handler) - table.insert(Gui.debug_info[self.name].events, debug.getinfo(1, "n").name) + table.insert(Gui.debug_info[self.uid].events, debug.getinfo(1, "n").name) self[event_name] = handler return self end diff --git a/expcore/gui/top_flow.lua b/expcore/gui/top_flow.lua index 064ee906..dd8f8070 100644 --- a/expcore/gui/top_flow.lua +++ b/expcore/gui/top_flow.lua @@ -48,6 +48,7 @@ end) ]] function Gui._prototype_element:add_to_top_flow(authenticator) + if not self.name then error("Elements for the top flow must have a static name") end Gui.top_elements[self.name] = authenticator or true return self end @@ -138,7 +139,8 @@ function Gui.toolbar_button(sprite, tooltip, authenticator) type = 'sprite-button', sprite = sprite, tooltip = tooltip, - style = Gui.top_flow_button_style + style = Gui.top_flow_button_style, + name = Gui.unique_static_name } :style{ minimal_width = 36,