Page 1 of 1

onguiclick-event

Posted: Fri Aug 02, 2013 1:33 pm
by drs9999
At the moment I try to tidy up my blueprints code to make it easier for me to maintain it.

I made some good progress with it, but now I am stuck at the onguiclick event.

It is quite big (nearly 500 lines), I guess I can move some of the code into seperate functions, but in the end it will still look like:

Code: Select all

game.onevent(defines.events.onguiclick, function(event)
  if event.element.name == "button_1" then ...
  elseif  event.element.name == "button_2" then ...
  elseif  event.element.name == "button_3" then ...
  ...
  elseif  event.element.name == "button_100000" then ...
I try to use buttonnames that point out their function more clearly than "button_1", but anyway it is quit hard to find the few lines that are related to one button in the whole event.

So my question is, is there a smarter/cleaner way than the huge if-then-else construct?

EDIT: What I am thinking about is something like this:

Code: Select all

game.onevent(defines.events.onguiclick, function(event)
  if event.element.highestParent == "Frame_A" then foo(event.element.name)
  elseif event.element.highestParent == "Frame_B" then bar(event.element.name)
  ...
  end
With "highestParent" I mean the element that is the child of top/left/center.

Obviously this will not result in less code, but would allow me to move all "button"-codes that belongs to the same UI into seperate functions, which makes it easier to maintain, IMO.

Re: onguiclick-event

Posted: Fri Aug 02, 2013 3:07 pm
by zer0t3ch
This could be of use to you: http://lua-users.org/wiki/SwitchStatement

I suggest starting at the "Simple table of functions" area.

Re: onguiclick-event

Posted: Fri Aug 02, 2013 4:04 pm
by drs9999
Thanks for the link, but I doubt that this will help to make it more readable.
Anyway it was not useless, I am pretty sure that I can use it somewhere else in the code, so thanks again.

Meanwhile I had the following Idea:
Renaming the buttons, so every button that is in UI foo gets the prefix(or suffix) "foo", every button in UI bar gets the prefix "bar" and so on.
When the event is raised the code checks the prefix and calls the related "UI-function" in which it checks which explicit button was clicked.

Of course this approach is more "expensive" in terms of performance, but because the ongui-event is not raised very often, I guess it is not a big deal.

Re: onguiclick-event

Posted: Fri Aug 02, 2013 5:11 pm
by zer0t3ch
drs9999 wrote:-snip- every button that is in UI foo gets the prefix(or suffix) "foo", every button in UI bar gets the prefix "bar" and so on
If you're saying what I think you're saying, a multidimensional array might work a bit better.

Example: (I haven't done LUA in a while, so the syntax may not be correct)
To set

Code: Select all

UI = {
    foo = {
        buttonSubmit,
        buttonCancel
    }
    bar = {
        buttonOk,
        buttonClose
    }
}
And to access, it should be something like this

Code: Select all

UI['foo'][1]
UI['foo'][2]
UI['bar'][1]
UI['bar'][2]
**EDIT
Or this:

Code: Select all

UI[foo][1]
UI[foo][2]
UI[bar][1]
UI[bar][2]

Re: onguiclick-event

Posted: Sat Aug 03, 2013 7:00 am
by drs9999
Hmm I do not understand how this could be helpful here.

Because the onguiclick-event returns the button name, so with your approach I have to search trough all "bottom-level" entries.
Pseudo-Code:

Code: Select all

for all elements in UI do
   for all elements in UI.element do
      if ui.element.button == event.element.name then do something end
   end
end
So I see no advantage here, but maybe I miss something.

I also tried my prefix-idea and it works quiet well.
I did the following:
- all buttons get a 3 letter prefix. E.g "CMS" for all buttons that are part of the blueprint-save-UI, "PMS" for all buttons in the load blueprint UI, etc.
- in the ongui-event I check the buttons prefix and call the related prefix-function
- in the prefix functions I check which button was clicked and call the related functions/ set values etc.

Again, I guess there is no performance-gain, but at least for me it is easier to find things in the code/ maintain them.

Re: onguiclick-event

Posted: Sat Aug 03, 2013 8:02 pm
by zer0t3ch
I was just proposing an idea for prefixing elements, because I thought you were creating your own elements, but I kinda see now.

I haven't really done any factorio modding yet, so I was looking at it from a VERY simplistic LUA standpoint.

Re: onguiclick-event

Posted: Mon Aug 05, 2013 9:55 am
by slpwnd
Just an idea, but you could make a handler for every of your buttons. Then make a table that is indexed by the button names and the values are those functions. Then when the event comes simply lookup the handling function in the table of yours and call it. For this to work properly with serialization you need to have the handler table building code in the onload or even better in the global context of the script.

Re: onguiclick-event

Posted: Mon Aug 05, 2013 6:29 pm
by zer0t3ch
slpwnd wrote:Just an idea, but you could make a handler for every of your buttons. Then make a table that is indexed by the button names and the values are those functions. Then when the event comes simply lookup the handling function in the table of yours and call it. For this to work properly with serialization you need to have the handler table building code in the onload or even better in the global context of the script.
Would something like this work:

Code: Select all

game.onevent(defines.events.onguiclick.element.name.fooButton1, function(event) blah blah blah end)
for just getting a certain button being clicked?

Re: onguiclick-event

Posted: Tue Aug 06, 2013 10:28 am
by slpwnd
zer0t3ch wrote: Would something like this work:

CODE: SELECT ALL
game.onevent(defines.events.onguiclick.element.name.fooButton1, function(event) blah blah blah end)
Nope, at the moment there are no filters implemented for the events subscriptions.

Re: onguiclick-event

Posted: Tue Aug 06, 2013 10:23 pm
by zer0t3ch
slpwnd wrote:
zer0t3ch wrote: Would something like this work:

CODE: SELECT ALL
game.onevent(defines.events.onguiclick.element.name.fooButton1, function(event) blah blah blah end)
Nope, at the moment there are no filters implemented for the events subscriptions.
Damn. Is that planned?

Re: onguiclick-event

Posted: Fri Aug 09, 2013 9:09 am
by slpwnd
zer0t3ch wrote:Damn. Is that planned?
Not really at the moment:| If this gets implemented than it will be mainly for performance reasons - to avoid checking some conditions in (slow) lua, but do it in (fast) c++. Apart from that it is just a "syntactic sugar" for something you guys can already do.