defmodule <%= inspect(@module) %> do @moduledoc """ `Finitomata`-based implementation of … """ @fsm """ <%= String.trim(@fsm) %> """ <%= @use_clause %> # State @type t :: %{ __struct__: __MODULE__, name: Finitomata.fsm_name() } defstruct name: nil # Interface @doc """ Starts an FSM under `Finitomata`-driven supervision tree. If `UUID` is available and `name` is not passed (is `nil`,) the name will be generated. """ @spec start_fsm(Finitomata.id(), Finitomata.fsm_name()) :: DynamicSupervisor.on_start_child() def start_fsm(id \\ nil, name \\ nil) case Code.ensure_compiled(UUID) do {:module, UUID} -> def start_fsm(id, nil), do: start_fsm(id, UUID.uuid4()) {:error, _} -> def start_fsm(id, nil), do: raise("add `uuid` to deps to use `nil` as a name") end def start_fsm(id, name) when not is_nil(name) do with {:ok, pid} <- Finitomata.start_fsm(id, name, __MODULE__, %__MODULE__{name: name}), do: {:ok, pid, name} end # Implementation @impl Finitomata <%= for %Finitomata.Transition{from: from, to: to, event: event} <- @transitions, from != :* do %> <%= if to != :* or not @auto_terminate? do %> def on_transition(:<%= from %>, :<%= event %>, _event_payload, state) do {:ok, :<%= to %>, state} end <% end %> <% end %> <%= if @timer? do %> @impl Finitomata def on_timer(_fsm_state, state) do {:ok, state} end <% end %> <%= if :on_enter in @to_implement do %> @impl Finitomata def on_enter(_fsm_state, _state) do :ok end <% end %> <%= if :on_exit in @to_implement do %> @impl Finitomata def on_exit(_fsm_state, _state) do :ok end <% end %> <%= if :on_failure in @to_implement do %> @impl Finitomata def on_failure(_event, _event_payload, _state) do :ok end <% end %> <%= if :on_terminate in @to_implement do %> @impl Finitomata def on_terminate(_state) do :ok end <% end %> end