Module strands

A pure Lua library to manage co-operative multitasking in games.

Used to declare a lists of sequential things for the game to do (including waiting), that can be done in parallel in the background.

Designed for point & click adventure games, but can be used in any genre. Also includes facilities for event handling through signals.

See strands_sample.lua, strands_say.lua, strands_nested.lua, and strands_signal.lua for examples of usage.

See Strand environments for more details about how and whether to use strand environments.

Functions

inside_strand() Check if the function invoking this is running inside a strand.
get_default_environment() Get the table corresponding to the default strand environment.

Fields

_NAME Library name.
_VERSION Library version.

Class Strand

Strand.new(f, env) Create new strand.
Strand.start(f[, env]) Create and automatically start new strand.
Strand:update(dt) Update the strand.
Strand:stop() Stop the strand.
Strand:resume() Resume a paused strand.
Strand:active() Check if a strand is active.

Class StrandRegistry

StrandRegistry.new() Create new strand registry.
StrandRegistry:create(f) Create a new strand and add it to the registry.
StrandRegistry:start(f) Create and start a new strand and add it to the registry.
StrandRegistry:update(dt) Update all registered strands.
StrandRegistry:clear() De-register all active strands.
StrandRegistry:set_environment(env) Set the registry environment.
StrandRegistry:get_environment() Get the registry environment.
StrandRegistry:is_running() Check if a strand from this registry is currently running.

Wait functions

wait(t) Pause strand execution for a specified amount of time.
wait_frame() Pause strand execution until the next update.
wait_strand(strand) Pause strand execution until another strand has finished running (or was stopped).
wait_signal(object, identifier) Pause strand execution until a signal is emitted.
accumulator(duration, num_steps, loop) Produces an iterator that cycles through integers by waiting a specified time between steps.

Signals

signals.connect(object, name, f) Register a function to be called when a signal is emitted.
signals.disconnect(object, name, f) Disconnect a function from a signal.
signals.emit(object, name, ...) Emit a signal.
signals.clear() Clear all registered functions.


Functions

inside_strand()
Check if the function invoking this is running inside a strand.
get_default_environment()
Get the table corresponding to the default strand environment. This contains the wait functions.

Fields

_NAME
Library name.
_VERSION
Library version.

Class Strand

Strands are threads of execution that use coroutines to wrap a function and allow to pause execution inside it as necessary.
Strand.new(f, env)
Create new strand. It is recommended to create strands using StrandRegistry:create instead.

Parameters:

  • f: (function) function containing the commands to execute in the strand. Should not have any arguments
  • env: (optional table) environment to load global functions from, within f. If not provided no changes are made to the function environment.

Raises:

f must be a function

See also:

Strand.start(f[, env])
Create and automatically start new strand. It is recommended to create and start strands using StrandRegistry:start instead.

Parameters:

See also:

Strand:update(dt)
Update the strand. Meant to be called when updating the game loop, should normally be done at every frame.

If the strand is updated and reaches the end of its execution the signal with the strand as object and "finished" as the identifier is emitted.

Note: don't update strands directly if they are already being updated through StrandRegistry:update.

Parameters:

  • dt: (number) time elapsed since last update. Units can be chosen by the user, but have to be consistent with the ones used in wait

Raises:

If any error is raised inside the strand
Strand:stop()
Stop the strand. After calling this method the strand can no longer be updated. Use one of the wait functions to temporarily pause the strand.
Strand:resume()
Resume a paused strand. Same as calling Strand:update with dt=0. Convenience function for starting a thread created with Strand.new.
Strand:active()
Check if a strand is active.

Returns:

    (bool) true if the strand has not reached the end of its associated function and has not been stopped with Strand:update

Class StrandRegistry

A container that can start multiple strands and update them all at the same time.
StrandRegistry.new()
Create new strand registry. The registry is assigned the default strand environment (the one returned by get_default_environment containing the wait functions. The environment can be changed using StrandRegistry:set_environment.

Returns:

    (StrandRegistry) strand registry instance
StrandRegistry:create(f)
Create a new strand and add it to the registry. The strand is created by passing the current registry environment to Strand.new.

Parameters:

  • f: (function) function associated to the strand. Should not have any arguments

Returns:

    (Strand) strand instance

See also:

StrandRegistry:start(f)
Create and start a new strand and add it to the registry. The strand is created by passing the current registry environment to Strand.new.

Parameters:

Returns:

    (Strand) same as StrandRegistry.new

See also:

StrandRegistry:update(dt)
Update all registered strands. Meant to be called when updating the game loop, should normally be done at every frame. If a strand has reached the end or has been stopped with Strand:stop it is removed from the registry.

Strands are updated in the order they were created.

If a strand is updated and reaches the end of its execution the signal with the strand as object and "finished" as the identifier is emitted.

Parameters:

StrandRegistry:clear()
De-register all active strands. The strands can still be updated individually through the instances obtained when they were created.
StrandRegistry:set_environment(env)
Set the registry environment.

Parameters:

  • env: (table or nil) table to use for the registry environment. If the registry environment is set to nil, the registry will pass a nil environment to Strand.new when creating new strands.

See also:

StrandRegistry:get_environment()
Get the registry environment. Unless changed, the default environment is the one returned by get_default_environment and containing the wait functions,

Returns:

    (table or nil) current environment (nil if no environment is set)
StrandRegistry:is_running()
Check if a strand from this registry is currently running.

Returns:

    (bool) true if a strand from this registry is running, false otherwise

Wait functions

These functions can normally only be accessed as fields of the table returned by get_default_environment. They can be accessed as global functions from within a strand if it was created with an environment that cointains them (for example if they are created from a registry that has the default environment set).
wait(t)
Pause strand execution for a specified amount of time.

Parameters:

Returns:

    (number) how much actual time has elapsed
wait_frame()
Pause strand execution until the next update. Normally the strands should be updated every frame, which results in a pause of a single frame. Useful to release control from the strand in a loop that should do something each frame.

Returns:

    (number) duration of the wait (effectively the dt passed when updating the strand)
wait_strand(strand)
Pause strand execution until another strand has finished running (or was stopped).

Parameters:

  • strand: (Strand) to wait for

Returns:

    (number) how much actual time has elapsed
wait_signal(object, identifier)
Pause strand execution until a signal is emitted.

Parameters:

  • object: object of the signal
  • identifier: (string) of the signal

Returns:

    (number) how much actual time has elapsed

See also:

accumulator(duration, num_steps, loop)
Produces an iterator that cycles through integers by waiting a specified time between steps. To be used in a generic for loop. Starts iterating from 1. Useful to use strands to control animations.

Note: to ensure that exactly the right amount of time is spent in each step, the iterator can skip over some steps, effectively returning the index of the steps that you would get by waiting the current total elapsed time. If not looping, the last index (num_steps) is always returned before ending the iterator.

Parameters:

  • duration: (number) duration of the step. The units should be chosen consistently with Strand:update
  • num_steps: (number) total number of steps to iterato over. It can be set to math.huge to leave it uncapped
  • loop: (optional bool) true if the itarator should restart

Returns:

  1. (function) the iterator
  2. (table) table containing the state of the iterator
  3. (int) the number 0

Usage:

  • for i in accumulator(0.5, 10) do
        print(i)
    end
  • -- roughly equivalent to the much more cumbersome
    
    local step_duration, num_steps = 0.5, 10
    local duration = num_steps*step_duration
    local t = 0
    local accum = 0
    while t < duration do
        local i = math.min(math.floor(t/step_duration) + 1, num_steps)
        print(i)
        while accum < step_duration do
            accum = accum + wait_frame()
        end
        t = t + accum
        accum = accum%step_duration
    end

Signals

Functions for event handling through emission of signals.
signals.connect(object, name, f)
Register a function to be called when a signal is emitted.

Parameters:

  • object: object the signal is associated to (e.g., the player). Can be of any type other than nil
  • name: (string) identifier of the event to signal (e.g., "finished moving"). Different objects can have the same identifier without conflicts
  • f: (function) function to register
signals.disconnect(object, name, f)
Disconnect a function from a signal.

Parameters:

signals.emit(object, name, ...)
Emit a signal. Calls all connected functions.

Note: no guarantees are made on the order in which the connected functions will be called.

Parameters:

  • object: object the signal is associated to (e.g., the player). Can be of any type other than nil
  • name: (string) identifier of the event to signal (e.g., "finished moving"). Different objects can have the same identifier without conflicts
  • ...: arguments to pass to the registered functions when calling them
signals.clear()
Clear all registered functions.
generated by LDoc 1.5.0