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.