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: YesallowedStateTransitions
— The list of allowed state transitions.
Type:Array
(ofStateTransition
)
Required: Yesoptions
— 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
still
,walking
, orattacking
; - can perform an attack only when standing still.
This would roughly translate into the following code:
import { SimpleFiniteStateManager } from 'cotton-box'
class PlayableCharacter {
readonly state = new SimpleFiniteStateManager('still', [
['still', 'walking'],
['still', 'attacking'],
['walking', 'still'],
['attacking', 'still'],
], {
name: 'PlayableCharacter',
})
}
Since the initial state is 'still'
, 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
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.
set(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.
set(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()
watch
Inherited from: SimpleStateManager.watch
Watch for state changes.
watch(callback: (state: State, eventType: StateChangeEventType) => 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.
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()