Module EventManagerLite

Native multi-handler events.

EventManagerLite mimics the LuaBootstrap api to allow mods to register multiple handlers to any event with only minimal code changes.

To prevent errors, EventManagerLite blocks direct access to LuaBootstrap. It's methods must instead be accessed via a ManagedLuaBootstrap object.

Module Status: Experimental 2021-08-19.

Usage:

    local EventManager = require('__eradicators-library__/erlib/factorio/EventManagerLite-1')()
    

Public methods

events Custom event names.
get_managed_script(module_name) Creates a new ManagedLuaBootstrap instance or fetches an existing one of the same name.

Concepts

EventName The unique name of an event.

Factorio Behavior

api_availability What apis are available during on_init, on_load and on_config?
boostrap_event_order In what order do on_init, on_load and on_config happen?
event_handler_order In what order are handlers executed?

Examples

Examples

ManagedLuaBootstrap

ManagedLuaBootstrap The main interface of EventManagerLite.
ManagedLuaBootstrap.on_event(event_name, f, filters) Register event handlers.
ManagedLuaBootstrap.on_nth_tick(period, f) Changed.
ManagedLuaBootstrap.on_init() Removed.
ManagedLuaBootstrap.on_load(f) Changed.
ManagedLuaBootstrap.on_configuration_changed(f) Changed.
ManagedLuaBootstrap.on_config() New: Shorthand for on_configuration_changed(f).
ManagedLuaBootstrap.generate_event_name([event_name]) Changed.
ManagedLuaBootstrap.module_name New: The name that was used to create this instance.
ManagedLuaBootstrap.module_index New: The load order index of this instance.
ManagedLuaBootstrap.object_name Changed.
ManagedLuaBootstrap.events New: Alias for EventManagerLite.events.
ManagedLuaBootstrap.set_event_filter() Removed.
ManagedLuaBootstrap.get_event_filter() Removed.

Commands

dump Dumps handler registration data to the attached terminal.

ExtraEvents

HowToActivateExtraEvents Extra events must be activated in settings stage prior to usage.
on_entity_created All-in-one entity building event.
on_player_changed_chunk Raised when the player moves or is teleported across a chunk border on the same surface, or has moved to another surface.
on_user_panic Raised when a player calls "DON'T PANIC!" in the chat.

TickedAction

on_ticked_action Called when an action should happen.
TickedAction.enqueue(module_name, method_name, offsets[, parameter]) Plans a future action.
TickedAction.dequeue(module_name, method_name[, ticks]) Cancels a future action before it happens.


Public methods

events
Custom event names. Erlibs equivalent to defines.events for modded event ids. This is the recommended way of sharing EventNames between mods.

This table contains all dynamically generated (event_name → event_id) mappings that are contained in the Remote.PackedInterfaceGroup 'erlib:managed-events'. Take care to use the correct load order and declare dependencies as needed.

Trying to read event names that have not been defined yet is an error. It is possible, but discouraged to add event ids by writing them directly to this table. It is recommended to use generate_event_name to generate new names.

See also remotes.events.

Usage:

    -- Mod_A:
    ManagedLuaBootstrap.generate_event_name('on_something_happend')
    
    -- Mod_X (can be Mod_A):
    script.on_event(events.on_something_happend, function(e)
      print('I just shared an event name without effort!')
      end)
    
    -- Mod_A:
    script.raise_event(events.on_something_happend, {player_index = ...})
    
    -- Mod_X (can be Mod_A):
    > I just shared an event name without effort!
    
get_managed_script(module_name)
Creates a new ManagedLuaBootstrap instance or fetches an existing one of the same name.

On the first call to this function with a new module_name a unique module_index is generated. Subsequent calls share the same index.

Parameters:

  • module_name string The name of your module.

Returns:

    ManagedLuaBootstrap If an instance of the same name has been created before you will recieve a reference to, not a copy of, that exact same instance table.

Concepts

EventName
The unique name of an event.

An EventName is any NaturalNumber or string that would normally be used to register an event handler with script.on_event().

That means any NaturalNumber from defines.events, any NaturalNumber number generated with script.generate_event_name(), any name string of a LuaCustomInputPrototype, or one of the literal strings "on_load", "on_config" and "on_configuration_changed".

Factorio Behavior

See also Data-Lifecycle.
api_availability
What apis are available during on_init, on_load and on_config?

Usage:

    on_init   : remote commands settings rcon rendering script game global[R/W]
    on_load   : remote commands settings rcon           script      global[R]
    on_config : remote commands settings rcon rendering script game global[R/W]
    
boostrap_event_order

In what order do on_init, on_load and on_config happen?

Absurdly the engine raises on_load* before on_config, at best causing unnesscary work, at worst running it on outdated global data. There's nothing I can do about that so you have to take countermeasures yourself. Don't forget to use migrations if nessecary.

See ManagedLuaBootstrap.on_init for why EventManagerLite never raises on_init.

Base game order:

InstallMod -> StartMap                         : on_init      -         -
InstallMod -> StartMap -> SaveMap    -> LoadMap:   -        on_load     -
InstallMod -> StartMap -> ChangeMod  -> LoadMap:   -        on_load*  on_config
StartMap   -> SaveMap  -> InstallMod -> LoadMap: on_init      -       on_config

EventManagerLite order:

InstallMod -> StartMap                         : on_config     -        -
InstallMod -> StartMap -> SaveMap    -> LoadMap:   -        on_load     -
InstallMod -> StartMap -> UpdateMod  -> LoadMap:   -        on_load*  on_config
StartMap   -> SaveMap  -> InstallMod -> LoadMap: on_config    -       on_config
event_handler_order
In what order are handlers executed?

When two mods or two ManagedLuaBootstrap instances each have a handler for the same event, then the events are executed in the order that they were loaded in. For ManagedLuaBootstrap this is determined by the module_index.

When multiple On_nth_tick handlers occur on the same tick then the handlers are executed in order from smallest to largest period. All on_tick handlers are always executed before any on_nth_tick handlers.

Examples

Examples

Usage:

  • -- same basic syntax as script.on_event
    local script = EventManagerLite.get_managed_script('my-scripted-entity')
    script.on_event(defines.events.on_entity_damaged,
      function(e)
        game.print{'', 'Entity ', e.entity.name, ' was damaged.'}
        end
      }
    
  • -- on_config replaces on_init and on_configuration_changed
    local script = EventManagerLite.get_managed_script('my-scripted-entity')
    script.on_config(function(e)
      print('This is a shortcut to on_configuration_changed!')
      end)
    

ManagedLuaBootstrap

ManagedLuaBootstrap
The main interface of EventManagerLite. Each instance can have one handler for every event, just like a normal factorio mod can. Differently named instances act like seperate mods and do not interfer with each others events.

This section documents only the changes compared to LuaBootstrap. Everything not mentioned here works exactly the same as it normally does (i.e. script.active_mods, script.generate_event_name, script.raise_event etc).

Changed: ManagedLuaBootstrap is not write-protected like real LuaBootstrap. Changes you make will be visible in all instances with the same name.

ManagedLuaBootstrap.on_event(event_name, f, filters)
Register event handlers. (See also LuaBootstrap.on_event.)

Parameters:

  • event_name EventName or table Changed: Accepts values of any type of table, not only of arrays, and recognizes the strings 'on_load', 'on_config' and 'on_configuration_changed'.
  • f function or nil Unchanged.
  • filters nil Removed. Because filtering would need to be done on the lua side there would be no performance benefit.

Returns:

    function or nil New: Returns the given function f.

Usage:

    local my_handler = script.on_event(defines.events, function(e) end)
    
ManagedLuaBootstrap.on_nth_tick(period, f)
Changed. To prevent lag spikes when several modules with handlers for the same period all execute on the same tick, each handler is assigned a random offset. The offset is deterministic and always the same for a given combination of module_name and period.

The offset is included in the event table when the handler is called.
For example: f{nth_tick = 30, offset = 9, tick = 39}.

The offset always fullfills the condition:
(tick % nth_tick) == offset.

Parameters:

Returns:

    function or nil New: Returns the given function f.
ManagedLuaBootstrap.on_init()
Removed.

Because factorio only raises on_init once per mod this is not reliable for adding new modules to an existing savegame. To prevent any confusion it is completely disabled. Use on_configuration_changed instead.

ManagedLuaBootstrap.on_load(f)
Changed.

Parameters:

Returns:

    function or nil New: Returns the given function f.
ManagedLuaBootstrap.on_configuration_changed(f)
Changed. Because on_init is not reliable, on_configuration_changed handlers must also handle on_init in an agnostic manner.

If the handler is raised during on_init it will be raised without parameters. Warning: Do not try to outsmart yourself by using this to "detect" on_init. There is no guarantee that this will ever happen at all. It's best if you just store a private "is_initialized" flag in your modules global data if you need to do heavy lifting in on_init.

See also EventManagerLite.boostrap_event_order, LuaBootstrap.on_configuration_changed

Parameters:

Returns:

    function or nil New: Returns the given function f.
ManagedLuaBootstrap.on_config()
New: Shorthand for on_configuration_changed(f).
ManagedLuaBootstrap.generate_event_name([event_name])
Changed. Now supports naming events. If a name is given it's id is automatically published to the Remote.PackedInterfaceGroup called 'erlib:managed-events', which can easily be accessed via EventManagerLite.events.

See also LuaBootstrap.generate_event_name and remotes.events.

Parameters:

  • event_name string Your custom name for the event. (optional)

Returns:

    NaturalNumber The EventName for your event. A new EventName will only be generated on the first call for each event_name. Subsequent calls with the same event_name will return the previously generated EventName.
ManagedLuaBootstrap.module_name
New: The name that was used to create this instance. Similar to LuaBootstrap.mod_name but not the same.

Read only. (Technically you can overwrite it but that won't affect anything.)

ManagedLuaBootstrap.module_index
New: The load order index of this instance. When an event is subscribed to by multiple instances then the handlers will be executed in this order, starting from lowest going to highest.

Read only. (Technically you can overwrite it but that won't affect anything.)

See also EventManagerLite.event_handler_order.

ManagedLuaBootstrap.object_name
Changed. The name is "ManagedLuaBootstrap". To distinguish from the real script which is named "LuaBootstrap".

Read only. (Technically you can overwrite it but that won't affect anything.)

See also Common.object_name.

ManagedLuaBootstrap.events
New: Alias for EventManagerLite.events.
ManagedLuaBootstrap.set_event_filter()
Removed. Event filters are not supported.
ManagedLuaBootstrap.get_event_filter()
Removed. Event filters are not supported.

Commands

dump
Dumps handler registration data to the attached terminal. This command only works when the erlib debug-mode sub-mod is active. Any incorrect usage is silently ignored.

/erlib event-manager dump <mod_name>

ExtraEvents

HowToActivateExtraEvents
Extra events must be activated in settings stage prior to usage.

erlib_enable_plugin(<extra_event_name>)

Usage:

    -- settings.lua
    erlib_enable_plugin('on_entity_created')
    erlib_enable_plugin('on_player_changed_chunk')
    erlib_enable_plugin('on_ticked_action')
    
on_entity_created
All-in-one entity building event.

Combines the following events:
on_built_entity
on_robot_built_entity
script_raised_built
script_raised_revive
on_entity_cloned
on_trigger_created_entity

Fields:

  • created_entity LuaEntity The entity built.
  • player_index NaturalNumber (optional)
  • robot LuaEntity The robot that did the building. (optional)
  • stack LuaItemStack The item used to do the building. (optional)
  • item LuaItemPrototype The item prototype used to build the entity. Note this won't exist in some situations (built from blueprint, undo, etc). (optional)
  • tags Tags The tags associated with this entity. (optional)
  • clone_source LuaEntity The entity that this entity was cloned from. (optional)
  • trigger_source LuaEntity The entity with a trigger prototype (such as capsules) that created this entity. (optional)
on_player_changed_chunk
Raised when the player moves or is teleported across a chunk border on the same surface, or has moved to another surface. After a surface was deleted this is called for all players regardless of if they were actually on that surface.

Abstracts:
on_player_changed_position
on_player_changed_surface

Fields:

on_user_panic
Raised when a player calls "DON'T PANIC!" in the chat. You should trigger some generic sanity checking and garbage collection of your mods internal state now.

Commands typed on the server console and commands raised by mods do not have a player_index, making them indistinguishable from each other, so they are filtered out and do not raise anything.

If the player is an admin or the game is Singleplayer then an additional event on_admin_panic is raised.

See also: on_console_chat

Fields:

  • player_index uint (not optional)
  • message string
  • calming_words string The key for the localised string you should print when you're done.

Usage:

    script.on_event(EventManager.events.on_user_panic, function(e)
      dostuff()
      Player.get_event_player(e).print{e.calming_words, 'name-of-your-content'}
      end)
    

TickedAction

Usage:

-- settings.lua
erlib_enable_plugin('on_ticked_action')

-- control.lua
local Action = Remote.get_interface('erlib:on_ticked_action')

local my_actions = {
  doit = function(name)
    print(name .. ' did it !')
    end
  }

script.on_event(EventManagerLite.events.on_ticked_action, function(e)
  if e.module_name == 'my-module' then
    if e.method_name == 'doit' then
      my_actions.doit(e.parameter.name)
      end
    end
  end)

script.on_event(defines.events.on_something_happend, function(e)
  Action.enqueue('my-module', 'doit', 60*5, {name = 'The gardener'})
  end)

-- 5 seconds later
> The gardener did it!
on_ticked_action
Called when an action should happen. Events with the same tick are raised in the order they were enqueued in.

See also EventManagerLite.events

Fields:

  • module_name string The name you chose.
  • method_name string The name you chose.
  • parameter AnyValue The data you gave.
TickedAction.enqueue(module_name, method_name, offsets[, parameter])
Plans a future action.

Parameters:

  • module_name string A name to identify your event later.
  • method_name string A name to identify your event later.
  • offsets NaturalNumber or DenseArray How many ticks from now you want the action to happen. You can plan several ticks at once.
  • parameter string, boolean, table or number You can store data here to retrieve it in the event later. The data must survive a remote call, global Savedata save/load cycles and script.raise_event, so it's best to keep it simple. (optional)
TickedAction.dequeue(module_name, method_name[, ticks])
Cancels a future action before it happens.

Parameters:

  • module_name string
  • method_name string
  • ticks NaturalNumber or DenseArray You can either unplan all actions with matching names, or only actions that were planned for the given ticks. (optional)
generated by LDoc 1.4.6 Last updated 2021-09-10 19:51:19