Page 1 of 1

Easy gui_element identification

Posted: Sat Aug 15, 2015 11:46 am
by Adil
tldr: on_gui_click event handlers are basically lookup functions written by different people with different degree of quality coding and which sole purpose is to find which ui button from an unknown multitude of those has been pressed. Instead of that: (see the text at the bottom of post)
Initial wallotext Im little ashamed of
3) Just allow handler for a given element be defined in the definition of the element itself.

Re: Easy gui_element identification

Posted: Sun Aug 16, 2015 9:46 pm
by Rseding91
You can compare elements directly:

if (event.element == game.get_player(event.player_index).gui.top.my_gui)

Also, element.name is unique in the element collection it resides (unique in the element.parent.children_names set).

Also also: element.parent points to the element that owns the element which can easily be used to crawl up the parent chain to the root gui element.

Re: Easy gui_element identification

Posted: Mon Aug 17, 2015 5:11 pm
by Adil
Rseding91 wrote:You can compare elements directly:

if (event.element == game.get_player(event.player_index).gui.top.my_gui)
That would actually require a number of nested ifs:

Code: Select all

if ( game.get_player(event.player_index).gui.top.my_gui~=nil) then
   if event.element == game.get_player(event.player_index).gui.top.my_gui.button1 then
   elseif game.get_player(event.player_index).gui.top.my_gui.subgroup1~=nil then
      if event.element == game.get_player(event.player_index).gui.top.my_gui.button2 then
      end
   end
end
Certainly doable, but not very intuitive or motivating to do it this way. The suggestion is about making doing the right thing easier.
Rseding91 wrote:Also, element.name is unique in the element collection it resides
Yes, but you don't know in which collection it resides. Only the full set of (name, parent_name, parent_parent_name,...,your_gui_name (and maybe top/left/center). And as for
Rseding91 wrote:Also also: element.parent points to the element that owns the element which can easily be used to crawl up the parent chain
you don't know the size of the set or the length of the chain for the element stored in event.element. Yes, a function can be written to determine the structure of the chain and the top parent, but once again, that's something that would get reimplemented by each modder, and would be implemented with various degree of correctness.

Re: Easy gui_element identification

Posted: Mon Aug 17, 2015 5:23 pm
by GopherAtl
Adil wrote:
Rseding91 wrote:You can compare elements directly:

if (event.element == game.get_player(event.player_index).gui.top.my_gui)
That would actually require a number of nested ifs:

Code: Select all

if ( game.get_player(event.player_index).gui.top.my_gui~=nil) then
   if event.element == game.get_player(event.player_index).gui.top.my_gui.button1 then
   elseif game.get_player(event.player_index).gui.top.my_gui.subgroup1~=nil then
      if event.element == game.get_player(event.player_index).gui.top.my_gui.button2 then
      end
   end
end
Certainly doable, but not very intuitive or motivating to do it this way. The suggestion is about making doing the right thing easier.
Rseding91 wrote:Also, element.name is unique in the element collection it resides
Yes, but you don't know in which collection it resides. Only the full set of (name, parent_name, parent_parent_name,...,your_gui_name (and maybe top/left/center). And as for
Rseding91 wrote:Also also: element.parent points to the element that owns the element which can easily be used to crawl up the parent chain
you don't know the size of the set or the length of the chain for the element stored in event.element. Yes, a function can be written to determine the structure of the chain and the top parent, but once again, that's something that would get reimplemented by each modder, and would be implemented with various degree of correctness.

Code: Select all


local myHandlers={}

local function myCreateElement(element_def,player_index,side,handler)
   game.players[player_index].gui[side].add(element_def)
  myHandlers[element_def.name]=handler
end

local myGuiHandler(event)
  local handler=myHandlers[event.element]

  if handler then 
     handler(event)
  end
end

function onClickHi(event)
  game.players[event.player_index).print("Hello to you, too.")
end

game.on_event(on_player_created, function(event) 
  myAddElement({type="button" caption="Hi!",name="hi"},event.player_index,"left",handler)
end)
(untested code, but should be basically sound)

You can make it as organized as you want. The api is low-level, and there's actually nothing wrong with if...elseif blocks. You're welcome to not like them, and lua actually makes it pretty esay to avoid them if you want. And as for "different people with different degree of quality coding," well, honestly, if doing some "if...elseif" blocks is taxing their coding skills, well, they're kind of screwed.

Re: Easy gui_element identification

Posted: Mon Aug 17, 2015 9:58 pm
by Rseding91
Gui elements are persistent (saved and restored on load) the current Factorio Lua event system is not. Every time the game is exited and loaded every mod re-registers the event handlers it wants to use with the game.

If Gui elements did the same there net effect wouldn't be any different: you'd still need to know which elements are yours so you could register the handlers. I've seen very complex mods and never seen one have issues with naming the elements or handling events for the elements.