[Rseding] [1.1.30] Opened GUI and controller change edge case

This subforum contains all the issues which we already resolved.
User avatar
Cooldude2606
Fast Inserter
Fast Inserter
Posts: 103
Joined: Sat Sep 16, 2017 9:04 pm
Contact:

[Rseding] [1.1.30] Opened GUI and controller change edge case

Post by Cooldude2606 »

While working on a spectator feature for a scenario, I discovered an edge case where "player.opened" is nil during and after the "on_gui_opened" event.
This edge case occurs when setting a new value for "player.opened" and the "on_gui_closed" event changes the players controller type.
I believe this is a bug because at no point is the value of "player.opened" set to the new value (not during close, during open or after).
I have found a work around for now which is to set "player.opened" to nil before setting your new value. (see ln70 in sample)
This work around suggests that the issue only exists when close and open are called during the same operation.

In the provided sample the case can be reproduced with the commands "/spectate" then "/display message":
Sample Code
The output (in chat) from this sample is shown below. The right hand image shows the output with the work around.
Sample Output
--- Developer for Explosive Gaming and Clusterio. Please contact me via our Discord. ---
User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5286
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: [1.1.30] Opened GUI and controller change edge case

Post by Klonan »

I have narrowed it down, it really isn't anything to do with the events,

Basically, changing the controller will nil out the player.opened
factorio-run_2021-04-15_10-43-32.png
factorio-run_2021-04-15_10-43-32.png (36.13 KiB) Viewed 5264 times
I will leave the rest to Rseding to decide whether it is a bug or not :)
Rseding91
Factorio Staff
Factorio Staff
Posts: 14345
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: [Rseding] [1.1.30] Opened GUI and controller change edge case

Post by Rseding91 »

player.opened getting cleared when switching controllers is intended. No event is sent in that case. The same happens when the target is invalidated (for example the opened entity is killed, destroyed, or just removed through some other means). The event only fires in reaction to the player closing the GUI himself.

I'm not seeing any other weirdness here - unless I missed something. If I did please let me know. Otherwise this seems to be working within the limitations of what the code can do.
If you want to get ahold of me I'm almost always on Discord.
User avatar
Cooldude2606
Fast Inserter
Fast Inserter
Posts: 103
Joined: Sat Sep 16, 2017 9:04 pm
Contact:

Re: [Rseding] [1.1.30] Opened GUI and controller change edge case

Post by Cooldude2606 »

I understand that changing controller will set opened to nil; however, opened is already nil during on_gui_closed and when set_controller is called.
(This is seen in my event output with "During Close spectate_label: nil" and "Before Controller Change: nil")
Therefore, the controler change during the closed event should have no impact on the final value of opened, since the new value has not yet been set.
But it does effect the final value, which causes opened to be nil during on_gui_opened and afterwards; which is why I reported this issue.
--- Developer for Explosive Gaming and Clusterio. Please contact me via our Discord. ---
Rseding91
Factorio Staff
Factorio Staff
Posts: 14345
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: [Rseding] [1.1.30] Opened GUI and controller change edge case

Post by Rseding91 »

I'm having a hard time understanding what you're saying. Can you phrase it in this format?

*what happens*

*what you expect to happen*

So I can reproduce it locally and see why what you expect to happen isn't.
If you want to get ahold of me I'm almost always on Discord.
User avatar
Cooldude2606
Fast Inserter
Fast Inserter
Posts: 103
Joined: Sat Sep 16, 2017 9:04 pm
Contact:

Re: [Rseding] [1.1.30] Opened GUI and controller change edge case

Post by Cooldude2606 »

What to do
Assign a LuaGuiElement to player.opened.
Assign a different LuaGuiElement to player.opened.
During on_gui_closed make a call to LuaPlayer.set_controller.
(I am not sure if the type of controller has an affect)

What happens
on_gui_closed is raised with the first gui element. (as expected)
During on_gui_closed, player.opened is nil. (as expected)
Before the call to set_controller, player.opened is nil. (as expected)
After the call to set_controller, player.opened is nil. (as expected)

on_gui_opened is raised with the second gui element. (as expected)
During on_gui_opened, player.opened is nil. (not expected)
After the assignment, player.opened is nil. (not expected)

Expected
During on_gui_opened, player.opened should be the second LuaGuiElement.
After the assignment, player.opened should be the second LuaGuiElement.

Why is this expected
When set_controller is called, the value of player.opened is already nil. Therefore, the nil assignment from set_controller should have no affect.
When "player.opened = nil" is used in the place of set_controller, the expected result occurs, suggesting the issue lies within set_controller.
When "player.opened = nil" is used before the assignment, the expected result occurs, suggesting the issue lies with the events being called together.
(Assigning nil before assigning my second gui element is my current work around)
--- Developer for Explosive Gaming and Clusterio. Please contact me via our Discord. ---
User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5286
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: [Rseding] [1.1.30] Opened GUI and controller change edge case

Post by Klonan »

It is the same thing, you are basically invalidating the controller during the assignment,
The code

Code: Select all

player.opened = player.gui.center.add(label)
Internally is something like this

Code: Select all

controller = player.get_controller()
new_gui = make_lua_gui(label)
if controller.has_open_gui()
  controller.close_gui({send_events = true})
end
controller.open_gui(new_gui)
However in your case, you set the player to a new controller in the 'close_gui()',
So the 'controller.open_gui()' happens on the old controller.
Rseding91
Factorio Staff
Factorio Staff
Posts: 14345
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: [Rseding] [1.1.30] Opened GUI and controller change edge case

Post by Rseding91 »

Ok, based off what Klonan showed I found the issue and it's now fixed. The fix however is that the "gui opened" event with nil .opened just doesn't happen anymore. Since as he showed; you invalidate the controller during the closed event and so it can't set the new .opened after that happens.
If you want to get ahold of me I'm almost always on Discord.
User avatar
Cooldude2606
Fast Inserter
Fast Inserter
Posts: 103
Joined: Sat Sep 16, 2017 9:04 pm
Contact:

Re: [Rseding] [1.1.30] Opened GUI and controller change edge case

Post by Cooldude2606 »

Thanks for the fix and sorry I wasnt able to explain it well the first time. :)
--- Developer for Explosive Gaming and Clusterio. Please contact me via our Discord. ---
Post Reply

Return to “Resolved Problems and Bugs”