Commit 82a6511b authored by Dominik Charousset's avatar Dominik Charousset

Fix namespaces and minor mistakes

This patch closes #223 (still using `cppa` namespace) and closes #224 (error in
lambda expression).
parent 3af15a6e
...@@ -18,7 +18,7 @@ self->trap_exit(true); ...@@ -18,7 +18,7 @@ self->trap_exit(true);
self->link_to(worker); self->link_to(worker);
// wait until worker exited // wait until worker exited
self->become ( self->become (
[](const exit_msg& e) >> [=] { [=](const exit_msg& e) {
if (e.reason == exit_reason::normal) { if (e.reason == exit_reason::normal) {
// worker finished computation // worker finished computation
else { else {
...@@ -54,8 +54,8 @@ self->become ( ...@@ -54,8 +54,8 @@ self->become (
\subsection{Error Codes} \subsection{Error Codes}
All error codes are defined in the namespace \lstinline^cppa::exit_reason^. All error codes are defined in the namespace \lstinline^caf::exit_reason^.
To obtain a string representation of an error code, use \lstinline^cppa::exit_reason::as_string(uint32_t)^. To obtain a string representation of an error code, use \lstinline^caf::exit_reason::as_string(uint32_t)^.
\begin{tabular*}{\textwidth}{m{0.35\textwidth}m{0.08\textwidth}m{0.5\textwidth}} \begin{tabular*}{\textwidth}{m{0.35\textwidth}m{0.08\textwidth}m{0.5\textwidth}}
\hline \hline
...@@ -81,23 +81,24 @@ To obtain a string representation of an error code, use \lstinline^cppa::exit_re ...@@ -81,23 +81,24 @@ To obtain a string representation of an error code, use \lstinline^cppa::exit_re
Actors can attach cleanup code to other actors. Actors can attach cleanup code to other actors.
This code is executed immediately if the actor has already exited. This code is executed immediately if the actor has already exited.
Keep in mind that \lstinline^self^ refers to the currently running actor.
Thus, \lstinline^self^ refers to the terminating actor and not to the actor that attached a functor to it.
\begin{lstlisting} \begin{lstlisting}
auto worker = spawn(...); using done_atom = atom_constant<atom("done")>;
actor observer = self;
// "monitor" spawned actor behavior supervisor(event_based_actor* self, actor worker) {
worker->attach_functor([observer](std::uint32_t reason) { actor observer = self;
// "monitor" spawned actor
worker->attach_functor([observer](std::uint32_t reason) {
// this callback is invoked from worker // this callback is invoked from worker
anon_send(observer, atom("DONE")); anon_send(observer, done_atom::value);
}); });
// wait until worker exited // wait until worker exited
self->become ( return {
on(atom("DONE")) >> [] { [](done_atom) {
// worker terminated // ... worker terminated ...
} }
); };
}
\end{lstlisting} \end{lstlisting}
\textbf{Note}: It is possible to attach code to remote actors, but the cleanup code will run on the local machine. \textbf{Note}: It is possible to attach code to remote actors, but the cleanup code will run on the local machine.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
\subsection{Class \texttt{option}} \subsection{Class \texttt{option}}
\label{Appendix::Option} \label{Appendix::Option}
Defined in header \lstinline^"cppa/option.hpp"^. Defined in header \lstinline^"caf/option.hpp"^.
\begin{lstlisting} \begin{lstlisting}
template<typename T> template<typename T>
...@@ -56,8 +56,8 @@ Represents an optional value. ...@@ -56,8 +56,8 @@ Represents an optional value.
When using \lstinline^cout^ from multiple actors, output often appears interleaved. When using \lstinline^cout^ from multiple actors, output often appears interleaved.
Moreover, using \lstinline^cout^ from multiple actors -- and thus from multiple threads -- in parallel should be avoided regardless, since the standard does not guarantee a thread-safe implementation. Moreover, using \lstinline^cout^ from multiple actors -- and thus from multiple threads -- in parallel should be avoided regardless, since the standard does not guarantee a thread-safe implementation.
By replacing \texttt{std::cout} with \texttt{cppa::aout}, actors can achieve a concurrency-safe text output. By replacing \texttt{std::cout} with \texttt{caf::aout}, actors can achieve a concurrency-safe text output.
The header \lstinline^cppa/cppa.hpp^ also defines overloads for \texttt{std::endl} and \texttt{std::flush} for \lstinline^aout^, but does not support the full range of ostream operations (yet). The header \lstinline^caf/all.hpp^ also defines overloads for \texttt{std::endl} and \texttt{std::flush} for \lstinline^aout^, but does not support the full range of ostream operations (yet).
Each write operation to \texttt{aout} sends a message to a `hidden' actor (keep in mind, sending messages from actor constructors is not safe). Each write operation to \texttt{aout} sends a message to a `hidden' actor (keep in mind, sending messages from actor constructors is not safe).
This actor only prints lines, unless output is forced using \lstinline^flush^. This actor only prints lines, unless output is forced using \lstinline^flush^.
The example below illustrates printing of lines of text from multiple actors (in random order). The example below illustrates printing of lines of text from multiple actors (in random order).
...@@ -66,9 +66,9 @@ The example below illustrates printing of lines of text from multiple actors (in ...@@ -66,9 +66,9 @@ The example below illustrates printing of lines of text from multiple actors (in
#include <chrono> #include <chrono>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include "cppa/cppa.hpp" #include "caf/all.hpp"
using namespace cppa; using namespace caf;
using std::endl; using std::endl;
int main() { int main() {
......
...@@ -7,11 +7,13 @@ All functions shown in this section can be accessed by including the header \lst ...@@ -7,11 +7,13 @@ All functions shown in this section can be accessed by including the header \lst
\subsection{Publishing of Actors} \subsection{Publishing of Actors}
\begin{lstlisting} \begin{lstlisting}
uint16_t publish(actor whom, uint16_t port, const char* addr = 0, bool reuse_addr = false) uint16_t publish(actor whom, uint16_t port,
const char* addr = nullptr,
bool reuse_addr = false)
\end{lstlisting} \end{lstlisting}
The function \lstinline^publish^ binds an actor to a given port. The function \lstinline^publish^ binds an actor to a given port.
To choose the next high-level port available available for binding, one can specify \lstinline^port == 0^ and retrieves the bound port as return value. To choose the next high-level port available for binding, one can specify \lstinline^port == 0^ and retrieves the bound port as return value.
The return value is equal to \lstinline^port^ if \lstinline^port != 0^. The return value is equal to \lstinline^port^ if \lstinline^port != 0^.
The function throws \lstinline^network_error^ if socket related errors occur or \lstinline^bind_failure^ if the specified port is already in use. The function throws \lstinline^network_error^ if socket related errors occur or \lstinline^bind_failure^ if the specified port is already in use.
The optional \lstinline^addr^ parameter can be used to listen only to the given address. The optional \lstinline^addr^ parameter can be used to listen only to the given address.
...@@ -32,12 +34,14 @@ self->become ( ...@@ -32,12 +34,14 @@ self->become (
); );
\end{lstlisting} \end{lstlisting}
To close a socket, e.g., to allow other actors to be published at the port, the function \lstinline^unpublish^ can be used: To close a socket, e.g., to allow other actors to be published at the port, the function \lstinline^unpublish^ can be used.
This function is called implicitly if a published actor terminates.
\begin{lstlisting} \begin{lstlisting}
void unpublish(caf::actor whom, uint16_t port) void unpublish(caf::actor whom, uint16_t port)
\end{lstlisting} \end{lstlisting}
\clearpage
\subsection{Connecting to Remote Actors} \subsection{Connecting to Remote Actors}
\begin{lstlisting} \begin{lstlisting}
......
\section{Spawning Actors} \section{Spawning Actors}
Actors are created using the function \lstinline^spawn^. Actors are created using the function \lstinline^spawn^.
%The arguments passed to \lstinline^spawn^ depend on the actor's implementation. The easiest way to implement actors is to use functors, e.g., a free function or a lambda expression.
%\subsection{Using \lstinline^spawn^ to Create Actors from Functors or Classes}
The easiest way to implement actors is to use functors, e.g., a free function or lambda expression.
The arguments to the functor are passed to \lstinline^spawn^ as additional arguments. The arguments to the functor are passed to \lstinline^spawn^ as additional arguments.
The function \lstinline^spawn^ also takes optional flags as template parameter. The function \lstinline^spawn^ also takes optional flags as template parameter.
%The optional template parameter of \lstinline^spawn^ decides whether an actor should run in its own thread or takes place in the cooperative scheduling. %The optional template parameter of \lstinline^spawn^ decides whether an actor should run in its own thread or takes place in the cooperative scheduling.
The flag \lstinline^detached^ causes \lstinline^spawn^ to create a thread-mapped actor (opt-out of the cooperative scheduling), the flag \lstinline^linked^ links the newly created actor to its parent -- not available on top-level spawn -- and the flag \lstinline^monitored^ automatically adds a monitor to the new actor. The flag \lstinline^detached^ causes \lstinline^spawn^ to assign a dedicated thread to the actor, i.e., to opt-out of the cooperative scheduling.
Actors that make use of the blocking API (see Section \ref{Sec::BlockingAPI}) must be spawned using the flag \lstinline^blocking_api^. Convenience flags like \lstinline^linked^ or \lstinline^monitored^ automatically link or monitor to the newly created actor.
Naturally, these two flags are not available on ``top-level'' spawns.
Actors that make use of the blocking API---see Section \ref{Sec::BlockingAPI}---must be spawned using the flag \lstinline^blocking_api^.
Flags are concatenated using the operator \lstinline^+^, as shown in the examples below. Flags are concatenated using the operator \lstinline^+^, as shown in the examples below.
\begin{lstlisting} \begin{lstlisting}
#include "cppa/cppa.hpp" #include "caf/all.hpp"
using namespace caf;
using namespace cppa;
void my_actor1(); void my_actor1();
void my_actor2(event_based_actor*, int arg1, const std::string& arg2); void my_actor2(event_based_actor*, int arg1, const std::string& arg2);
void ugly_duckling(); void ugly_duckling(blocking_actor*);
class my_actor3 : public event_based_actor { /* ... */ }; class my_actor3 : public event_based_actor { /* ... */ };
class my_actor4 : public sb_actor<my_actor4> { class my_actor4 : public event_based_actor {
public: my_actor4(int some_value) { /* ... */ } public: my_actor4(int some_value) { /* ... */ }
/* ... */ /* ... */
}; };
...@@ -30,26 +29,26 @@ class my_actor4 : public sb_actor<my_actor4> { ...@@ -30,26 +29,26 @@ class my_actor4 : public sb_actor<my_actor4> {
// we have to spawn it using the self pointer, otherwise // we have to spawn it using the self pointer, otherwise
// we can use the free function 'spawn' (top-level spawn) // we can use the free function 'spawn' (top-level spawn)
void server(event_based_actor* self) { void server(event_based_actor* self) {
// spawn function-based actors // spawn functor-based actors
auto a0 = spawn(my_actor1); auto a0 = self->spawn(my_actor1);
auto a1 = self->spawn<linked>(my_actor2, 42, "hello actor"); auto a1 = self->spawn<linked>(my_actor2, 42, "hello actor");
auto a2 = self->spawn<monitored>([] { /* ... */ }); auto a2 = self->spawn<monitored>([] { /* ... */ });
auto a3 = spawn([](int) { /* ... */ }, 42); auto a3 = self->spawn([](int) { /* ... */ }, 42);
// spawn thread-mapped actors // spawn thread-mapped actors
auto a4 = spawn<detached>(my_actor1); auto a4 = self->spawn<detached>(my_actor1);
auto a5 = self->spawn<detached + linked>([] { /* ... */ }); auto a5 = self->spawn<detached + linked>([] { /* ... */ });
auto a6 = spawn<detached>(my_actor2, 0, "zero"); auto a6 = self->spawn<detached>(my_actor2, 0, "zero");
// spawn class-based actors // spawn class-based actors
auto a7 = spawn<my_actor3>(); auto a7 = self->spawn<my_actor3>();
auto a8 = self->spawn<my_actor4, monitored>(42); auto a8 = self->spawn<my_actor4, monitored>(42);
// spawn thread-mapped actors using a class // spawn and detach class-based actors
auto a9 = spawn<my_actor4, detached>(42); auto a9 = self->spawn<my_actor4, detached>(42);
// spawn actors that need access to the blocking API // spawn actors that need access to the blocking API
auto aa = self->spawn<blocking_api>(ugly_duckling); auto aa = self->spawn<blocking_api>(ugly_duckling);
// compiler error: my_actor2 captures the implicit // compiler error: my_actor2 captures the implicit
// self pointer as event_based_actor* and thus cannot // self pointer as event_based_actor* and thus cannot
// be spawned using blocking_api flag // be spawned using the `blocking_api` flag
/*-auto ab = self->spawn<blocking_api>(my_actor2);-*/ // --- auto ab = self->spawn<blocking_api>(my_actor2);
} }
\end{lstlisting} \end{lstlisting}
......
...@@ -10,10 +10,13 @@ Unlike \lstinline^std::type_info::name()^, \lstinline^uniform_type_info::name()^ ...@@ -10,10 +10,13 @@ Unlike \lstinline^std::type_info::name()^, \lstinline^uniform_type_info::name()^
\begin{lstlisting} \begin{lstlisting}
// creates a signed, 32 bit integer // creates a signed, 32 bit integer
cppa::object i = cppa::uniform_typeid<int>()->create(); uniform_value i = uniform_typeid<int>()->create();
\end{lstlisting} \end{lstlisting}
However, you should rarely if ever need to use \lstinline^object^ or \lstinline^uniform_type_info^. You should rarely, if ever, need to use \lstinline^uniform_value^ or \lstinline^uniform_type_info^.
The type \lstinline^uniform_value^ stores a type-erased pointer along with the associated \lstinline^uniform_type_info^.
The sole purpose of this simple abstraction is to enable the pattern matching engine of \lib to query the type information and then dispatch the value to a message handler.
When using a \lstinline^message_builder^, each element is stored as a \lstinline^uniform_value^.
\subsection{User-Defined Data Types in Messages} \subsection{User-Defined Data Types in Messages}
\label{Sec::TypeSystem::UserDefined} \label{Sec::TypeSystem::UserDefined}
...@@ -21,20 +24,18 @@ However, you should rarely if ever need to use \lstinline^object^ or \lstinline^ ...@@ -21,20 +24,18 @@ However, you should rarely if ever need to use \lstinline^object^ or \lstinline^
All user-defined types must be explicitly ``announced'' so that \lib can (de)serialize them correctly, as shown in the example below. All user-defined types must be explicitly ``announced'' so that \lib can (de)serialize them correctly, as shown in the example below.
\begin{lstlisting} \begin{lstlisting}
#include "cppa/cppa.hpp" #include "caf/all.hpp"
using namespace cppa;
struct foo { int a; int b; }; struct foo { int a; int b; };
int main() { int main() {
announce<foo>("foo", &foo::a, &foo::b); caf::announce<foo>("foo", &foo::a, &foo::b);
// ... foo can now safely be used in messages ... // ... foo can now safely be used in messages ...
} }
\end{lstlisting} \end{lstlisting}
Without the \lstinline^announce^ function call, the example program would terminate with an exception, because \lib rejects all types without available runtime type information. Without announcing \lstinline^foo^, \lib is not able to (de)serialize instances of it.
The function \lstinline^announce()^ takes the class as template parameter.
\lstinline^announce()^ takes the class as template parameter.
The first argument to the function always is the type name followed by pointers to all members (or getter/setter pairs). The first argument to the function always is the type name followed by pointers to all members (or getter/setter pairs).
This works for all primitive data types and STL compliant containers. This works for all primitive data types and STL compliant containers.
See the announce examples 1 -- 4 of the standard distribution for more details. See the announce examples 1 -- 4 of the standard distribution for more details.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment