Page 1 of 1

.meta (and .mod?) property on LuaGuiElement

Posted: Sun Aug 28, 2016 6:50 am
by aubergine18
A new .meta property on LuaGuiElement - table or nil (RW).

Mods could associate metadata directly with a GUI element instance. This would make event handling much simpler.

For example, I could have a table like:

Code: Select all

{ mod = 'my_mod', do = 'method_name' }
This stems from an idea I just posted in the modding discussion forum.

In the example above, my mod would be able to instantly identify that a GUI event is related to my mod, and also what to do with it.

For better performance, maybe it would be nice to have a .mod property on gui elements - so mods can check that specific property quickly prior to accessing the .meta property (which would often contain quite a bit more data to typecast from C to Lua).

The first line in any GUI-related event handler would be:

Code: Select all

if event.element.mod ~= 'my_mod' then return end
Maybe Factorio could expose the element.mod property as a property on `event` for even faster lookup?

Code: Select all

if event.mod ~= 'my_mod' then return end
It still leaves the door open for other mods to also process the event (it's not forcing events to a specifc mod), it's backwards compatible, it helps eradicate unwieldy global lookup tables, etc.

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Sun Aug 28, 2016 7:23 am
by aubergine18
Addendum: Also add a .find() method on the LuaGui elements (top, left, center) for quickly locating a GUI element:

Code: Select all

--example
game.player.gui.top.find{ type=..., mod=..., meta={ prop=val, ... }, name=..., style=..., etc... }
Returns array table of matching elements, or nil if none found.

All search params optional. If none specified, return a list of all GUI elements in the scope.

This would also remove a lot of pain if a mod update has completely refactored UI - it could just find any existing GUI elements and destroy them in simple loop:

Code: Select all

for player in pairs(game.players) do
  local oldGUI = game.players[player].gui.top.find { mod='my_mod' }
  if oldGUI then
    for _,element in pairs(oldGUI) do
      if element.valid then element.destroy() end
    end
  end
end
A `parent = guiElement` param could be used to limit scope of search, for example I might only want to search stuff within a specific grid (table element) within my UI.

Another use case is finding all selected checkboxes, or all buttons with specific style.

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Fri Sep 02, 2016 5:25 am
by Mooncat
About event handling, I prefer adding the handler directly inside LuaGuiElement::add
Example:

Code: Select all

player.gui.left.add{type = "button", name = "just_a_button", caption = "Dare to click me?", on_click = function(event)
    game.players[event.player_index].print("Woah!? You really clicked me!?")
end}
If possible, 2 methods can also be introduced for convenience:
LuaGuiElement::addEventListener(string, function(event))
LuaGuiElement::removeEventListener(string, function(event))
Example:

Code: Select all

local function on_just_a_button_clicked(event)
    game.players[event.player_index].print("Woah!? You really clicked me!?")
    event.element.caption = "This button is dead."
    event.element.removeEventListener(defines.events.on_gui_click, on_just_a_button_clicked)
end)

local button = player.gui.left.add{type = "button", name = "just_a_button", caption = "Dare to click me?"}
button.addEventListener(defines.events.on_gui_click, on_just_a_button_clicked)
Just like how ActionScript 3.0 is doing.
(Also the same as my suggestion about entity events: Register entity-related events in entity instead of script)

I have seen mods that have their own GUI helper class for mapping GUI elements to the corresponding event handlers. But I feel dirty about that.

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Fri Sep 02, 2016 7:35 pm
by Rseding91
One large issue with event handlers per GUI element: they aren't persisted between save/load. So, you'd still need to re-setup all of them on_load which means you still need to know what each element is and what it's meant to be doing.

Adding .mod to read which mod owns which widget wouldn't be hard to do - I'll add that.

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Fri Sep 02, 2016 8:30 pm
by Mooncat
Oh, didn't think of that.

To me, there will be no problem to re-setup the event handlers, because I will just destroy the GUI and reconstruct it. :P
But I understand that not all people like this.

Out of curiosity, since "game" is not accessible in on_load, hence we can't use game.players, how would you iterate the GUI for each player?

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Fri Sep 02, 2016 9:20 pm
by Rseding91
Mooncat wrote:Oh, didn't think of that.

To me, there will be no problem to re-setup the event handlers, because I will just destroy the GUI and reconstruct it. :P
But I understand that not all people like this.

Out of curiosity, since "game" is not accessible in on_load, hence we can't use game.players, how would you iterate the GUI for each player?
You wouldn't and can't. That's another reason this wouldn't work :P

Also destroying and re-creating the GUI on_load would desync everything and also doesn't work because you don't have access to game to re-create the GUI elements.

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Fri Sep 02, 2016 9:29 pm
by Mooncat
oh... ok :lol:

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Sun Sep 04, 2016 2:47 am
by mickael9
If a mod property is going to be added, I have to ask, what's the point in keeping GUI items from uninstalled mods?

Currently, if you remove a mod that still has a GUI open then you're left with that GUI "forever" with "Unknown key" goodness everywhere (unless you load the mod again and close the GUI manually of course).

On multiplayer this is worse because potentially each user would have to do that. It's still possible to close it using /c but in my opinion an user should not have to do that.

If a mod property is added, wouldn't it make sense for the game to use it and simply destroy every GUI element that's owned by an uninstalled mod?

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Sun Sep 04, 2016 4:44 am
by Rseding91
mickael9 wrote:If a mod property is going to be added, I have to ask, what's the point in keeping GUI items from uninstalled mods?

Currently, if you remove a mod that still has a GUI open then you're left with that GUI "forever" with "Unknown key" goodness everywhere (unless you load the mod again and close the GUI manually of course).

On multiplayer this is worse because potentially each user would have to do that. It's still possible to close it using /c but in my opinion an user should not have to do that.

If a mod property is added, wouldn't it make sense for the game to use it and simply destroy every GUI element that's owned by an uninstalled mod?
The game is meant to remove mod GUIs when the mod is removed. If you can reproduce the GUI getting left behind with a new map + mod please make a bug report with the steps how to do so.

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Sun Sep 04, 2016 6:42 am
by Mooncat
I didn't know the game can remove mod GUI automatically. :o
Right now, my 0.13 -> 0.14 save has some undefined GUI because some mods don't support 0.14 yet. I will submit a bug report with a simple mod if it can reproduce it.

Edit: after a simple test, the GUI was automatically removed after I removed the mod. Maybe there is a problem when loading a 0.13 save in 0.14? Going to test again. ;)

Edit2: Yes! The GUI was left in the game if the mod became incompatible with Factorio (mod is red). And I have done a third test: if I disable the mod (gray), but keeping it in the mod directory, the GUI is removed correctly. A little bit inconsistent since the mod is disabled in both cases, but is it intentional, to let player upgrade the mod?

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Sun Sep 04, 2016 2:33 pm
by Rseding91
Mooncat wrote:I didn't know the game can remove mod GUI automatically. :o
Right now, my 0.13 -> 0.14 save has some undefined GUI because some mods don't support 0.14 yet. I will submit a bug report with a simple mod if it can reproduce it.

Edit: after a simple test, the GUI was automatically removed after I removed the mod. Maybe there is a problem when loading a 0.13 save in 0.14? Going to test again. ;)

Edit2: Yes! The GUI was left in the game if the mod became incompatible with Factorio (mod is red). And I have done a third test: if I disable the mod (gray), but keeping it in the mod directory, the GUI is removed correctly. A little bit inconsistent since the mod is disabled in both cases, but is it intentional, to let player upgrade the mod?
Can you reproduce the 0.13 -> 0.14 issue with a new save in 0.13 + a mod then migrating to 0.14? If so, please make a bug report with those steps.

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Sun Sep 04, 2016 2:49 pm
by Mooncat
Rseding91 wrote:Can you reproduce the 0.13 -> 0.14 issue with a new save in 0.13 + a mod then migrating to 0.14? If so, please make a bug report with those steps.
Just to make sure: did you mean only migrate the save to 0.14 but keep the mod for 0.13? If so, I can reproduce it. :)
But if you meant also migrate the mod to 0.14, then there is no issue. The issue occurs only when mod is not compatible with updated Factorio.

Edit: oh, I made a mistake. Although the mod was incompatible, its status in the mod list was still "Enabled". So I think it is not a bug at all? :P

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Sun Sep 04, 2016 3:07 pm
by Rseding91
Mooncat wrote:
Rseding91 wrote:Can you reproduce the 0.13 -> 0.14 issue with a new save in 0.13 + a mod then migrating to 0.14? If so, please make a bug report with those steps.
Just to make sure: did you mean only migrate the save to 0.14 but keep the mod for 0.13? If so, I can reproduce it. :)
But if you meant also migrate the mod to 0.14, then there is no issue. The issue occurs only when mod is not compatible with updated Factorio.

Edit: oh, I made a mistake. Although the mod was incompatible, its status in the mod list was still "Enabled". So I think it is not a bug at all? :P
Which version of 0.14 are you using to test?

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Sun Sep 04, 2016 3:08 pm
by Mooncat
Rseding91 wrote:Which version of 0.14 are you using to test?
0.13.20 -> 0.14.3

Re: .meta (and .mod?) property on LuaGuiElement

Posted: Sun Sep 04, 2016 3:14 pm
by Mooncat
Preparing screenshots for the bug report:
Started game in 0.13.20
Prepare to load game in 0.14.3
Loaded game in 0.14.3
Edit: here is the bug report - viewtopic.php?f=7&t=32196&p=203022