75 #include <type_traits>
78 #include <boost/algorithm/string.hpp>
97 template <
typename D = Duration>
100 explicit Contact(
bool active) : active_(active) {}
112 if (active_ | down) {
121 bool has_contact()
const {
return active_; }
151 template <
typename D = Duration>
154 std::shared_ptr<Contact<D>> contact;
158 std::map<std::string, Button> buttons_;
166 if (buttons_.count(key)) {
167 throw std::logic_error(
"HMI contact '" + key +
"' already exists.");
169 buttons_.emplace(std::make_pair(key, Button{c, c->has_contact()}));
170 schema_.
set_property(key,
Schema(&(buttons_[key].state),
"push " + key +
" HMI contact"));
181 for (
auto& elem : buttons_) {
182 auto& b = elem.second;
183 b.contact->update(time, b.state);
187 Schema schema() {
return schema_; }
189 void to_json(Json& j)
const override {
190 for (
auto& elem : buttons_) {
191 j[elem.first] = elem.second.state;
196 for (
auto& elem : buttons_) {
197 c.
try_from(elem.first, elem.second.state);
204 template <
typename D = Duration>
209 ActionPtr
clone()
const override {
return std::make_unique<UseContact<D>>(
name(), hmi_, data_); }
213 void to_json(Json& j)
const override { j = *data_; }
220 template <
typename D = Duration>
231 InlineSchema(
"comma-separated list of buttons to press",
"[!]<button>[,...]",
true),
237 return std::make_unique<UseContact<D>>(
name(), contacts_, c);
251 ActionPtr
make(
const std::string& s)
const override {
254 std::vector<std::string> fields;
255 boost::split(fields, s, boost::is_any_of(
","));
259 for (
const auto& f : fields) {
261 throw Error(
"empty entry in comma-separated list");
263 bool value = (f[0] ==
'!' ? false :
true);
264 std::string key = (value ? f : f.substr(1));
287 template <
typename D = Duration>
290 Switch(std::function<
void()> set_fn, std::function<
void()> unset_fn,
bool active)
291 :
Contact<D>(active), set_func_(set_fn), unset_func_(unset_fn) {}
292 virtual ~
Switch() =
default;
295 void contact_down(D)
override {
297 if (!this->active_) {
298 this->active_ =
true;
303 void contact_up(D)
override {
304 assert(this->active_);
305 this->active_ =
false;
310 std::function<void()> set_func_;
311 std::function<void()> unset_func_;
334 template <
typename D = Duration>
337 explicit PushButton(std::function<
void()> click_fn) :
Contact<D>(
false), single_func_(click_fn) {}
338 PushButton(std::function<
void()> click_fn, std::function<
void()> repeat_fn)
339 :
Contact<D>(
false), single_func_(click_fn), repeat_func_(repeat_fn) {}
358 void contact_down(D time)
override {
359 if (!this->active_) {
360 this->active_ =
true;
363 }
else if (!repeat_func_) {
371 if (time - last_event_ > interval_) {
377 if (time - last_event_ > delay_) {
385 void contact_up(D)
override {
386 assert(this->active_);
394 this->active_ =
false;
396 last_event_ = D::zero();
400 std::function<void()> single_func_;
401 std::function<void()> repeat_func_;
402 D delay_{std::chrono::milliseconds(500)};
403 D interval_{std::chrono::milliseconds(250)};
406 D last_event_{D::zero()};
407 bool repeated_{
false};
425 template <
typename N>
426 typename std::enable_if<std::is_integral<N>::value, N>::type
round_step(N target, N increment) {
427 auto rem = target % increment;
432 return target + (increment - rem);
435 return target + increment;
444 template <
typename N>
445 typename std::enable_if<std::is_floating_point<N>::value, N>::type
round_step(N target,
447 auto rem = fmod(target, increment);
452 return target + (increment - rem);
455 return target + increment;
464 template <
typename D = Duration>
466 assert(ptr !=
nullptr);
467 return new Switch<D>([ptr]() { *ptr =
true; }, [ptr]() { *ptr =
false; }, *ptr);
473 template <
typename D = Duration>
475 assert(ptr !=
nullptr);
482 template <
typename D = Duration,
typename N>
484 assert(ptr !=
nullptr);
492 template <
typename D = Duration,
typename N>
494 assert(ptr !=
nullptr);
496 [ptr, multiple]() { *ptr += multiple; });
503 template <
typename D = Duration,
typename N>
505 assert(ptr !=
nullptr);
515 template <
typename D = Duration,
typename N>
517 assert(ptr !=
nullptr);
519 assert(multiple != 0);
521 [ptr, multiple]() { *ptr =
round_step(*ptr, multiple); });
530 template <
typename D = Duration,
typename N>
532 assert(ptr !=
nullptr);
549 template <
typename D = Duration,
typename N>
551 assert(ptr !=
nullptr);
553 assert(multiple != 0);
Definition: trigger.hpp:619
const std::string & description() const
Definition: entity.hpp:90
const std::string & name() const
Definition: entity.hpp:67
Definition: trigger.hpp:290
Definition: trigger.hpp:437
Definition: hmi_contact.hpp:288
void try_from(const std::string &key, T &val) const
Definition: conf.hpp:454
Definition: confable.hpp:98
Json to_json() const
Definition: confable.cpp:78
Definition: schema.hpp:173
Definition: struct.hpp:70
void set_property(const std::string &key, Box &&s)
Definition: struct.cpp:31
Definition: trigger.hpp:87
Definition: trigger.hpp:207
CallbackResult
Definition: trigger.hpp:514