Enum State Machine for Crystal
enum_state_machine is a type-safe finite state machine for Crystal where the states are defined using enum's. I created it because I wanted the minimal FSM data type that was function and easy to use.
Installation
-
Add the dependency to your
shard.yml:dependencies: enum_state_machine: github: nogginly/enum_state_machine.cr -
Run
shards install
Usage
Here's a single example that illustrates how to use enum_state_machine to setup a toy Player class with two statuses, Action and Health, and their respective state machines.
require "enum_state_machine"
module MyGame
enum Action
Idle
Walk
Run
Jump
Attack
end
enum Health
Alive
Dead
end
class Player
include EnumStateMachine
state_machine(Action, initial: Action::Idle) do
event :idle, # from any state except these
except_from: {Action::Idle, Action::Jump}, to: Action::Idle
event :jump, # from one of many states
from: {Action::Walk, Action::Run, Action::Idle}, to: Action::Jump
event :attack, # from one state
from: Action::Idle, to: Action::Attack
event :run, to: Action::Run
end
state_machine(Health, initial: Health::Alive) do
event :die, # from one state
from: Health::Alive, to: Health::Dead
event :resurrect, # from a state, with a guard
from: Health::Dead, to: Health::Alive,
guard: ->{ idle? }
end
end
Each event do_this adds the following capability methods:
do_thisattempts to perform the transitiondo_this(&)which yields after successfully performing transitionmay_do_this?returns true of the transition may be performed
Each state machine for an enum Feeling adds the following methods:
feelingwhich returns the current value of theFeelingstate- for each enumeration of
Feeling, sayFeeling::KindandFeeling::Sadkind?which returns true of the current value offeelingisFeeling::Kindsad?- and so on.
To do
In no particular order:
- More examples for the various ways to define and use
enum_state_machine - Document possible compile errors
- Event transition failure handler (like
guard) - Multiple transitions for a single event
- Test suite
Contributing
Bug reports and sugestions are welcome. Otherwise, at this time, this project is closed for code changes and pull requests. I appreciate your understanding.
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
This shard is available as open source under the terms of the MIT License.
Contributors
- nogginly - creator and maintainer