12 template<
int...>
struct seq {};
13 template<
int N,
int... S>
struct gens :
gens<N - 1, N - 1, S...> {};
14 template<
int... S>
struct gens<0, S...> {
using type =
seq<S...>; };
16 #define TEMPLATABLE_VALUE_(type, name) \ 18 TemplatableValue<type, Ts...> name##_{}; \ 21 template<typename V> void set_##name(V name) { this->name##_ = name; } 23 #define TEMPLATABLE_VALUE(type, name) TEMPLATABLE_VALUE_(type, name) 38 if (this->type_ == LAMBDA) {
39 return this->f_(
x...);
46 if (!this->has_value()) {
49 return this->value(
x...);
53 if (!this->has_value()) {
56 return this->value(
x...);
67 std::function<T(X...)> f_{};
77 virtual bool check(Ts...
x) = 0;
81 return this->check_tuple_(tuple,
typename gens<
sizeof...(Ts)>::
type());
86 return this->check(std::get<S>(tuple)...);
96 if (this->automation_parent_ ==
nullptr)
98 this->automation_parent_->trigger(
x...);
104 if (this->automation_parent_ ==
nullptr)
106 this->automation_parent_->stop();
110 if (this->automation_parent_ ==
nullptr)
112 return this->automation_parent_->is_running();
124 this->num_running_++;
126 this->play_next_(
x...);
131 this->num_running_ = 0;
136 virtual bool is_running() {
return this->num_running_ > 0 || this->is_running_next_(); }
141 int total = this->num_running_;
142 if (this->next_ !=
nullptr)
143 total += this->next_->num_running_total();
150 virtual void play(Ts...
x) = 0;
152 if (this->num_running_ > 0) {
153 this->num_running_--;
154 if (this->next_ !=
nullptr) {
155 this->next_->play_complex(
x...);
160 this->play_next_(std::get<S>(tuple)...);
163 this->play_next_tuple_(tuple,
typename gens<
sizeof...(Ts)>::
type());
168 if (this->next_ !=
nullptr) {
169 this->next_->stop_complex();
174 if (this->next_ ==
nullptr)
176 return this->next_->is_running();
189 if (this->actions_end_ ==
nullptr) {
190 this->actions_begin_ = action;
192 this->actions_end_->
next_ = action;
194 this->actions_end_ = action;
197 for (
auto *action : actions) {
198 this->add_action(action);
202 if (this->actions_begin_ !=
nullptr)
203 this->actions_begin_->play_complex(
x...);
205 void play_tuple(
const std::tuple<Ts...> &tuple) { this->play_tuple_(tuple,
typename gens<
sizeof...(Ts)>::
type()); }
207 if (this->actions_begin_ !=
nullptr)
208 this->actions_begin_->stop_complex();
210 bool empty()
const {
return this->actions_begin_ ==
nullptr; }
214 if (this->actions_begin_ ==
nullptr)
216 return this->actions_begin_->is_running();
220 if (this->actions_begin_ ==
nullptr)
222 return this->actions_begin_->num_running_total();
227 this->play(std::get<S>(tuple)...);
241 void stop() { this->actions_.stop(); }
void add_action(Action< Ts... > *action)
T value_or(X... x, T default_value)
virtual void play_complex(Ts... x)
typename std::enable_if< B, T >::type enable_if_t
int num_running()
Return the number of actions in the action part of this automation that are currently running...
TemplatableValue(F value)
virtual void stop_complex()
int num_running_total()
The total number of actions that are currently running in this plus any of the following actions in t...
void play_tuple_(const std::tuple< Ts... > &tuple, seq< S... >)
bool check_tuple_(const std::tuple< Ts... > &tuple, seq< S... >)
bool is_running()
Check if any action in this action list is currently running.
bool is_action_running()
Returns true if any action connected to this trigger is running.
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
void play_next_tuple_(const std::tuple< Ts... > &tuple)
Trigger< Ts... > * trigger_
void play_next_tuple_(const std::tuple< Ts... > &tuple, seq< S... >)
void play_tuple(const std::tuple< Ts... > &tuple)
Base class for all automation conditions.
void add_actions(const std::vector< Action< Ts... > *> &actions)
ActionList< Ts... > actions_
int num_running()
Return the number of actions in this action list that are currently running.
optional< T > optional_value(X... x)
bool check_tuple(const std::tuple< Ts... > &tuple)
Call check with a tuple of values as parameter.
virtual bool is_running()
Check if this or any of the following actions are currently running.
void set_automation_parent(Automation< Ts... > *automation_parent)
void add_action(Action< Ts... > *action)
Automation(Trigger< Ts... > *trigger)
Implementation of SPI Controller mode.
void add_actions(const std::vector< Action< Ts... > *> &actions)
void stop_action()
Stop any action connected to this trigger.