GlassBricks / typed-factorio

Complete and featureful Typescript defintions for the Factorio modding API
MIT License
33 stars 3 forks source link

Feature request: Get the name of an event as a string #3

Closed aSemy closed 2 years ago

aSemy commented 2 years ago

At the moment I'm processing events from Factorio

script.on_event(
    defines.events.on_player_mined_entity,
    (e: OnPlayerMinedEntityEvent) => {
      handlePlayerUpdate(e.tick, e.player_index, "on_player_mined_entity")
      handleEntityUpdate(e.tick, e.entity, "on_player_mined_entity")
    }
)

I'd like to be able to do something like e.event_name which will return a string, "on_player_mined_entity".

I've tried e.name, but that returns another object, not the name.

Maybe this is already possible and I don't know how to do it in TypeScript :)

GlassBricks commented 2 years ago

I don't think there's currently a built-in way to do this in the factorio api. What you could do, is create your own id-to-string-name table:

export const eventIdToName = new LuaTable<defines.events, keyof typeof defines.events>()
for (const [k, v] of pairs(defines.events)) {
  eventIdToName.set(v, k)
}

//usage
script.on_event(defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => {
  const name = eventIdToName.get(e.name)
})
aSemy commented 2 years ago

Wonderful, that does the trick, thanks!

But since the TypeScript code is generated, could you add the string name of the event to the generated TS code, improving upon the actual Factorio class?

aSemy commented 2 years ago

Actually, it might be better to have a super-interface or abstract class FactorioEvent that all events implement/extend. This would have two fields: event_name and tick. That would make handling events generically, but still type-safely, much more easy. What do you think? Is that possible, or worth the effort to implement?

GlassBricks commented 2 years ago

But since the TypeScript code is generated, could you add the string name of the event to the generated TS code, improving upon the actual Factorio class?

This would be currently out of the scope of this project as this project only generates type definitions: it defines the types of the existing API, but doesn't extend the api/run any code. I might in the future release a separate project which could have such utilities.

Actually, it might be better to have a super-interface or abstract class FactorioEvent that all events implement/extend. This would have two fields: event_name and tick. That would make handling events generically, but still type-safely, much more easy. What do you think? Is that possible, or worth the effort to implement?

There is already an interface for this called EventData. Although currently none of the events types explicitly extend this interface (yet), they should all be assignable to it.

GlassBricks commented 2 years ago

To help people discover this, event types now explicitly extend from EventData in v0.8.0.

aSemy commented 2 years ago

Amazing, thanks!