Event filters
Posted: Tue Sep 27, 2016 12:26 am
I'm always cringing at the thought that my event handlers are wasting CPU cycles. I'm aware that the game already provides a lot of optimisation such as lazy-loading LuaCustomTable objects, but any unwanted events hitting Lua are eating up time, especially when lots of players have 50+ mods active in their games.
Would it be possible to add an additional parameter to `script.on_tick()` and `script.on_event()` that allows the game engine to do some internal filtering of events before sending stuff to Lua? The new "filter" param would be optional, and not all events will have it.
Example for on_tick:
I know there's a trivial way to do that in Lua, but it would still result in 29 unwanted calls to Lua.
By having the game engine handle the throttling, there are two potential advantages:
This way, my event handlers only get called when the event relates to the listed entities.
When removing event handlers (by specifying nil) the corresponding filter (if applicable) would need to be specified, for example:
Note: I don't think I've yet seen any mod that ever removes event listeners, although I imagine it would be a good practice for modders to start doing that more often where possible.
Would it be possible to add an additional parameter to `script.on_tick()` and `script.on_event()` that allows the game engine to do some internal filtering of events before sending stuff to Lua? The new "filter" param would be optional, and not all events will have it.
Example for on_tick:
Code: Select all
-- wait 30 ticks between each invocation of myHandlerFn:
script.on_tick( myHandlerFn, 30 )
By having the game engine handle the throttling, there are two potential advantages:
- I could define multiple tick handlers, at different frequencies (eg. regular task every 2 ticks, housekeeping task every 600 ticks)
- The game engine could defer calling the event if too much time has already been spent on current tick; because the Lua code is no longer checking specific tick modulus.
Code: Select all
-- only trigger these if the entity is 'foo' or 'bar'
local filter = { 'foo', 'bar' }
local e = defines.events
script.on_event(e.on_entity_died , myHandlerFn, filter)
script.on_event(e.on_robot_pre_mined , myHandlerFn, filter)
script.on_event(e.on_preplayer_mined_item, myHandlerFn, filter)
When removing event handlers (by specifying nil) the corresponding filter (if applicable) would need to be specified, for example:
Code: Select all
script.on_tick(nil, 30)
script.on_event(e.on_entity_died, nil, filter) -- remove listener for that specific filter