Skip to main content

SimpleFiniteStateManager

Overview​

Type: class

A bare-bones state manager that only allows state change according to a set of predefined state transitions.

class SimpleFiniteStateManager<State> extends SimpleStateManager<State>

Constructor​

constructor(
defaultState: State,
allowedStateTransitions: Array<[fromState: State, toState: State]>,
options: SimpleStateManagerOptions
)

Parameters​

  • defaultState — The default state.
    Type: any
    Required: Yes
  • allowedStateTransitions — The list of allowed state transitions.
    Type: Array (of StateTransition)
    Required: Yes
  • options — Additional options for the State Manager.
    Type: SimpleStateManagerOptions
    Required: No — (default value: {})

Example​

Consider an example where a playable character in a game:

  • can stand be standing idle, walking, or attacking;
  • can only attack only when standing still.

This would roughly translate into the following code:

import { SimpleFiniteStateManager } from 'cotton-box'

class PlayableCharacter {

readonly state = new SimpleFiniteStateManager('idle', [
['idle', 'walking'],
['idle', 'attacking'],
['walking', 'idle'],
['attacking', 'idle'],
], {
name: 'PlayableCharacter',
})

}

Since the initial state is 'idle', changing the state to 'walking' immediately after instantiating the class would be just fine.

const newCharacter = new PlayableCharacter()
newCharacter.set('walking')
newCharacter.set('attacking')

However, proceeding to change the state from 'walking' to 'attacking' would result in the following error:

InvalidStateTransitionError: from "walking" to "attacking" in PlayableCharacter

Also see: InvalidStateTransitionError

Properties​

defaultState​

Inherited from: SimpleStateManager.defaultState

The default state.

readonly defaultState: State

name​

Inherited from: SimpleStateManager.name

The display name. Only used for debugging.

readonly name?: string | undefined | null

Methods​

get​

Inherited from: SimpleStateManager.get

Retrieves the current state value.

get(): State

Parameters​

get does not take any parameters.

Returns​

get returns the current state value.

Example​

const state = ExampleState.get()

set​

Inherited from: SimpleStateManager.set

Sets the state with a value.

set(newState: State): void

Sets the state with a function.

set(setStateFn: SetStateFn<State>): void

Parameters​

set takes either one of the following parameters:

  • newState — The new state.
    Type: any
    Required: Yes (either one)
  • setStateFn — A function that accepts the current state and default state as parameters and returns a new state.
    Type: SetStateFn
    Required: Yes (either one)

Returns​

set does not return anything.

Example​

ExampleState.set('A')
ExampleState.set((previousState) => previousState === 'A' ? 'B' : 'C')

trySet​

Tries to set the state with a value. If the new state does not conform to the defined state transitions, the state will not change and no error will be thrown.

trySet(newState: State): void

Tries to set the state with a function. If the new state does not conform to the defined state transitions, the state will not change and no error will be thrown.

trySet(setStateFn: SetStateFn<State>): void

Parameters​

trySet takes either one of the following parameters:

  • newState — The new state.
    Type: any
    Required: Yes (either one)
  • setStateFn — A function that accepts the current state and default state as parameters and returns a new state.
    Type: SetStateFn
    Required: Yes (either one)

Returns​

trySet returns true if the state change conforms to the predefined state transitions, otherwise false.

Example​

ExampleState.trySet('A')
ExampleState.trySet((previousState) => previousState === 'A' ? 'B' : 'C')

reset​

Inherited from: SimpleStateManager.reset

Resets the State Manager back to it's default value.

reset(): void

Parameters​

reset does not take any parameters.

Returns​

reset does not return anything.

Example​

ExampleState.reset()

tryReset​

Tries to reset the State Manager back to it's default value. If the reset does not conform to the defined state transitions, the state will not change and no error will be thrown.

tryReset(): boolean

Returns​

reset returns true if the state reset conforms to the predefined state transitions, otherwise false.

Parameters​

tryReset does not take any parameters.

Example​

ExampleState.tryReset()

watch​

Inherited from: SimpleStateManager.watch

Watch for state changes.

watch(callback: (state: State) => void): () => void

Parameters​

  • callback — The callback that will be invoked each time the state changes.
    Type: Function
    Required: Yes

Returns​

watch returns an "unwatch" function that when called, will remove the watcher. The "unwatch" function does not take any parameters and does not return anything.

Example​

const unwatch = ExampleState.watch((state) => { console.log(state) })
// ··· then after some time ···
unwatch()

unwatchAll​

Inherited from: SimpleStateManager.unwatchAll

Removes all existing watchers referencing to this State Manager. Watchers that added after calling this method will not be affected.

unwatchAll(): void

Parameters​

unwatchAll does not take any parameters.

Returns​

unwatchAll does not return anything.

Example​

ExampleState.unwatchAll()

wait​

Waits for the state to match the expected value. If the state already matches the expectedValue, the Promise will be resolved immediately.

wait(expectedValue: State): Promise<State>

Waits for the evaluator to evaluate to true. The evaluator will be called immediately to check if the condition is fulfilled. If not, it will be called again each time the state changes until the condition is fulfilled.

wait(evaluator: WaitEvaluator<State>): Promise<State>

Parameters​

wait takes either one of the following parameters:

  • expectedValue — The value to wait for.
    Type: any
    Required: Yes (either one)
  • evaluator — Determines whether the state fulfills a certain condition.
    Type: WaitEvaluator
    Required: Yes (either one)

Returns​

wait returns a Promise that resolves into a snapshot of the state value that matches the expectedValue or allows the evaluator to return true.

Example​

// Promise will resolve when the state value becomes `42`.
await ExampleState.wait(42)

// Promise will resolve when the function returns `true`.
await ExampleState.wait((state) => fulfillsSomeCondition(state))

dispose​

Inherited from: SimpleStateManager.dispose

Disposes the State Manager when it is no longer in use. This will remove all watchers and prevent new ones from being added.

dispose(): void

Parameters​

dispose does not take any parameters.

Returns​

dispose does not return anything.

Example​

ExampleState.dispose()