Commit ac7dc7c8 authored by Dominik Charousset's avatar Dominik Charousset

Deprecate `sb_actor`, close #265

parent 1403a0db
...@@ -23,21 +23,18 @@ ...@@ -23,21 +23,18 @@
#include <utility> #include <utility>
#include <type_traits> #include <type_traits>
#include "caf/config.hpp"
#include "caf/event_based_actor.hpp" #include "caf/event_based_actor.hpp"
namespace caf { namespace caf {
/// A base class for state-based actors using the // <backward_compatibility version="0.13">
/// Curiously Recurring Template Pattern
/// to initialize the derived actor with its `init_state` member.
template <class Derived, class Base = event_based_actor> template <class Derived, class Base = event_based_actor>
class sb_actor : public Base { class sb_actor : public Base {
public: public:
static_assert(std::is_base_of<event_based_actor, Base>::value, static_assert(std::is_base_of<event_based_actor, Base>::value,
"Base must be event_based_actor or a derived type"); "Base must be event_based_actor or a derived type");
/// Overrides {@link event_based_actor::make_behavior()} and sets
/// the initial actor behavior to `Derived::init_state.
behavior make_behavior() override { behavior make_behavior() override {
return static_cast<Derived*>(this)->init_state; return static_cast<Derived*>(this)->init_state;
} }
...@@ -49,7 +46,8 @@ protected: ...@@ -49,7 +46,8 @@ protected:
sb_actor(Ts&&... xs) : Base(std::forward<Ts>(xs)...) { sb_actor(Ts&&... xs) : Base(std::forward<Ts>(xs)...) {
// nop // nop
} }
}; } CAF_DEPRECATED ;
// </backward_compatibility>
} // namespace caf } // namespace caf
......
...@@ -42,7 +42,6 @@ using c_atom = atom_constant<atom("c")>; ...@@ -42,7 +42,6 @@ using c_atom = atom_constant<atom("c")>;
using abc_atom = atom_constant<atom("abc")>; using abc_atom = atom_constant<atom("abc")>;
using name_atom = atom_constant<atom("name")>; using name_atom = atom_constant<atom("name")>;
void inc_actor_instances() { void inc_actor_instances() {
long v1 = ++s_actor_instances; long v1 = ++s_actor_instances;
long v2 = s_max_actor_instances.load(); long v2 = s_max_actor_instances.load();
...@@ -55,50 +54,49 @@ void dec_actor_instances() { ...@@ -55,50 +54,49 @@ void dec_actor_instances() {
--s_actor_instances; --s_actor_instances;
} }
class event_testee : public sb_actor<event_testee> { class event_testee : public event_based_actor {
public: public:
event_testee(); event_testee() {
~event_testee(); inc_actor_instances();
wait4string.assign(
[=](const std::string&) {
become(wait4int);
},
[=](get_atom) {
return "wait4string";
}
);
wait4float.assign(
[=](float) {
become(wait4string);
},
[=](get_atom) {
return "wait4float";
}
);
wait4int.assign(
[=](int) {
become(wait4float);
},
[=](get_atom) {
return "wait4int";
}
);
}
~event_testee() {
dec_actor_instances();
}
behavior make_behavior() override {
return wait4int;
}
behavior wait4string; behavior wait4string;
behavior wait4float; behavior wait4float;
behavior wait4int; behavior wait4int;
behavior& init_state = wait4int;
}; };
event_testee::event_testee() {
inc_actor_instances();
wait4string.assign(
[=](const std::string&) {
become(wait4int);
},
[=](get_atom) {
return "wait4string";
}
);
wait4float.assign(
[=](float) {
become(wait4string);
},
[=](get_atom) {
return "wait4float";
}
);
wait4int.assign(
[=](int) {
become(wait4float);
},
[=](get_atom) {
return "wait4int";
}
);
}
event_testee::~event_testee() {
dec_actor_instances();
}
// quits after 5 timeouts // quits after 5 timeouts
actor spawn_event_testee2(actor parent) { actor spawn_event_testee2(actor parent) {
struct impl : event_based_actor { struct impl : event_based_actor {
......
...@@ -22,62 +22,41 @@ class printer : public event_based_actor { ...@@ -22,62 +22,41 @@ class printer : public event_based_actor {
}; };
\end{lstlisting} \end{lstlisting}
Another way to implement class-based actors is provided by the class \lstinline^sb_actor^ (``State-Based Actor'').
This base class simply returns \lstinline^init_state^ (defined in the subclass) from its implementation for \lstinline^make_behavior^.
\begin{lstlisting}
struct printer : sb_actor<printer> {
behavior init_state {
others >> [] {
cout << to_string(last_dequeued()) << endl;
}
};
};
\end{lstlisting}
Note that \lstinline^sb_actor^ uses the Curiously Recurring Template Pattern. Thus, the derived class must be given as template parameter.
This technique allows \lstinline^sb_actor^ to access the \lstinline^init_state^ member of a derived class.
The following example illustrates a more advanced state-based actor that implements a stack with a fixed maximum number of elements.
\clearpage \clearpage
\begin{lstlisting} \begin{lstlisting}
using pop_atom = atom_constant<atom("pop")>; using pop_atom = atom_constant<atom("pop")>;
using push_atom = atom_constant<atom("push")>; using push_atom = atom_constant<atom("push")>;
class fixed_stack : public sb_actor<fixed_stack> { class fixed_stack : public event_based_actor {
public: public:
fixed_stack(size_t max) : max_size(max) { fixed_stack(size_t max) : max_size(max) {
full.assign( full_.assign(
[=](push_atom, int) { [=](push_atom, int) {
/* discard */ // discard
}, },
[=](pop_atom) -> message { [=](pop_atom) -> message {
auto result = data.back(); auto result = data.back();
data.pop_back(); data.pop_back();
become(filled); become(filled_);
return make_message(ok_atom::value, result); return make_message(ok_atom::value, result);
} }
); );
filled.assign( filled_.assign(
[=](push_atom, int what) { [=](push_atom, int what) {
data.push_back(what); data.push_back(what);
if (data.size() == max_size) { if (data.size() == max_size) become(full_);
become(full);
}
}, },
[=](pop_atom) -> message { [=](pop_atom) -> message {
auto result = data.back(); auto result = data.back();
data.pop_back(); data.pop_back();
if (data.empty()) { if (data.empty()) become(empty_);
become(empty);
}
return make_message(ok_atom::value, result); return make_message(ok_atom::value, result);
} }
); );
empty.assign( empty_.assign(
[=](push_atom, int what) { [=](push_atom, int what) {
data.push_back(what); data.push_back(what);
become(filled); become(filled_);
}, },
[=](pop_atom) { [=](pop_atom) {
return error_atom::value; return error_atom::value;
...@@ -85,12 +64,15 @@ class fixed_stack : public sb_actor<fixed_stack> { ...@@ -85,12 +64,15 @@ class fixed_stack : public sb_actor<fixed_stack> {
); );
} }
behavior make_behavior() override {
return empty_;
}
size_t max_size; size_t max_size;
std::vector<int> data; std::vector<int> data;
behavior full; behavior full_;
behavior filled; behavior filled_;
behavior empty; behavior empty_;
behavior& init_state = empty;
}; };
\end{lstlisting} \end{lstlisting}
......
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