Packages

Type-safe finite state machine library for Gleam

Current section

Files

Jump to
scamper src scamper@actor.erl
Raw

src/scamper@actor.erl

-module(scamper@actor).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/scamper/actor.gleam").
-export([start/3, send_event/3, get_state/2, get_context/2, get_machine/2]).
-export_type([message/3]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" OTP actor wrapper for scamper FSMs.\n"
"\n"
" Provides a thin wrapper around `gleam/otp/actor` to run a state machine\n"
" as an OTP-compatible process. Events are serialized (processed one at a\n"
" time) and the pure FSM logic remains fully testable without OTP.\n"
).
-opaque message(ICS, ICT, ICU) :: {send_event,
ICU,
gleam@erlang@process:subject({ok, scamper:machine(ICS, ICT, ICU)} |
{error, scamper@error:transition_error(ICS, ICU)})} |
{get_state, gleam@erlang@process:subject(ICS)} |
{get_context, gleam@erlang@process:subject(ICT)} |
{get_machine, gleam@erlang@process:subject(scamper:machine(ICS, ICT, ICU))}.
-file("src/scamper/actor.gleam", 42).
-spec handle_message(scamper:machine(IDI, IDJ, IDK), message(IDI, IDJ, IDK)) -> gleam@otp@actor:next(scamper:machine(IDI, IDJ, IDK), message(IDI, IDJ, IDK)).
handle_message(Machine, Message) ->
case Message of
{send_event, Event, Reply_to} ->
Result = scamper:transition(Machine, Event),
gleam@erlang@process:send(Reply_to, Result),
case Result of
{ok, New_machine} ->
gleam@otp@actor:continue(New_machine);
{error, _} ->
gleam@otp@actor:continue(Machine)
end;
{get_state, Reply_to@1} ->
gleam@erlang@process:send(
Reply_to@1,
scamper:current_state(Machine)
),
gleam@otp@actor:continue(Machine);
{get_context, Reply_to@2} ->
gleam@erlang@process:send(
Reply_to@2,
scamper:current_context(Machine)
),
gleam@otp@actor:continue(Machine);
{get_machine, Reply_to@3} ->
gleam@erlang@process:send(Reply_to@3, Machine),
gleam@otp@actor:continue(Machine)
end.
-file("src/scamper/actor.gleam", 28).
?DOC(
" Start an FSM actor process.\n"
" Returns the actor's subject for sending messages.\n"
).
-spec start(scamper@config:config(ICV, ICW, ICX), ICV, ICW) -> {ok,
gleam@otp@actor:started(gleam@erlang@process:subject(message(ICV, ICW, ICX)))} |
{error, gleam@otp@actor:start_error()}.
start(Config, Initial_state, Context) ->
Machine = scamper:new(Config, Initial_state, Context),
_pipe = gleam@otp@actor:new(Machine),
_pipe@1 = gleam@otp@actor:on_message(_pipe, fun handle_message/2),
gleam@otp@actor:start(_pipe@1).
-file("src/scamper/actor.gleam", 72).
?DOC(
" Send an event to the FSM actor and wait for the result.\n"
" Times out after `timeout` milliseconds.\n"
).
-spec send_event(
gleam@erlang@process:subject(message(IDZ, IEA, IEB)),
IEB,
integer()
) -> {ok, scamper:machine(IDZ, IEA, IEB)} |
{error, scamper@error:transition_error(IDZ, IEB)}.
send_event(Subject, Event, Timeout) ->
gleam@otp@actor:call(
Subject,
Timeout,
fun(Reply_to) -> {send_event, Event, Reply_to} end
).
-file("src/scamper/actor.gleam", 83).
?DOC(" Query the current state of the FSM actor.\n").
-spec get_state(
gleam@erlang@process:subject(message(IEN, any(), any())),
integer()
) -> IEN.
get_state(Subject, Timeout) ->
gleam@otp@actor:call(
Subject,
Timeout,
fun(Reply_to) -> {get_state, Reply_to} end
).
-file("src/scamper/actor.gleam", 93).
?DOC(" Query the current context of the FSM actor.\n").
-spec get_context(
gleam@erlang@process:subject(message(any(), IEV, any())),
integer()
) -> IEV.
get_context(Subject, Timeout) ->
gleam@otp@actor:call(
Subject,
Timeout,
fun(Reply_to) -> {get_context, Reply_to} end
).
-file("src/scamper/actor.gleam", 103).
?DOC(" Get the full machine from the actor.\n").
-spec get_machine(
gleam@erlang@process:subject(message(IFB, IFC, IFD)),
integer()
) -> scamper:machine(IFB, IFC, IFD).
get_machine(Subject, Timeout) ->
gleam@otp@actor:call(
Subject,
Timeout,
fun(Reply_to) -> {get_machine, Reply_to} end
).