Line | Branch | Exec | Source |
---|---|---|---|
1 | #pragma once | ||
2 | |||
3 | #include "Algorithm.h" | ||
4 | |||
5 | namespace iguana { | ||
6 | |||
7 | /// @brief User-level class for running a sequence of algorithms | ||
8 | /// | ||
9 | /// The `Start`, `Run`, and `Stop` methods will sequentially call the corresponding algorithms' methods, | ||
10 | /// in the order the algorithms were added to the sequence by `AlgorithmSequence::Add`. | ||
11 | class AlgorithmSequence : public Algorithm | ||
12 | { | ||
13 | |||
14 |
5/12✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
128 | DEFINE_IGUANA_ALGORITHM(AlgorithmSequence, seq) |
15 | |||
16 | public: | ||
17 | |||
18 | void Start(hipo::banklist& banks) override; | ||
19 | void Run(hipo::banklist& banks) const override; | ||
20 | void Stop() override; | ||
21 | |||
22 | /// Create and add an algorithm to the sequence, by name. | ||
23 | /// | ||
24 | /// **Example** | ||
25 | /// @code | ||
26 | /// Add("iguana::MyAlgorithm", "my_algorithm_name"); | ||
27 | /// @endcode | ||
28 | /// @param class_name the name of the algorithm class | ||
29 | /// @param instance_name a user-specified unique name for this algorithm instance; | ||
30 | /// if not specified, `class_name` will be used | ||
31 | void Add(std::string const& class_name, std::string const& instance_name = ""); | ||
32 | |||
33 | /// Create and add an algorithm to the sequence. | ||
34 | /// | ||
35 | /// **Example** | ||
36 | /// @code | ||
37 | /// Add<iguana::MyAlgorithm>("my_algorithm_name"); | ||
38 | /// @endcode | ||
39 | /// @param instance_name a user-specified unique name for this algorithm instance; | ||
40 | /// if not specified, the class name will be used | ||
41 | template <class ALGORITHM> | ||
42 | void Add(std::string_view instance_name = "") | ||
43 | { | ||
44 | if(instance_name == "") | ||
45 | Add(std::make_unique<ALGORITHM>()); | ||
46 | else | ||
47 | Add(std::make_unique<ALGORITHM>(instance_name)); | ||
48 | } | ||
49 | |||
50 | /// Add an existing algorithm to the sequence. The `AlgorithmSequence` instance will take ownership of the algorithm | ||
51 | /// (if it is an `lvalue`, you will have to `std::move` it). | ||
52 | /// | ||
53 | /// **Example** | ||
54 | /// @code | ||
55 | /// Add(std::make_unique<iguana::MyAlgorithm>("my_algorithm_name")); | ||
56 | /// @endcode | ||
57 | /// @param algo the algorithm | ||
58 | void Add(algo_t&& algo); | ||
59 | |||
60 | /// Get an algorithm by its instance name | ||
61 | /// | ||
62 | /// **Example** | ||
63 | /// @code | ||
64 | /// Get<iguana::MyAlgorithm>("my_algorithm_name"); | ||
65 | /// @endcode | ||
66 | /// @param instance_name the instance name of the algorithm | ||
67 | /// @return a reference to the algorithm | ||
68 | template <class ALGORITHM> | ||
69 | 1893 | ALGORITHM* Get(std::string const& instance_name) | |
70 | { | ||
71 |
1/2✓ Branch 0 taken 1893 times.
✗ Branch 1 not taken.
|
1893 | if(auto it{m_algo_names.find(instance_name)}; it != m_algo_names.end()) |
72 |
1/2✓ Branch 0 taken 1865 times.
✗ Branch 1 not taken.
|
1893 | return dynamic_cast<ALGORITHM*>(m_sequence[it->second].get()); |
73 | ✗ | m_log->Error("cannot find algorithm '{}' in sequence", instance_name); | |
74 | ✗ | throw std::runtime_error("cannot Get algorithm"); | |
75 | } | ||
76 | |||
77 | /// Set an algorithm option | ||
78 | /// @see `Algorithm::SetOption` | ||
79 | /// @param algo_name the algorithm instance name | ||
80 | /// @param key the option name | ||
81 | /// @param val the option value | ||
82 | template <typename OPTION_TYPE> | ||
83 | 12 | void SetOption(std::string const& algo_name, std::string const& key, const OPTION_TYPE val) | |
84 | { | ||
85 |
5/10✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
|
30 | Get<Algorithm>(algo_name)->SetOption(key, val); |
86 | 28 | } | |
87 | |||
88 | /// Set the name of this sequence | ||
89 | /// @param name the new name | ||
90 | void SetName(std::string_view name); | ||
91 | |||
92 | /// Print the names of the algorithms in this sequence | ||
93 | /// @param level the log level of the printout | ||
94 | void PrintSequence(Logger::Level level = Logger::info) const; | ||
95 | |||
96 | /// @brief Set a custom configuration file for each algorithm in the sequence | ||
97 | /// | ||
98 | /// Use this function if you have a single configuration file for all the | ||
99 | /// algorithms in your sequence | ||
100 | /// @param name the configuration file name | ||
101 | void SetConfigFileForEachAlgorithm(std::string const& name); | ||
102 | |||
103 | /// @brief Set a custom configuration file directory for each algorithm in the sequence | ||
104 | /// | ||
105 | /// Use this function if you have a single configuration file directory for all the | ||
106 | /// algorithms in your sequence | ||
107 | /// @param name the directory name | ||
108 | void SetConfigDirectoryForEachAlgorithm(std::string const& name); | ||
109 | |||
110 | /// @brief Call a function for each algorithm in the sequence | ||
111 | /// | ||
112 | /// Use as: | ||
113 | /// ```cpp | ||
114 | /// ForEachAlgorithm([](auto& algo){ algo->...; }); | ||
115 | /// ``` | ||
116 | /// @param func the function to call for each algorithm `algo` | ||
117 | void ForEachAlgorithm(std::function<void(algo_t&)> func); | ||
118 | |||
119 | private: | ||
120 | |||
121 | /// The sequence of algorithms | ||
122 | std::vector<algo_t> m_sequence; | ||
123 | |||
124 | /// Association of algorithm name to its index in the sequence | ||
125 | std::unordered_map<std::string, std::vector<algo_t>::size_type> m_algo_names; | ||
126 | }; | ||
127 | } | ||
128 |