Commit 5616bec9 authored by Dominik Charousset's avatar Dominik Charousset

Enable composable behaviors to use streaming API

parent 0ea433f3
...@@ -18,12 +18,12 @@ ...@@ -18,12 +18,12 @@
#pragma once #pragma once
#include "caf/param.hpp" #include "caf/abstract_composable_behavior.hpp"
#include "caf/behavior.hpp" #include "caf/behavior.hpp"
#include "caf/param.hpp"
#include "caf/replies_to.hpp" #include "caf/replies_to.hpp"
#include "caf/typed_actor.hpp" #include "caf/typed_actor.hpp"
#include "caf/typed_actor_pointer.hpp" #include "caf/typed_actor_pointer.hpp"
#include "caf/abstract_composable_behavior.hpp"
namespace caf { namespace caf {
...@@ -106,4 +106,3 @@ public: ...@@ -106,4 +106,3 @@ public:
}; };
} // namespace caf } // namespace caf
...@@ -84,15 +84,27 @@ private: ...@@ -84,15 +84,27 @@ private:
flag flag_; flag flag_;
}; };
/// Convenience alias that wraps `T` into `param<T>` /// Converts `T` to `param<T>` unless `T` is arithmetic, an atom constant, or
/// unless `T` is arithmetic or an atom constant. /// a stream handshake.
template <class T> template <class T>
using param_t = struct add_param : std::conditional<std::is_arithmetic<T>::value, T, param<T>> {
typename std::conditional< // nop
std::is_arithmetic<T>::value || is_atom_constant<T>::value, };
T,
param<T> template <atom_value V>
>::type; struct add_param<atom_constant<V>> {
using type = atom_constant<V>;
};
template <class T>
struct add_param<stream<T>> {
using type = stream<T>;
};
/// Convenience alias that wraps `T` into `param<T>` unless `T` is arithmetic,
/// a stream handshake or an atom constant.
template <class T>
using param_t = typename add_param<T>::type;
/// Unpacks `param<T>` to `T`. /// Unpacks `param<T>` to `T`.
template <class T> template <class T>
...@@ -112,4 +124,3 @@ struct param_decay { ...@@ -112,4 +124,3 @@ struct param_decay {
}; };
} // namespace caf } // namespace caf
...@@ -58,7 +58,11 @@ public: ...@@ -58,7 +58,11 @@ public:
} }
/// @private /// @private
scheduled_actor* internal_ptr() const { scheduled_actor* internal_ptr() const noexcept {
return view_.internal_ptr();
}
operator scheduled_actor*() const noexcept {
return view_.internal_ptr(); return view_.internal_ptr();
} }
......
...@@ -112,23 +112,27 @@ public: ...@@ -112,23 +112,27 @@ public:
/// Returns a pointer to the sender of the current message. /// Returns a pointer to the sender of the current message.
/// @pre `current_mailbox_element() != nullptr` /// @pre `current_mailbox_element() != nullptr`
inline strong_actor_ptr& current_sender() { strong_actor_ptr& current_sender() {
return self_->current_sender(); return self_->current_sender();
} }
/// Returns a pointer to the currently processed mailbox element. /// Returns a pointer to the currently processed mailbox element.
inline mailbox_element* current_mailbox_element() { mailbox_element* current_mailbox_element() {
return self_->current_mailbox_element(); return self_->current_mailbox_element();
} }
/// @private /// @private
actor_control_block* ctrl() const { actor_control_block* ctrl() const noexcept {
CAF_ASSERT(self_ != nullptr); CAF_ASSERT(self_ != nullptr);
return actor_control_block::from(self_);; return actor_control_block::from(self_);;
} }
/// @private /// @private
scheduled_actor* internal_ptr() const { scheduled_actor* internal_ptr() const noexcept {
return self_;
}
operator scheduled_actor*() const noexcept {
return self_; return self_;
} }
...@@ -137,4 +141,3 @@ private: ...@@ -137,4 +141,3 @@ private:
}; };
} // namespace caf } // namespace caf
This diff is collapsed.
...@@ -18,13 +18,14 @@ ...@@ -18,13 +18,14 @@
#pragma once #pragma once
#include <type_traits>
#include "caf/all.hpp" #include "caf/all.hpp"
#include "caf/config.hpp" #include "caf/config.hpp"
#include "caf/detail/gcd.hpp"
#include "caf/meta/annotation.hpp" #include "caf/meta/annotation.hpp"
#include "caf/test/unit_test.hpp" #include "caf/test/unit_test.hpp"
#include "caf/detail/gcd.hpp"
CAF_PUSH_WARNINGS CAF_PUSH_WARNINGS
/// The type of `_`. /// The type of `_`.
...@@ -375,6 +376,71 @@ protected: ...@@ -375,6 +376,71 @@ protected:
std::function<void ()> peek_; std::function<void ()> peek_;
}; };
template <class... Ts>
class inject_clause {
public:
inject_clause(caf::scheduler::test_coordinator& sched)
: sched_(sched), dest_(nullptr) {
// nop
}
inject_clause(inject_clause&& other) = default;
template <class Handle>
inject_clause& from(const Handle& whom) {
src_ = caf::actor_cast<caf::strong_actor_ptr>(whom);
return *this;
}
template <class Handle>
inject_clause& to(const Handle& whom) {
dest_ = caf::actor_cast<caf::strong_actor_ptr>(whom);
return *this;
}
inject_clause& to(const caf::scoped_actor& whom) {
dest_ = whom.ptr();
return *this;
}
void with(Ts... xs) {
if (src_ == nullptr)
CAF_FAIL("missing .from() in inject() statement");
if (dest_ == nullptr)
CAF_FAIL("missing .to() in inject() statement");
caf::send_as(caf::actor_cast<caf::actor>(src_),
caf::actor_cast<caf::actor>(dest_), xs...);
CAF_REQUIRE(sched_.prioritize(dest_));
auto dest_ptr = &sched_.next_job<caf::abstract_actor>();
auto ptr = dest_ptr->peek_at_next_mailbox_element();
CAF_REQUIRE(ptr != nullptr);
CAF_REQUIRE_EQUAL(ptr->sender, src_);
// TODO: replace this workaround with the make_tuple() line when dropping
// support for GCC 4.8.
std::tuple<Ts...> tmp{std::move(xs)...};
using namespace caf::detail;
elementwise_compare_inspector<decltype(tmp)> inspector{tmp};
auto ys = extract<Ts...>(dest_);
auto ys_indices = get_indices(ys);
CAF_REQUIRE(apply_args(inspector, ys_indices, ys));
run_once();
}
protected:
void run_once() {
auto ptr = caf::actor_cast<caf::abstract_actor*>(dest_);
auto dptr = dynamic_cast<caf::blocking_actor*>(ptr);
if (dptr == nullptr)
sched_.run_once();
else
dptr->dequeue(); // Drop message.
}
caf::scheduler::test_coordinator& sched_;
caf::strong_actor_ptr src_;
caf::strong_actor_ptr dest_;
};
template <class... Ts> template <class... Ts>
class allow_clause { class allow_clause {
public: public:
...@@ -796,6 +862,12 @@ T unbox(T* x) { ...@@ -796,6 +862,12 @@ T unbox(T* x) {
expect_clause<CAF_EXPAND(CAF_DSL_LIST types)>{sched}.fields; \ expect_clause<CAF_EXPAND(CAF_DSL_LIST types)>{sched}.fields; \
} while (false) } while (false)
#define inject(types, fields) \
do { \
CAF_MESSAGE("inject" << #types << "." << #fields); \
inject_clause<CAF_EXPAND(CAF_DSL_LIST types)>{sched}.fields; \
} while (false)
/// Convenience macro for defining allow clauses. /// Convenience macro for defining allow clauses.
#define allow(types, fields) \ #define allow(types, fields) \
([&] { \ ([&] { \
......
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