Cheatsheet
View SourceUse this cheatsheet to quickly lookup the APIs for XFsm.
Examples
Creating a state machine
defmodule ToggleMachine do
use XFsm.Actor
use XFsm.Machine
initial(:active)
context(%{count: 0})
state :active do
entry(assigns(%{count: &(&1.context.count +1)}))
on :toggle, do: target(:inactive)
end
state :inactive do
on :toggle, do: target(:active)
end
end
alias XFsm.Actor
{:ok, pid} = ToggleMachine.start_link()
Actor.subscribe(pid, &IO.puts/1)
Actor.send(pid, %{type: :toggle})
# logs 'inactive' with context %{count: 1}
Actor.send(pid, %{type: :toggle})
# logs 'active' with context %{count: 2}
Actor.send(pid, %{type: :toggle})
# logs 'inactive' with context %{count: 2}
Guards
defmodule ToggleMachine do
use XFsm.Actor
use XFsm.Machine
initial(:active)
context(%{activate?: false})
state :inactive do
on :toggle do
target(:active)
guard(:toggle?)
end
on :toggle do
action(:notify_not_allowed)
end
end
state :active do
on :toggle do
target(:inactive)
guard(%{
method: :after_time?,
params: %{time: "00:00"}
})
end
end
defg toggle?(%{context: context}), do: context.activate?
defg after_time?(_, %{time: time}) do
now = DateTime.utc_now()
[hour, minute] = String.split(time, ":")
{hour, ""} = Integer.parse(hour)
{minute, ""} = Integer.parse(minute)
now.hour > hour and now.minute > minute
end
defa notify_not_allowed(%{context: context}) do
IO.puts("Cannot be toggled")
context
end
end
Actions
defmodule ToggleMachine do
use XFsm.Actor
use XFsm.Machine
initial(:active)
state :active do
entry(:activate)
exit(:deactivate)
on :toggle do
target(:inactive)
action(:notify)
end
end
state :inactive do
on :toggle do
target(:active)
action(%{
method: :notify,
params: %{message: "Some notification"}
})
end
end
defa activate(_) do
# ...
end
defa deactivate(_) do
# ...
end
defa notify(_, %{message: _}) do
# ...
end
end