\lstinline^any_tuple last_dequeued()^& Returns the last message that was dequeued from the actor's mailbox\newline\textbf{Note}: Only set during callback invocation \\
\hline
\lstinline^actor_ptr last_sender()^& Returns the sender of the last dequeued message\newline\textbf{Note$_{1}$}: Only set during callback invocation\newline\textbf{Note$_{2}$}: Used by the function \lstinline^reply^ (see Section \ref{Sec::Send::Reply}) \\
\lstinline^actor_ptr last_sender()^& Returns the sender of the last dequeued message\newline\textbf{Note$_{1}$}: Only set during callback invocation\newline\textbf{Note$_{2}$}: Used implicitly to send response messages (see Section \ref{Sec::Send::Reply}) \\
\hline
\lstinline^vector<group_ptr> joined_groups()^& Returns all subscribed groups \\
@@ -25,13 +25,12 @@ Related functions, e.g., \lstinline^sync_send(...).then(...)^, behave the same,
\begin{itemize}
\item
\lstinline^send(self->last_sender(), ...)^ is \textbf{not} equal to \lstinline^reply(...)^.
The two functions \lstinline^receive_response^ and \lstinline^handle_response^ will only recognize messages send via either \lstinline^reply^ or \lstinline^reply_tuple^.
\lstinline^send(self->last_sender(), ...)^ does \textbf{not} send a response message.
\item
A handle returned by \lstinline^sync_send^ represents \emph{exactly one} response message.
Therefore, it is not possible to receive more than one response message.
Calling \lstinline^reply^ more than once will result in lost messages and calling \lstinline^handle_response^ or \lstinline^receive_response^ more than once on a future will throw an exception.
%Calling \lstinline^reply^ more than once will result in lost messages and calling \lstinline^handle_response^ or \lstinline^receive_response^ more than once on a future will throw an exception.
\item
The future returned by \lstinline^sync_send^ is bound to the calling actor.
@@ -35,24 +35,18 @@ Choosing one or the other is merely a matter of personal preferences.
\subsection{Replying to Messages}
\label{Sec::Send::Reply}
The return value of a message handler is used as response message.
During callback invokation, \lstinline^self->last_sender()^ is set.
This identifies the sender of the received message and is used implicitly by the functions \lstinline^reply^ and \lstinline^reply_tuple^.
Using \lstinline^reply(...)^ is \textbf{not} equal to \lstinline^send(self->last_sender(), ...)^.
The function \lstinline^send^ always uses asynchronous message passing, whereas \lstinline^reply^ will send a synchronous response message if the received message was a synchronous request (see Section \ref{Sec::Sync}).
%Note that you cannot reply more than once.
To delay a response, i.e., reply to a message after receiving another message, actors can use \lstinline^self->make_response_handle()^.
The functions \lstinline^reply_to^ and \lstinline^reply_tuple_to^ then can be used to reply the the original request, as shown in the example below.
This identifies the sender of the received message and is used implicitly to reply to the correct sender.
However, using \lstinline^send(self->last_sender(), ...)^ does \emph{not} reply to the message, i.e., synchronous messages will not recognize the message as response.
Strongly typed actors provide a convenient way of defining type-safe messaging interfaces.
Unlike ``dynamic actors'', typed actors are not allowed to change their behavior at runtime, neither are typed actors allowed to use guard expressions.
When calling \lstinline^become^ in a strongly typed actor, the actor will be killed with exit reason \lstinline^unallowed_function_call^.
Typed actors use \lstinline^typed_actor_ptr<...>^ instead of \lstinline^actor_ptr^, whereas the template parameters hold the messaging interface.
For example, an actor responding to two integers with a dobule would use the type \lstinline^typed_actor_ptr<replies_to<int, int>::with<double>>^.
\subsection{Spawning Typed Actors}
\label{sec:strong:spawn}
Actors are spawned using the function \lstinline^spawn_typed^.
The argument to this function call \emph{must} be a match expression as shown in the example below, because the runtime of libcppa needs to evaluate the signature of each message handler.
\begin{lstlisting}
auto p0 = spawn_typed(
on_arg_match >> [](int a, int b) {
return static_cast<double>(a) * b;
},
on_arg_match >> [](double a, double b) {
return make_cow_tuple(a * b, a / b);
}
);
// assign to identical type
using full_type = typed_actor_ptr<
replies_to<int, int>::with<double>,
replies_to<double, double>::with<double, double>
>;
full_type p1 = p0;
// assign to subtype
using subtype1 = typed_actor_ptr<
replies_to<int, int>::with<double>
>;
subtype1 p2 = p0;
// assign to another subtype
using subtype2 = typed_actor_ptr<
replies_to<double, double>::with<double, double>
>;
subtype1 p3 = p0;
\end{lstlisting}
All functions for message passing, linking and monitoring are overloaded to accept both types of actors.
As of version 0.8, strongly typed actors cannot be published (this is a planned feature for future releases).
\subsubsection{Continuations for Event-based Actors}
\libcppa supports continuations to enable chaining of send/receive statements.
The functions \lstinline^handle_response^ and \lstinline^message_future::then^ both return a helper object offering \lstinline^continue_with^, which takes a functor $f$ without arguments.
The functions \lstinline^handle_response^ and \lstinline^message_future::then^ both return a helper object offering the member function \lstinline^continue_with^, which takes a functor $f$ without arguments.
After receiving a message, $f$ is invoked if and only if the received messages was handled successfully, i.e., neither \lstinline^sync_failure^ nor \lstinline^sync_timeout^ occurred.