Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:26

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 // Project includes(s)
0010 #include "detray/propagator/actor_chain.hpp"
0011 #include "detray/propagator/base_actor.hpp"
0012 
0013 // System include(s)
0014 #include <iostream>
0015 #include <sstream>
0016 #include <string>
0017 
0018 namespace {
0019 
0020 // Propagator state: Does nothing
0021 struct empty_prop_state {};
0022 const empty_prop_state prop_state{};
0023 
0024 /// Actor that prints its call chain and subject data
0025 struct print_actor : public detray::base_actor {
0026   /// State keeps an internal string representation
0027   struct state {
0028     std::stringstream stream{};
0029 
0030     std::string to_string() const { return stream.str(); }
0031   };
0032 
0033   // Actor result: status code
0034   using result = detray::actor::result;
0035 
0036   /// Actor implementation: append call notification to internal string
0037   template <typename propagator_state_t>
0038   result operator()(state &printer_state,
0039                     const propagator_state_t & /*p_state*/,
0040                     const detray::actor::result /*res*/) const {
0041     printer_state.stream << "[print actor]:";
0042 
0043     return {detray::actor::status::e_notify};
0044   }
0045 
0046   /// Observing actor implementation: append call notification to internal
0047   /// string
0048   template <typename subj_result_t, typename propagator_state_t>
0049   result operator()(state &printer_state,
0050                     const propagator_state_t & /*p_state*/,
0051                     const subj_result_t res) const {
0052     printer_state.stream << "[" << res << ": print actor obs "
0053                          << res.buffer->back() << "]:";
0054 
0055     return {detray::actor::status::e_notify};
0056   }
0057 };
0058 
0059 /// Example actor that counts the number of elements in its buffer
0060 template <template <typename...> class vector_t>
0061 struct example_actor : public detray::base_actor {
0062   /// Actor state
0063   struct state {
0064     // Keep dynamic data per propagation stream
0065     vector_t<float> buffer = {};
0066   };
0067 
0068   /// Actor result
0069   struct result : detray::actor::result {
0070     vector_t<float> *buffer{nullptr};
0071   };
0072 
0073   /// Actor implementation: Counts vector elements
0074   template <typename propagator_state_t>
0075   result operator()(state &example_state,
0076                     const propagator_state_t & /*p_state*/) const {
0077     example_state.buffer.push_back(
0078         static_cast<float>(example_state.buffer.size()));
0079 
0080     return {{detray::actor::status::e_notify}, &example_state.buffer};
0081   }
0082 
0083   /// Observing actor implementation: Counts vector elements (division)
0084   template <typename propagator_state_t>
0085   result operator()(state &example_state,
0086                     const propagator_state_t & /*p_state*/,
0087                     const result &res) const {
0088     example_state.buffer.push_back(static_cast<float>(res.buffer->size()) /
0089                                    10.f);
0090 
0091     return {{detray::actor::status::e_notify}, &example_state.buffer};
0092   }
0093 
0094   /// Observing actor implementation to printer: do nothing
0095   template <typename subj_result_t, typename propagator_state_t>
0096     requires(!std::is_same_v<subj_result_t, result>)
0097   result operator()(state &example_state,
0098                     const propagator_state_t & /*p_state*/,
0099                     const subj_result_t & /*res*/) const {
0100     return {{detray::actor::status::e_notify}, &example_state.buffer};
0101   }
0102 };
0103 
0104 }  // anonymous namespace
0105 
0106 // Run the actor chain on some dummy actor types
0107 int main() {
0108   using example_actor_t = example_actor<std::vector>;
0109   // Implements example_actor with two print observers
0110   using composite =
0111       detray::composite_actor<example_actor_t, print_actor, print_actor>;
0112 
0113   std::clog << "Actor Definition Tutorial\n=========================\n";
0114 
0115   example_actor_t::state example_state{};
0116   print_actor::state printer_state{};
0117 
0118   // Aggregate actor states to be able to pass them through the chain
0119   auto actor_states = detray::tie(example_state, printer_state);
0120 
0121   // Chain of actors
0122   using actor_chain_t = detray::actor_chain<example_actor_t, composite>;
0123   // Run
0124   actor_chain_t run_actors{};
0125   run_actors(actor_states, prop_state);
0126 
0127   std::clog << "\nactor list: " << printer_state.to_string() << std::endl;
0128 
0129   // Test chaining of multiple actors
0130 
0131   /* Test chaining of multiple actors
0132    * The chain goes as follows (depth first):
0133    *                          example_actor1
0134    *                              1.|
0135    *                          observer_lvl1 (print)
0136    *                              2.|
0137    *                          observer_lvl2 (example_actor observing print
0138    * actor)
0139    *                      3./     5.|     6.\
0140    *            observer_lvl3 example_actor2 print
0141    *          (example_actor3)
0142    *               4.|
0143    *               print
0144    */
0145   using observer_lvl3 = detray::composite_actor<example_actor_t, print_actor>;
0146   using observer_lvl2 = detray::composite_actor<example_actor_t, observer_lvl3,
0147                                                 example_actor_t, print_actor>;
0148   using observer_lvl1 = detray::composite_actor<print_actor, observer_lvl2>;
0149   using chain = detray::composite_actor<example_actor_t, observer_lvl1>;
0150 
0151   // Reset example actor state
0152   example_state.buffer.clear();
0153   printer_state.stream.str("");
0154   printer_state.stream.clear();
0155 
0156   // Run the chain
0157   detray::actor_chain<chain> run_chain{};
0158   run_chain(actor_states, prop_state);
0159 
0160   std::clog << "actor chain: " << printer_state.to_string() << std::endl;
0161 }