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 {
class timeout_definition_builder {
public:
constexpr timeout_definition_builder(const duration& d) : tout_(d) {
constexpr timeout_definition_builder(duration d) : tout_(d) {
// nop
}
......@@ -43,10 +43,8 @@ private:
};
/// Returns a generator for timeouts.
template <class Rep, class Period>
constexpr timeout_definition_builder
after(const std::chrono::duration<Rep, Period>& d) {
return {duration(d)};
constexpr timeout_definition_builder after(duration d) {
return {d};
}
} // namespace caf
......
......@@ -27,6 +27,7 @@
#include "caf/fwd.hpp"
#include "caf/send.hpp"
#include "caf/none.hpp"
#include "caf/after.hpp"
#include "caf/extend.hpp"
#include "caf/behavior.hpp"
#include "caf/local_actor.hpp"
......@@ -336,10 +337,14 @@ public:
tl_size<filtered>::value, sizeof...(Ts)
>::type;
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);
}
/// 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.
template <class... Ts>
void varargs_receive(receive_cond& rcc, message_id mid, Ts&&... xs) {
......
......@@ -29,9 +29,9 @@ namespace detail {
class blocking_behavior {
public:
behavior nested;
behavior& nested;
blocking_behavior(behavior nested);
blocking_behavior(behavior& nested);
blocking_behavior(blocking_behavior&&) = default;
virtual ~blocking_behavior();
......@@ -48,8 +48,8 @@ class blocking_behavior_v2 : public blocking_behavior {
public:
catch_all<F> f;
blocking_behavior_v2(behavior x, catch_all<F> y)
: blocking_behavior(std::move(x)),
blocking_behavior_v2(behavior& x, catch_all<F> y)
: blocking_behavior(x),
f(std::move(y)) {
// nop
}
......@@ -66,8 +66,8 @@ class blocking_behavior_v3 : public blocking_behavior {
public:
timeout_definition<F> f;
blocking_behavior_v3(behavior x, timeout_definition<F> y)
: blocking_behavior(std::move(x)),
blocking_behavior_v3(behavior& x, timeout_definition<F> y)
: blocking_behavior(x),
f(std::move(y)) {
// nop
}
......@@ -89,8 +89,8 @@ public:
catch_all<F1> f1;
timeout_definition<F2> f2;
blocking_behavior_v4(behavior x, catch_all<F1> y, timeout_definition<F2> z)
: blocking_behavior(std::move(x)),
blocking_behavior_v4(behavior& x, catch_all<F1> y, timeout_definition<F2> z)
: blocking_behavior(x),
f1(std::move(y)),
f2(std::move(z)) {
// nop
......@@ -116,25 +116,29 @@ struct make_blocking_behavior_t {
// nop
}
inline blocking_behavior operator()(behavior x) const {
return {std::move(x)};
inline blocking_behavior operator()(behavior* x) const {
CAF_ASSERT(x != nullptr);
return {*x};
}
template <class F>
blocking_behavior_v2<F> operator()(behavior x, catch_all<F> y) const {
return {std::move(x), std::move(y)};
blocking_behavior_v2<F> operator()(behavior* x, catch_all<F> y) const {
CAF_ASSERT(x != nullptr);
return {*x, std::move(y)};
}
template <class F>
blocking_behavior_v3<F> operator()(behavior x,
blocking_behavior_v3<F> operator()(behavior* x,
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>
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 {
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:
bool running = true;
std::multimap<hrc::time_point, delayed_msg> messages;
// our message handler
auto bhvr = detail::make_blocking_behavior(
behavior{
[&](const duration& d, strong_actor_ptr& from,
strong_actor_ptr& to, message_id mid, message& msg) {
insert_dmsg(messages, d, std::move(from),
std::move(to), mid, std::move(msg));
},
[&](const exit_msg& dm) {
if (dm.reason) {
fail_state(dm.reason);
running = false;
}
}
behavior nested{
[&](const duration& d, strong_actor_ptr& from,
strong_actor_ptr& to, message_id mid, message& msg) {
insert_dmsg(messages, d, std::move(from),
std::move(to), mid, std::move(msg));
},
[&](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> {
std::cerr << "*** unexpected message in timer_actor: "
<< to_string(x.content()) << std::endl;
......
......@@ -396,6 +396,22 @@ mailbox_element_ptr blocking_actor::dequeue() {
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) {
return attach_functor(actor_cast<strong_actor_ptr>(x));
}
......
......@@ -26,7 +26,7 @@ blocking_behavior::~blocking_behavior() {
// nop
}
blocking_behavior::blocking_behavior(behavior x) : nested(std::move(x)) {
blocking_behavior::blocking_behavior(behavior& x) : nested(x) {
// nop
}
......
......@@ -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()
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