Skip to content

StateMachine

A StateMachine (or machine) is a mechanism that transitions between several states that have been added, usually through newState. When a transition is performed, the previous state is left, the onTransition event fires, and the new state is entered. Machines do not begin in any state in particular, but rather a nil state.

Event-based Usage

local sm = StateMachine.new()

-- Create some states
local stateGame = sm:newState("game")
local stateShop = sm:newState("shop")
stateShop.onEnter:connect(function ()
    print("Welcome to the shop!")
end)
stateShop.onLeave:connect(function ()
    print("Come back soon.")
end)

-- Make some transitions
sm:transition("game")
sm:transition("shop") --> Welcome to the shop!
sm:transition("game") --> Come back soon.

Subclass Usage

local MyMachine = setmetatable({}, StateMachine)
MyMachine.__index = MyMachine

function MyMachine.new()
    local self = setmetatable(StateMachine.new(), MyMachine)

    -- States 
    self.defaultState = self:newState("default")
    self.spamState = self:newState("spam")
    self.eggsState = self:newState("eggs")
    self.maid:addTask(self.spamState.onEnter:connect(function ()
        self:onSpamStateEntered()
    end))

    -- Transition counter
    self.transitionCounter = 0

    -- Default state
    self:transition(self.defaultState)

    return self
end

function MyMachine:transition(...)
    StateMachine.transition(self, ...) -- call super
    self.transitionCounter = self.transitionCounter + 1
    print("Transitions: " .. self.transitionCounter)
end

function MyMachine:onSpamStateEntered()
    print("Spam!")
end
Usage
local myMachine = MyMachine.new()
myMachine:transition("spam")
myMachine:transition("eggs")

Sub-machines

Certain states may control their own StateMachine (a sub-StateMachine or submachine). When a state with a sub-machine is entered, the submachine enters the "Active" state. Upon leaving, it enters the "Inactive" state.

Constructors

StateMachine StateMachine.new()

Construct a new StateMachine.

The new machine has no states added to it, and is not in any state to begin with.

Fields

StateMachine.StateClass

The State class used when creating a new state via this machine.

StateMachine.SubStateMachineClass

The StateMachine class used when creating a new submachine for a state via this machine.

StateMachine.state

Refers to the current State the machine is in, if any.

Use isInState to check the current state by object or id.

dictionary StateMachine.states

Dictionary of states by id that have been added

Maid StateMachine.maid

A Maid invoked upon cleanup Cleans up onTransition and states constructed through newState.

boolean StateMachine.debugMode

A flag which enables transition printing for this machine.

Functions

StateMachine:__tostring()

Returns a string with the current State this machine is in (if any), calling State:__tostring.

StateMachine:print(...)

Wraps the default print function; does nothing if debugMode is false.

StateMachine:cleanup()

Clean up resources used by this machine by calling cleanup on this machine's maid.

States created with newState are cleaned up as well.

StateMachine:addState(State state)

Add a State to this machine's states.

StateMachine:newState(...)

Construct and add a new state of type StateClass (by default, State) for this machine.

The state is added as a maid task.

boolean StateMachine:hasState(string id)

Determines whether this machine has a state with the given id.

State StateMachine:getState(string id)

Get a state by id that was previously added to this machine.

boolean StateMachine:isInState(State/string state)

Returns whether the machine is currently in the given state or state with given id

StateMachine:transition(State/string stateNew)

Transition the machine to another state, firing all involved events in the process.

This method will print transitions before making them if the machine has debugMode set. Events are fired in the following order: old state onLeave, machine onTransition, then finally new state onEnter.

StateMachine:newSubmachine(State state)

Create a StateMachine of type SubStateMachineClass, given a state.

Two new states are created on the sub-StateMachine with ids "Active" and "Inactive":

  • When the parent machine enters the given state, the sub-StateMachine transitions to "Active".
  • When the parent machine leaves the given state, the sub-StateMachine transitions to "Inactive".

The sub-StateMachine is added as a task to this machine's maid.

Events

StateMachine.onTransition(State oldState, State newState)

Fires when the machine transitions between states.