tin  1.5.9
actors

Purpose

Actors compose local components under an execution loop that the application owns. An actor can wrap an HSM runtime, a driver adapter, a replay source, a simulator endpoint, or a reporting sink.

An actor exposes local work through a common cooperative surface:

bool step();
std::size_t drain();
bool empty() const;
std::size_t pending_events() const;

step() performs at most one unit of immediate work. drain() repeats local work until the actor reports no more progress. empty() and pending_events() report backlog.

API Entry Points

  • tin::actor_like<T> for the step/drain actor shape.
  • tin::actor_sink<T, Event> for components that accept one typed event.
  • tin::actor_source<T, Event> for components that produce one typed event.
  • tin::input_port<Event, Sink> and tin::output_port<Event, Source>.
  • tin::make_input_port<Event>(sink) and tin::make_output_port<Event>(source).
  • tin::actor_link<Source, Sink> for typed handoff with one pending retry slot.
  • tin::link_all(link_a, link_b, ...) for stepping several links in order.
  • tin::actor_group<Actors...> for declaration-order actor stepping.
  • tin::actor_group_resources<Actors...> for compile-time resource summaries.

Actor Link Retry

actor_link is the transfer primitive. It moves at most one value per step(). If it removes a value from the source and the sink rejects it because bounded storage is full, the link keeps that value in its pending slot and retries later.

auto output = tin::make_output_port<Sample>(sensor);
auto input = tin::make_input_port<Sample>(controller);
tin::actor_link sample_to_controller{ output, input };
if (!sample_to_controller.step() && sample_to_controller.pending()) {
// The sink was full; the value is retained for a later step.
}
actor_link(Source &, Sink &) -> actor_link< Source, Sink >

There is no best-effort free link(source, sink) shortcut. Use actor_link so the retry behavior is explicit and testable.

Actor Group Order

actor_group stores non-owning references and visits actors in declaration order.

tin::actor_group actors{ sensor, controller, reporter };
while (!actors.empty()) {
(void)sample_to_controller.step();
(void)actors.step();
(void)report_to_sink.step();
}
actor_group(Actors &...) -> actor_group< Actors... >

actor_group::drain() repeats declaration-order rounds until no actor reports progress.

Execution Context

Actors do not create threads or callbacks. The execution context is the caller: a test body, a bare-metal superloop, an RTOS task, a Linux realtime thread, a simulator loop, or a platform adapter.

for (;;) {
poll_inputs();
(void)links.step();
(void)actors.drain();
wait_for_next_tick_or_interrupt();
}

Related pages: