File indexing completed on 2026-05-27 07:24:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/propagator/actor_chain.hpp"
0011
0012 #include "detray/definitions/units.hpp"
0013 #include "detray/propagator/base_actor.hpp"
0014 #include "detray/propagator/concepts.hpp"
0015
0016
0017 #include <gtest/gtest.h>
0018
0019
0020 #include <sstream>
0021 #include <string>
0022
0023 using namespace detray;
0024
0025
0026 struct print_actor : public detray::base_actor {
0027
0028 struct state {
0029 std::stringstream stream{};
0030
0031 state() = default;
0032 state(state &&) noexcept = default;
0033 state(const state &) = delete;
0034 state &operator=(state const &) = delete;
0035 state &operator=(state &&) noexcept = default;
0036
0037 std::string to_string() const { return stream.str(); }
0038 };
0039
0040
0041 using result = detray::actor::result;
0042
0043
0044 template <typename propagator_state_t>
0045 result operator()(state &printer_state,
0046 const propagator_state_t & ) const {
0047 printer_state.stream << "[print actor]:";
0048
0049 return {detray::actor::status::e_notify};
0050 }
0051
0052
0053
0054 template <typename subj_result_t, typename propagator_state_t>
0055 result operator()(state &printer_state,
0056 const propagator_state_t & ,
0057 const subj_result_t &res) const {
0058 printer_state.stream << "[print actor obs " << res.buffer->back() << "]:";
0059
0060 return {detray::actor::status::e_notify};
0061 }
0062 };
0063
0064
0065 template <template <typename...> class vector_t>
0066 struct example_actor : public detray::base_actor {
0067
0068 struct state {
0069
0070 vector_t<float> buffer = {};
0071 };
0072
0073
0074 struct result : detray::actor::result {
0075 vector_t<float> *buffer{nullptr};
0076 };
0077
0078
0079 template <typename propagator_state_t>
0080 result operator()(state &example_state,
0081 const propagator_state_t & ) const {
0082 example_state.buffer.push_back(
0083 static_cast<float>(example_state.buffer.size()));
0084
0085 return {{detray::actor::status::e_notify}, &example_state.buffer};
0086 }
0087
0088
0089 template <typename propagator_state_t>
0090 result operator()(state &example_state,
0091 const propagator_state_t & ,
0092 const result &res) const {
0093 example_state.buffer.push_back(static_cast<float>(res.buffer->size()) *
0094 0.1f);
0095
0096 return {{detray::actor::status::e_notify}, &example_state.buffer};
0097 }
0098
0099
0100 template <typename subj_result_t, typename propagator_state_t>
0101 requires(!std::is_same_v<subj_result_t, state>)
0102 result operator()(state &example_state,
0103 const propagator_state_t & ,
0104 const subj_result_t & ) const {
0105 return {{detray::actor::status::e_notify}, &example_state.buffer};
0106 }
0107 };
0108
0109 using example_actor_t = example_actor<std::vector>;
0110
0111 using composite1 = composite_actor<example_actor_t, print_actor, print_actor>;
0112
0113 using composite2 = composite_actor<example_actor_t, print_actor>;
0114
0115 using composite3 = composite_actor<example_actor_t, composite1>;
0116
0117 using composite4 = composite_actor<example_actor_t, composite1>;
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 using observer_lvl3 = composite_actor<example_actor_t, print_actor>;
0133 using observer_lvl2 = composite_actor<example_actor_t, observer_lvl3,
0134 example_actor_t, print_actor>;
0135 using observer_lvl1 = composite_actor<print_actor, observer_lvl2>;
0136 using chain = composite_actor<example_actor_t, observer_lvl1>;
0137
0138
0139 GTEST_TEST(detray_propagator, actor_chain) {
0140 static_assert(detray::concepts::actor<print_actor>);
0141 static_assert(detray::concepts::actor<example_actor_t>);
0142 static_assert(detray::concepts::actor<composite1>);
0143 static_assert(detray::concepts::actor<composite2>);
0144 static_assert(detray::concepts::actor<composite3>);
0145 static_assert(detray::concepts::actor<composite4>);
0146 static_assert(detray::concepts::actor<observer_lvl3>);
0147 static_assert(detray::concepts::actor<observer_lvl2>);
0148 static_assert(detray::concepts::actor<observer_lvl1>);
0149
0150 static_assert(!detray::concepts::composite_actor<print_actor>);
0151 static_assert(!detray::concepts::composite_actor<example_actor_t>);
0152 static_assert(detray::concepts::composite_actor<composite1>);
0153 static_assert(detray::concepts::composite_actor<composite2>);
0154 static_assert(detray::concepts::composite_actor<composite3>);
0155 static_assert(detray::concepts::composite_actor<composite4>);
0156 static_assert(detray::concepts::composite_actor<observer_lvl3>);
0157 static_assert(detray::concepts::composite_actor<observer_lvl2>);
0158 static_assert(detray::concepts::composite_actor<observer_lvl1>);
0159
0160
0161 example_actor_t::state example_state{};
0162 print_actor::state printer_state{};
0163
0164
0165 auto actor_states = detray::tie(example_state, printer_state);
0166
0167
0168 struct empty_prop_state {};
0169 empty_prop_state prop_state{};
0170
0171
0172 using actor_chain_t = actor_chain<example_actor_t, composite1, composite2,
0173 composite3, composite4>;
0174
0175 static_assert(detray::concepts::actor_chain<actor_chain<>>);
0176 static_assert(detray::concepts::actor_chain<actor_chain_t>);
0177
0178
0179 actor_chain_t run_actors{};
0180 run_actors(actor_states, prop_state);
0181
0182 ASSERT_TRUE(printer_state.to_string().compare(
0183 "[print actor obs 1]:[print actor obs 1]:[print actor obs "
0184 "2]:[print actor obs 0.4]:[print actor obs 0.4]:[print "
0185 "actor obs 0.6]:[print actor obs 0.6]:") == 0)
0186 << "Printer call chain: " << printer_state.to_string() << std::endl;
0187
0188
0189
0190
0191 example_state.buffer.clear();
0192 printer_state.stream.str("");
0193 printer_state.stream.clear();
0194
0195
0196 actor_chain<chain> run_chain{};
0197 run_chain(actor_states, prop_state);
0198
0199 ASSERT_TRUE(printer_state.to_string().compare(
0200 "[print actor obs 0]:[print actor obs 0.1]:[print actor "
0201 "obs 0.2]:") == 0)
0202 << "Printer call chain: " << printer_state.to_string() << std::endl;
0203 }