Add events for `remote.add_interface` and `remote.remove_interface`

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
BurninSun
Long Handed Inserter
Long Handed Inserter
Posts: 58
Joined: Fri Mar 16, 2018 4:54 am
Contact:

Add events for `remote.add_interface` and `remote.remove_interface`

Post by BurninSun »

Currently, if I want to call a remote interface, I have to do something similar to

Code: Select all

if remote.interfaces["iface"] and remote.interfaces["iface"]["ifunc"] then
	local ret = remote.call("iface", "ifunc", myargs)
	dostuff(ret)
end
Every call to `remote.interfaces` requires the engine to create a dictionary of dictionaries for all interface names and all function names which we only use to check an interfaces existence then throw away.

(Alternatively, that code can be rewritten so that `remote.interfaces` is only called once, but still, my point remains)

The problem: This is a relatively slow process to create this dictionary of dictionaries into Lua.

These values cannot be cached as remote interfaces can be added and removed at any time. (Alternatively we can use `xpcall` on `remote.call` without checking a functions existence, but that becomes a huge pain to handle for something that should be simple.)

It seems it would be simple for the engine to trigger events `on_remote_interface_added` and `on_remote_interface_removed` as appropriate. Included in the `event` data would be the name of the interface added or removed. The actual function names included in the interface can then be retrieved with `remote.interfaces[event.interface]` and kept in a cache. Then when I need to do a remote.call I simply check my cache for the functions existence and call it.
FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Add events for `remote.add_interface` and `remote.remove_interface`

Post by FuryoftheStars »

Can you give a usage example on this? IE, in what situation is this useful? My understanding on remote interfaces has been such that these aren't things that are (or should be) dynamically added or removed during runtime. As such, it's either there because the mod that makes it is there, or it isn't because the mod isn't, and so you either require the mod for your mod, or you check for that mod's existence before running your call. I feel like a mod dynamically adding or removing interfaces defeats the point of the interfaces and is just asking for trouble.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics
BurninSun
Long Handed Inserter
Long Handed Inserter
Posts: 58
Joined: Fri Mar 16, 2018 4:54 am
Contact:

Re: Add events for `remote.add_interface` and `remote.remove_interface`

Post by BurninSun »

While I agree with your sentiment, the fact is that interfaces can be added and removed on the fly. So do we just call it and hope another mod hasn't removed their interface then take the bug reports if it has?
FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Add events for `remote.add_interface` and `remote.remove_interface`

Post by FuryoftheStars »

Honestly? As a mod author attempting to make a mod to go along with another and use their remote interfaces, I'd file a bug report to their mod and explain why that's an issue doing that.

I suppose if someone could come up with a great example where calling these functions dynamically would be beneficial, I could see this, otherwise I'd rather propose to the devs to restrict the usage (if it's possible) of these functions to being able to run only in the root, on_init, and/or on_configuration_changed code spaces (and any other "executes once" code space that I'm forgetting and makes sense). Or, I just wouldn't sweat it until I ran across someone that was doing this and either refused to (or couldn't because they were gone) change it, then I'd find a work around if possible (maybe even release an alternate version of the mod if they were indeed gone).
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics
curiosity
Filter Inserter
Filter Inserter
Posts: 478
Joined: Wed Sep 11, 2019 4:13 pm
Contact:

Re: Add events for `remote.add_interface` and `remote.remove_interface`

Post by curiosity »

Why is this better than adding a function like this?

Code: Select all

LuaRemote::try_call(interface, function, ...)  → boolean, Any?
Assuming call errors when given a nonexistent interface/function name instead of doing something similar already.
BurninSun
Long Handed Inserter
Long Handed Inserter
Posts: 58
Joined: Fri Mar 16, 2018 4:54 am
Contact:

Re: Add events for `remote.add_interface` and `remote.remove_interface`

Post by BurninSun »

Restricting usage during on_init and similar would also work, but that is not a system that the engine currently does. Creating that system and explaining it to the modders would be a big undertaking for such a rarely used feature.

LuaRemote::try_call would work similar to pcall(remote.call, "iface", "func", ...) though pcall has the issue of catching any errors in the remotely called function. Otherwise, that could work as well.

With events as proposed, I'd imagine it would be simple to implement and go along nicely with the other similar features in the engine.
curiosity
Filter Inserter
Filter Inserter
Posts: 478
Joined: Wed Sep 11, 2019 4:13 pm
Contact:

Re: Add events for `remote.add_interface` and `remote.remove_interface`

Post by curiosity »

BurninSun wrote: Mon Feb 19, 2024 10:54 pm With events as proposed, I'd imagine it would be simple to implement and go along nicely with the other similar features in the engine.
In the context of the problem you are trying to solve, it's a suboptimal solution. You have to set up caches that you need to keep updated, handle events and so on. As opposed to simply having the game do what it already has to do to call the function in the first place.
BurninSun
Long Handed Inserter
Long Handed Inserter
Posts: 58
Joined: Fri Mar 16, 2018 4:54 am
Contact:

Re: Add events for `remote.add_interface` and `remote.remove_interface`

Post by BurninSun »

curiosity wrote: Wed Feb 21, 2024 5:32 pm In the context of the problem you are trying to solve, it's a suboptimal solution. You have to set up caches that you need to keep updated, handle events and so on. As opposed to simply having the game do what it already has to do to call the function in the first place.
Some remote calls are generic and the interface is unknown. For example, space exploration beacon overload has the following when an entity is reactivated due to beacon overload being disabled.

Code: Select all

for interface, functions in pairs(remote.interfaces) do -- allow other mods to deactivate after
  if interface ~= "space-exploration" and functions["on_entity_activated"] then
    remote.call(interface, "on_entity_activated", {entity=entity, mod="space-exploration"})
  end
end
In this case, `try_call` would not work as the interfaces would not be known. Caching the interfaces from `remote.interfaces` also would not work as the callee might only enable that interface after a specific event (eg. an entity needing to receive this callback being built).

There is another similar "unknown interface" callback when space explorations deletes a surface. Informatron also uses this construction.

Having interface events would allow modders to either use the existing `remote.interfaces` for simplicity of coding or use the events to track available interfaces for performance.
Post Reply

Return to “Modding interface requests”