Use 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 :assign, &increment/1
on :toggle, do: target :inactive
end
state :inactive do
on :toggle, do: target :active
end
def increment(%{context: context}), do: %{count: context.count + 1}
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 :after_time?, %{time: "00:00"}
end
end
def toggle?(%{context: context}), do: context.activate?
def 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
def notify_not_allowed(%{context: context}) do
IO.puts("Cannot be toggled")
context
end
endActions
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 :notify, %{message: "Some notification"}
end
end
def activate(_) do
# ...
end
def deactivate(_) do
# ...
end
def notify(_) do
# ...
end
def notify(_, %{message: _}) do
# ...
end
end