Commit d8884198 authored by Dominik Charousset's avatar Dominik Charousset

Accept behavior& in receive functions, close #494

parent 7ad680ec
...@@ -29,7 +29,7 @@ namespace caf { ...@@ -29,7 +29,7 @@ namespace caf {
class timeout_definition_builder { class timeout_definition_builder {
public: public:
constexpr timeout_definition_builder(const duration& d) : tout_(d) { constexpr timeout_definition_builder(duration d) : tout_(d) {
// nop // nop
} }
...@@ -43,10 +43,8 @@ private: ...@@ -43,10 +43,8 @@ private:
}; };
/// Returns a generator for timeouts. /// Returns a generator for timeouts.
template <class Rep, class Period> constexpr timeout_definition_builder after(duration d) {
constexpr timeout_definition_builder return {d};
after(const std::chrono::duration<Rep, Period>& d) {
return {duration(d)};
} }
} // namespace caf } // namespace caf
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/send.hpp" #include "caf/send.hpp"
#include "caf/none.hpp" #include "caf/none.hpp"
#include "caf/after.hpp"
#include "caf/extend.hpp" #include "caf/extend.hpp"
#include "caf/behavior.hpp" #include "caf/behavior.hpp"
#include "caf/local_actor.hpp" #include "caf/local_actor.hpp"
...@@ -336,10 +337,14 @@ public: ...@@ -336,10 +337,14 @@ public:
tl_size<filtered>::value, sizeof...(Ts) tl_size<filtered>::value, sizeof...(Ts)
>::type; >::type;
make_blocking_behavior_t factory; make_blocking_behavior_t factory;
auto fun = apply_moved_args_prefixed(factory, tail_indices{}, tup, bhvr); auto fun = apply_moved_args_prefixed(factory, tail_indices{}, tup, &bhvr);
receive_impl(rcc, mid, fun); receive_impl(rcc, mid, fun);
} }
/// Receives messages until either a pre- or postcheck of `rcc` fails.
void varargs_tup_receive(receive_cond& rcc, message_id mid,
std::tuple<behavior&>& tup);
/// Receives messages until either a pre- or postcheck of `rcc` fails. /// Receives messages until either a pre- or postcheck of `rcc` fails.
template <class... Ts> template <class... Ts>
void varargs_receive(receive_cond& rcc, message_id mid, Ts&&... xs) { void varargs_receive(receive_cond& rcc, message_id mid, Ts&&... xs) {
......
...@@ -29,9 +29,9 @@ namespace detail { ...@@ -29,9 +29,9 @@ namespace detail {
class blocking_behavior { class blocking_behavior {
public: public:
behavior nested; behavior& nested;
blocking_behavior(behavior nested); blocking_behavior(behavior& nested);
blocking_behavior(blocking_behavior&&) = default; blocking_behavior(blocking_behavior&&) = default;
virtual ~blocking_behavior(); virtual ~blocking_behavior();
...@@ -48,8 +48,8 @@ class blocking_behavior_v2 : public blocking_behavior { ...@@ -48,8 +48,8 @@ class blocking_behavior_v2 : public blocking_behavior {
public: public:
catch_all<F> f; catch_all<F> f;
blocking_behavior_v2(behavior x, catch_all<F> y) blocking_behavior_v2(behavior& x, catch_all<F> y)
: blocking_behavior(std::move(x)), : blocking_behavior(x),
f(std::move(y)) { f(std::move(y)) {
// nop // nop
} }
...@@ -66,8 +66,8 @@ class blocking_behavior_v3 : public blocking_behavior { ...@@ -66,8 +66,8 @@ class blocking_behavior_v3 : public blocking_behavior {
public: public:
timeout_definition<F> f; timeout_definition<F> f;
blocking_behavior_v3(behavior x, timeout_definition<F> y) blocking_behavior_v3(behavior& x, timeout_definition<F> y)
: blocking_behavior(std::move(x)), : blocking_behavior(x),
f(std::move(y)) { f(std::move(y)) {
// nop // nop
} }
...@@ -89,8 +89,8 @@ public: ...@@ -89,8 +89,8 @@ public:
catch_all<F1> f1; catch_all<F1> f1;
timeout_definition<F2> f2; timeout_definition<F2> f2;
blocking_behavior_v4(behavior x, catch_all<F1> y, timeout_definition<F2> z) blocking_behavior_v4(behavior& x, catch_all<F1> y, timeout_definition<F2> z)
: blocking_behavior(std::move(x)), : blocking_behavior(x),
f1(std::move(y)), f1(std::move(y)),
f2(std::move(z)) { f2(std::move(z)) {
// nop // nop
...@@ -116,25 +116,29 @@ struct make_blocking_behavior_t { ...@@ -116,25 +116,29 @@ struct make_blocking_behavior_t {
// nop // nop
} }
inline blocking_behavior operator()(behavior x) const { inline blocking_behavior operator()(behavior* x) const {
return {std::move(x)}; CAF_ASSERT(x != nullptr);
return {*x};
} }
template <class F> template <class F>
blocking_behavior_v2<F> operator()(behavior x, catch_all<F> y) const { blocking_behavior_v2<F> operator()(behavior* x, catch_all<F> y) const {
return {std::move(x), std::move(y)}; CAF_ASSERT(x != nullptr);
return {*x, std::move(y)};
} }
template <class F> template <class F>
blocking_behavior_v3<F> operator()(behavior x, blocking_behavior_v3<F> operator()(behavior* x,
timeout_definition<F> y) const { timeout_definition<F> y) const {
return {std::move(x), std::move(y)}; CAF_ASSERT(x != nullptr);
return {*x, std::move(y)};
} }
template <class F1, class F2> template <class F1, class F2>
blocking_behavior_v4<F1, F2> operator()(behavior x, catch_all<F1> y, blocking_behavior_v4<F1, F2> operator()(behavior* x, catch_all<F1> y,
timeout_definition<F2> z) const { timeout_definition<F2> z) const {
return {std::move(x), std::move(y), std::move(z)}; CAF_ASSERT(x != nullptr);
return {*x, std::move(y), std::move(z)};
} }
}; };
......
...@@ -87,20 +87,21 @@ public: ...@@ -87,20 +87,21 @@ public:
bool running = true; bool running = true;
std::multimap<hrc::time_point, delayed_msg> messages; std::multimap<hrc::time_point, delayed_msg> messages;
// our message handler // our message handler
auto bhvr = detail::make_blocking_behavior( behavior nested{
behavior{ [&](const duration& d, strong_actor_ptr& from,
[&](const duration& d, strong_actor_ptr& from, strong_actor_ptr& to, message_id mid, message& msg) {
strong_actor_ptr& to, message_id mid, message& msg) { insert_dmsg(messages, d, std::move(from),
insert_dmsg(messages, d, std::move(from), std::move(to), mid, std::move(msg));
std::move(to), mid, std::move(msg));
},
[&](const exit_msg& dm) {
if (dm.reason) {
fail_state(dm.reason);
running = false;
}
}
}, },
[&](const exit_msg& dm) {
if (dm.reason) {
fail_state(dm.reason);
running = false;
}
}
};
auto bhvr = detail::make_blocking_behavior(
&nested,
others >> [&](message_view& x) -> result<message> { others >> [&](message_view& x) -> result<message> {
std::cerr << "*** unexpected message in timer_actor: " std::cerr << "*** unexpected message in timer_actor: "
<< to_string(x.content()) << std::endl; << to_string(x.content()) << std::endl;
......
...@@ -396,6 +396,22 @@ mailbox_element_ptr blocking_actor::dequeue() { ...@@ -396,6 +396,22 @@ mailbox_element_ptr blocking_actor::dequeue() {
return next_message(); return next_message();
} }
void blocking_actor::varargs_tup_receive(receive_cond& rcc, message_id mid,
std::tuple<behavior&>& tup) {
using namespace detail;
auto& bhvr = std::get<0>(tup);
if (bhvr.timeout().valid()) {
auto tmp = after(bhvr.timeout()) >> [&] {
bhvr.handle_timeout();
};
auto fun = make_blocking_behavior(&bhvr, std::move(tmp));
receive_impl(rcc, mid, fun);
} else {
auto fun = make_blocking_behavior(&bhvr);
receive_impl(rcc, mid, fun);
}
}
size_t blocking_actor::attach_functor(const actor& x) { size_t blocking_actor::attach_functor(const actor& x) {
return attach_functor(actor_cast<strong_actor_ptr>(x)); return attach_functor(actor_cast<strong_actor_ptr>(x));
} }
......
...@@ -26,7 +26,7 @@ blocking_behavior::~blocking_behavior() { ...@@ -26,7 +26,7 @@ blocking_behavior::~blocking_behavior() {
// nop // nop
} }
blocking_behavior::blocking_behavior(behavior x) : nested(std::move(x)) { blocking_behavior::blocking_behavior(behavior& x) : nested(x) {
// nop // nop
} }
......
...@@ -60,4 +60,14 @@ CAF_TEST(catch_all) { ...@@ -60,4 +60,14 @@ CAF_TEST(catch_all) {
); );
} }
CAF_TEST(behavior_ref) {
behavior bhvr{
[](int i) {
CAF_CHECK_EQUAL(i, 42);
}
};
self->send(self, 42);
self->receive(bhvr);
}
CAF_TEST_FIXTURE_SCOPE_END() CAF_TEST_FIXTURE_SCOPE_END()
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