7
7
8
8
#pragma once
9
9
10
- // Propagate include(s)
11
- #include " detray/definitions/containers.hpp"
12
- #include " detray/definitions/detail/qualifiers.hpp"
13
- #include " detray/utils/tuple_helpers.hpp"
14
-
15
10
// System include(s)
16
- #include < concepts>
17
11
#include < type_traits>
18
- #include < utility>
19
12
20
13
namespace detray {
21
14
@@ -28,167 +21,4 @@ struct actor {
28
21
struct state {};
29
22
};
30
23
31
- namespace detail {
32
- // / Extrac the tuple of actor states from an actor type
33
- // / @{
34
- // Simple actor: No observers
35
- template <typename actor_t >
36
- struct get_state_tuple {
37
- private:
38
- using state_t = typename actor_t ::state;
39
-
40
- // Remove empty default state of base actor type from tuple
41
- using principal = std::conditional_t <std::same_as<state_t , actor::state>,
42
- dtuple<>, dtuple<state_t >>;
43
- using principal_ref =
44
- std::conditional_t <std::same_as<state_t , actor::state>, dtuple<>,
45
- dtuple<state_t &>>;
46
-
47
- public:
48
- using type = principal;
49
- using ref_type = principal_ref;
50
- };
51
-
52
- // Composite actor: Has observers
53
- template <typename actor_t >
54
- requires (!std::same_as<typename std::remove_cvref_t <actor_t >::observer_states,
55
- void >) struct get_state_tuple <actor_t > {
56
- private:
57
- using principal_actor_t = typename actor_t ::actor_type;
58
-
59
- using principal = typename get_state_tuple<principal_actor_t >::type;
60
- using principal_ref = typename get_state_tuple<principal_actor_t >::ref_type;
61
-
62
- using observers = typename actor_t ::observer_states;
63
- using observer_refs = typename actor_t ::observer_state_refs;
64
-
65
- public:
66
- using type = detail::tuple_cat_t <principal, observers>;
67
- using ref_type = detail::tuple_cat_t <principal_ref, observer_refs>;
68
- };
69
-
70
- // / Tuple of state types
71
- template <typename actor_t >
72
- using state_tuple_t = get_state_tuple<actor_t >::type;
73
-
74
- // / Tuple of references
75
- template <typename actor_t >
76
- using state_ref_tuple_t = get_state_tuple<actor_t >::ref_type;
77
- // / @}
78
-
79
- } // namespace detail
80
-
81
- // / Composition of actors
82
- // /
83
- // / The composition represents an actor together with its observers. In
84
- // / addition to running its own implementation, it notifies its observing actors
85
- // /
86
- // / @tparam principal_actor_t the actor the compositions implements itself.
87
- // / @tparam observers a pack of observing actors that get called on the updated
88
- // / actor state of the compositions actor implementation.
89
- template <class principal_actor_t = actor, typename ... observers>
90
- class composite_actor final : public principal_actor_t {
91
-
92
- public:
93
- // / Tag whether this is a composite type (hides the def in the actor)
94
- struct is_comp_actor : public std ::true_type {};
95
-
96
- // / The composite is an actor in itself.
97
- using actor_type = principal_actor_t ;
98
- using state = typename actor_type::state;
99
-
100
- // / Tuple of states of observing actors
101
- using observer_states =
102
- detail::tuple_cat_t <detail::state_tuple_t <observers>...>;
103
- using observer_state_refs =
104
- detail::tuple_cat_t <detail::state_ref_tuple_t <observers>...>;
105
-
106
- // / Call to the implementation of the actor (the actor possibly being an
107
- // / observer itself)
108
- // /
109
- // / First runs its own implementation, then passes the updated state to its
110
- // / observers.
111
- // /
112
- // / @param states the states of all actors in the chain
113
- // / @param p_state the state of the propagator (stepper and navigator)
114
- // / @param subject_state the state of the actor this actor observes. Uses
115
- // / a dummy type if this is not an observing actor.
116
- template <typename actor_states_t , typename propagator_state_t ,
117
- typename subj_state_t = typename actor::state>
118
- DETRAY_HOST_DEVICE void operator ()(
119
- actor_states_t &states, propagator_state_t &p_state,
120
- subj_state_t &&subject_state = {}) const {
121
-
122
- // State of the primary actor that is implement by this composite actor
123
- auto &actor_state = detail::get<typename actor_type::state &>(states);
124
-
125
- // Do your own work ...
126
- // Two cases: This is a simple actor or observing actor (pass on its
127
- // subject's state)
128
- if constexpr (std::is_same_v<subj_state_t , typename actor::state>) {
129
- actor_type::operator ()(actor_state, p_state);
130
- } else {
131
- actor_type::operator ()(actor_state, p_state,
132
- std::forward<subj_state_t >(subject_state));
133
- }
134
-
135
- // ... then run the observers on the updated state
136
- notify (m_observers, states, actor_state, p_state,
137
- std::make_index_sequence<sizeof ...(observers)>{});
138
- }
139
-
140
- private:
141
- // / Notifies the observing actors for composite and simple actor case.
142
- // /
143
- // / @param observer one of the observers
144
- // / @param states the states of all actors in the chain
145
- // / @param actor_state the state of this compositions actor as the subject
146
- // / to all of its observers
147
- // / @param p_state the state of the propagator (stepper and navigator)
148
- template <typename observer_t , typename actor_states_t ,
149
- typename actor_impl_state_t , typename propagator_state_t >
150
- DETRAY_HOST_DEVICE inline void notify (const observer_t &observer,
151
- actor_states_t &states,
152
- actor_impl_state_t &actor_state,
153
- propagator_state_t &p_state) const {
154
- // Two cases: observer is a simple actor or a composite actor
155
- if constexpr (!typename observer_t::is_comp_actor ()) {
156
- // No actor state defined (empty)
157
- if constexpr (std::same_as<typename observer_t ::state,
158
- detray::actor::state>) {
159
- observer (actor_state, p_state);
160
- } else {
161
- observer (detail::get<typename observer_t ::state &>(states),
162
- actor_state, p_state);
163
- }
164
- } else {
165
- observer (states, actor_state, p_state);
166
- }
167
- }
168
-
169
- // / Resolve the observer notification.
170
- // /
171
- // / Unrolls the observer types and runs the notification for each of them.
172
- // /
173
- // / @param observer_list all observers of the actor
174
- // / @param states the states of all actors in the chain
175
- // / @param actor_state the state of this compositions actor as the subject
176
- // / to all of its observers
177
- // / @param p_state the state of the propagator (stepper and navigator)
178
- template <std::size_t ... indices, typename actor_states_t ,
179
- typename actor_impl_state_t , typename propagator_state_t >
180
- DETRAY_HOST_DEVICE inline void notify (
181
- const dtuple<observers...> &observer_list, actor_states_t &states,
182
- actor_impl_state_t &actor_state, propagator_state_t &p_state,
183
- std::index_sequence<indices...> /* ids*/ ) const {
184
-
185
- (notify (detail::get<indices>(observer_list), states, actor_state,
186
- p_state),
187
- ...);
188
- }
189
-
190
- // / Keep the observers (might be composites again)
191
- [[no_unique_address]] dtuple<observers...> m_observers = {};
192
- };
193
-
194
24
} // namespace detray
0 commit comments