Page 1 of 2
Event System in STDLIB
Posted: Fri Aug 26, 2016 9:26 pm
by kiba
I am trying to make use of the stdlib by Afforess, but I have no idea how to use its event system.
I discussed this on the stdlib's
thread but nobody responded.
Code: Select all
function test()
print("test")
end
Gui.Event.register (defines.events.on_player_armor_inventory_changed, "top", test)
Looking through the stdlib's source code, I am not clear on how the game check for events being pinged? Though Gui.Event.dispatch?
Re: Event System in STDLIB
Posted: Fri Aug 26, 2016 9:29 pm
by Supercheese
From what I can tell, the StdLib forms a list of all events, and assigns them each only a single function, initially just a null function that does nothing. When you call register() on that event, your code gets added to that event-function, and will run each time the event fires. In this fashion, you could have multiple functions that are independently registered and de-registered from an event -- so maybe sometimes you want this part of on_tick to run, so you register it, then later you want another part, so you register that, but later you de-register the first bit, so it stops running while the second bit still goes. It's a bit tricky at times, but can be helpful for performance under certain circumstances.
EDIT: Also, you call register() with only two arguments, not three. See:
http://afforess.github.io/Factorio-Stdl ... Event.html
Re: Event System in STDLIB
Posted: Fri Aug 26, 2016 9:41 pm
by kiba
Supercheese wrote:From what I can tell, the StdLib forms a list of all events, and assigns them each only a single function, initially just a null function that does nothing. When you call register() on that event, your code gets added to that event-function, and will run each time the event fires. In this fashion, you could have multiple functions that are independently registered and de-registered from an event -- so maybe sometimes you want this part of on_tick to run, so you register it, then later you want another part, so you register that, but later you de-register the first bit, so it stops running while the second bit still goes. It's a bit tricky at times, but can be helpful for performance under certain circumstances.
EDIT: Also, you call register() with only two arguments, not three. See:
http://afforess.github.io/Factorio-Stdl ... Event.html
So I can only have one event handler active at any given time?
Edit: I am looking at the GUI stuff, not the event stuff. That's why there's three.
Re: Event System in STDLIB
Posted: Fri Aug 26, 2016 9:51 pm
by Choumiko
kiba wrote:
Gui.Event.register (defines.events.on_player_armor_inventory_changed, "top", test)
[/code]
This looks more like a mix between the gui events and the others.
For non gui events it is
Code: Select all
Event.register(defines.events.on_player_armor_inventory_changed, test)
Event.register lets you register mutliple functions for a single event and let's you remove them individually, as Supercheese described
Haven't used the GUI events from stdlib yet, but
Code: Select all
Gui.on_click("button_name", test) --(Gui.on_click is short for Gui.Event.register(defines.events.on_gui_click, test)
should call the function if a gui element named button_name is clicked
Gui.Event.register() can have multiple patterns assigned per event, but only one handler/function per pattern. (I might be wrong about this, didn't write the Gui.Event)
Re: Event System in STDLIB
Posted: Fri Aug 26, 2016 10:08 pm
by kiba
Choumiko wrote:kiba wrote:
Gui.Event.register (defines.events.on_player_armor_inventory_changed, "top", test)
[/code]
This looks more like a mix between the gui events and the others.
For non gui events it is
Code: Select all
Event.register(defines.events.on_player_armor_inventory_changed, test)
Event.register lets you register mutliple functions for a single event and let's you remove them individually, as Supercheese described
Haven't used the GUI events from stdlib yet, but
Code: Select all
Gui.on_click("button_name", test) --(Gui.on_click is short for Gui.Event.register(defines.events.on_gui_click, test)
should call the function if a gui element named button_name is clicked
Gui.Event.register() can have multiple patterns assigned per event, but only one handler/function per pattern. (I might be wrong about this, didn't write the Gui.Event)
Ah, my problem is trying to register "gui.top" rather than creating an element for it, before I could register it toward a GUI element?
Re: Event System in STDLIB
Posted: Sat Aug 27, 2016 1:19 pm
by Choumiko
kiba wrote:Ah, my problem is trying to register "gui.top" rather than creating an element for it, before I could register it toward a GUI element?
I'm not sure what you want to achieve, but if by gui.top you mean e.g. game.players[1].gui.top then it should look like
This should call test() when you click the frame top (if that is even firing an event/can be clicked)
You can register any kind of string as a pattern, the element doesn't have to exist at time of registration.
Re: Event System in STDLIB
Posted: Sat Aug 27, 2016 11:04 pm
by aubergine18
If I understand correctly, the main GUI areas (top, left, center) are just flows and thus won't generate any gui click events. You'd have to have a button, checkbox or some other event-generating gui element in there and listen for that being clicked.
Re: Event System in STDLIB
Posted: Thu Sep 01, 2016 9:10 pm
by kiba
I simplified the code, but I still haven't figure out why it isn't working or triggering.
Code: Select all
function test()
LOG.log("asdf_asdf")
LOG.write()
print("test")
end
Event.register (defines.events.on_player_armor_inventory_changed, test)
Re: Event System in STDLIB
Posted: Fri Sep 02, 2016 6:47 am
by Nexela
I use the events system all over without a problem. not sure why your example isn't working.
Code: Select all
Event=require("stdlib.event.event")
local function do_once_tick(event)
for _, player in pairs(game.players) do
player.print("Once")
end
Event.remove(defines.events.on_tick, do_once_tick)
end
Event.register(defines.events.on_tick, do_once_tick)
Re: Event System in STDLIB
Posted: Fri Sep 02, 2016 8:00 pm
by Rseding91
Just wondering, what's the advantage to aliasing script.on_event(...)?
To me, it seems like it's just going to obscure the code so someone else doesn't understand what's happening compared to just registering the events directly. It will also be ever so slightly slower because it has to do more function calls.
Re: Event System in STDLIB
Posted: Fri Sep 02, 2016 8:01 pm
by Rseding91
Nexela wrote:I use the events system all over without a problem. not sure why your example isn't working.
Code: Select all
Event=require("stdlib.event.event")
local function do_once_tick(event)
for _, player in pairs(game.players) do
player.print("Once")
end
Event.remove(defines.events.on_tick, do_once_tick)
end
Event.register(defines.events.on_tick, do_once_tick)
Also there's no way this is MP safe since it would end up running every time someone connected/loaded a game.
Re: Event System in STDLIB
Posted: Fri Sep 02, 2016 8:10 pm
by Nexela
That was example code :p
Re: Event System in STDLIB
Posted: Fri Sep 02, 2016 8:13 pm
by Rseding91
Nexela wrote:That was example code :p
Sure, but any such "fire once" system isn't going to be save-load stable since you can't save/load closures and it isn't going to fire that event until the next tick.
If you tell it "fire on next tick" and then the game is saved and exited that same tick it won't happen.
Re: Event System in STDLIB
Posted: Sun Sep 04, 2016 12:59 am
by kiba
Rseding91 wrote:Just wondering, what's the advantage to aliasing script.on_event(...)?
To me, it seems like it's just going to obscure the code so someone else doesn't understand what's happening compared to just registering the events directly. It will also be ever so slightly slower because it has to do more function calls.
I am not exactly sure myself. Supposedly, the advantage of using Afforess' stdlib is that I don't have to do so much gruntwork.
From what I peeked, it seems that there's a lot of code that do things but I don't know what exactly it do.
Re: Event System in STDLIB
Posted: Fri Sep 30, 2016 3:32 am
by Afforess
Rseding91 wrote:Just wondering, what's the advantage to aliasing script.on_event(...)?
To me, it seems like it's just going to obscure the code so someone else doesn't understand what's happening compared to just registering the events directly. It will also be ever so slightly slower because it has to do more function calls.
Main advantage is multiple handlers per event, and ability to deregister by handler, as well as built-in error handling.
Sorry about the slow response, hopefully you've figured things out by now Kiba.
Re: Event System in STDLIB
Posted: Fri Sep 30, 2016 4:35 am
by Rseding91
Afforess wrote:Rseding91 wrote:Just wondering, what's the advantage to aliasing script.on_event(...)?
To me, it seems like it's just going to obscure the code so someone else doesn't understand what's happening compared to just registering the events directly. It will also be ever so slightly slower because it has to do more function calls.
Main advantage is multiple handlers per event, and ability to deregister by handler, as well as built-in error handling.
Sorry about the slow response, hopefully you've figured things out by now Kiba.
How are the event handlers persisted through save-load? And if not, how are the order of the registered events maintained if mods have to re-register on_load?
Re: Event System in STDLIB
Posted: Fri Sep 30, 2016 9:18 pm
by Afforess
Rseding91 wrote:
How are the event handlers persisted through save-load? And if not, how are the order of the registered events maintained if mods have to re-register on_load?
They aren't, persisting closures is complex and generally not useful. The order is deterministic because event handlers are registered when the lua files are loaded, exactly how the script.on_event handlers are registered now. The Stdlib handlers just wrap those handlers with a table to allow multiple registration.
If it makes it more clear, stdlib event handlers *are* just wrappers. You can do a strict find-and-replace in a text editor, and replace script.on_event with Event.register, and your code will work exactly like before.
Re: Event System in STDLIB
Posted: Fri Sep 30, 2016 10:06 pm
by Rseding91
Afforess wrote:Rseding91 wrote:
How are the event handlers persisted through save-load? And if not, how are the order of the registered events maintained if mods have to re-register on_load?
They aren't, persisting closures is complex and generally not useful. The order is deterministic because event handlers are registered when the lua files are loaded, exactly how the script.on_event handlers are registered now. The Stdlib handlers just wrap those handlers with a table to allow multiple registration.
If it makes it more clear, stdlib event handlers *are* just wrappers. You can do a strict find-and-replace in a text editor, and replace script.on_event with Event.register, and your code will work exactly like before.
That's assuming people use it like that. Some register event handlers conditionally. For example: runtime the player builds something and that activates the on_tick handler for say 30 seconds and then it turns off again.
Not sure if anyone does that with this library system but it's just something to think about

Re: Event System in STDLIB
Posted: Fri Sep 30, 2016 11:18 pm
by Afforess
Rseding91 wrote:Afforess wrote:Rseding91 wrote:
How are the event handlers persisted through save-load? And if not, how are the order of the registered events maintained if mods have to re-register on_load?
They aren't, persisting closures is complex and generally not useful. The order is deterministic because event handlers are registered when the lua files are loaded, exactly how the script.on_event handlers are registered now. The Stdlib handlers just wrap those handlers with a table to allow multiple registration.
If it makes it more clear, stdlib event handlers *are* just wrappers. You can do a strict find-and-replace in a text editor, and replace script.on_event with Event.register, and your code will work exactly like before.
That's assuming people use it like that. Some register event handlers conditionally. For example: runtime the player builds something and that activates the on_tick handler for say 30 seconds and then it turns off again.
Not sure if anyone does that with this library system but it's just something to think about

As long as the events are registered in a deterministic fashion (register on_tick after an assembler is created for 30s), and it occurs on all hosts, there is no problem, right? I believe the problem would be when a mod registers handlers based on the state of local variables or something else not deterministic.
Re: Event System in STDLIB
Posted: Fri Sep 30, 2016 11:38 pm
by Rseding91
Afforess wrote:As long as the events are registered in a deterministic fashion (register on_tick after an assembler is created for 30s), and it occurs on all hosts, there is no problem, right? I believe the problem would be when a mod registers handlers based on the state of local variables or something else not deterministic.
Say they register on_tick and then you save and exit the game. On_load they re-register to keep the handler valid but now it's in a different order.