custom-input: ability to dynamically consume events

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
Post Reply
User avatar
mickael9
Fast Inserter
Fast Inserter
Posts: 112
Joined: Mon Mar 14, 2016 4:04 am
Contact:

custom-input: ability to dynamically consume events

Post by mickael9 »

I personally always use the "e" key to close GUIs in the game, but it's not currently possible to have to exact same behavior with mods.

The native game will always catch a close window (e) keypress if a GUI is opened rather than using the other (open inventory) action.

Trying to replicate the same thing for mods, using a global "close key" between the game and all mods, we hit a few problems, depending on the way we set the "consuming" key of the custom-input.
  • nil (default): the "e" keypress will always be passed to every mod (unless there's a native GUI open). This sounds good, except that this means it will pass the key to the mod, then execute the open inventory action
  • "game-only": this looks better, but it means the open-inventory action will never be executed because it will be catched unconditionally by the mod.
  • "scripts-only": the open-inventory action will execute AND only one mod can catch it
  • "all" : open-inventory will never execute and only one mod can catch it

    My proposal is to add a new "dynamic" key which will allow the input handler to decide whether it consumes the event or not, by returning a boolean:

    Code: Select all

    data:extend({
    {
      type = "custom-input",
      name = "mod-close-window",
      key_sequence = "e",
      consuming = "dynamic"
    }
    
    With that, a handler code would look like this:

    Code: Select all

    script.on_event("mod-close-window", function(event)
        if (global.gui_opened) then
            close_gui()
            return true
        end
    end)
    
    This would meet all the uses cases :
    • If the game has a native GUI open, it will catch it (this seems to always be the case) which is fine
    • If not it will call the event for the first mod in list.
    • Assuming that first mod has no gui window open, it will return false or nil and the key will be propagated to the next mod
    • If the next mod has a window open, it will close it and return true. This stops the propgation of the event which will not be passed the game and will not cause the open inventory action.
    • If all mods have their windows closed, then the key press is passed to the game and will execute the open inventory action.

Rseding91
Factorio Staff
Factorio Staff
Posts: 13218
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: custom-input: ability to dynamically consume events

Post by Rseding91 »

That's not how Factorio works.

The input action isn't actually applied to the game until long after the key has been pressed and the event sent into the event queue.

It could be up to 2 seconds after the key was pressed that the mod actually gets the event at which point it's far too late to say "don't fire the other events".
If you want to get ahold of me I'm almost always on Discord.

User avatar
mickael9
Fast Inserter
Fast Inserter
Posts: 112
Joined: Mon Mar 14, 2016 4:04 am
Contact:

Re: custom-input: ability to dynamically consume events

Post by mickael9 »

I'm conducting some tests in order to understand how all of this works exactly, and have found some strange stuff happening:

Some keys seem to be always catched by the game, with no possibility to receive them (even in the "none" consuming mode) : Escape, p, t, m, r (when holding an item), e (when a GUI is opened) and probably others. (I mention the keys here, but the behavior is bound to the default action for that key, not the key itself of course)

While it makes sense to disallow mods to block those, it would be nice to be able to see them with consuming = "none" (this is especially true for the Escape key which can act as a general "close gui" key)

Also, I don't really understand how the "all" mode is supposed to work. From the description, my understanding is that's is basically both game-only and script-only and will catch the event before it has a chance to go to other scripts or the game. But from my testing, it acts more like script-only and does not prevent the event from getting to the game. What's going on?

And finally, how hard would it be to allow mods to enable/disable their inputs at will so that they don't eat the keypress when disabled? This could be simply implemented by having an input not catch anything if no callback was set for it (eg script.on_event("my-input", nil)).

Post Reply

Return to “Modding interface requests”