Move TemplatableValue helper class to automation.h (#2511)

This commit is contained in:
Oxan van Leeuwen 2021-10-15 22:05:11 +02:00 committed by GitHub
parent 653a3d5d11
commit c82d5d63e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 65 deletions

View file

@ -8,6 +8,18 @@
namespace esphome { namespace esphome {
namespace api { namespace api {
template<typename... X> class TemplatableStringValue : public TemplatableValue<std::string, X...> {
public:
TemplatableStringValue() : TemplatableValue<std::string, X...>() {}
template<typename F, enable_if_t<!is_callable<F, X...>::value, int> = 0>
TemplatableStringValue(F value) : TemplatableValue<std::string, X...>(value) {}
template<typename F, enable_if_t<is_callable<F, X...>::value, int> = 0>
TemplatableStringValue(F f)
: TemplatableValue<std::string, X...>([f](X... x) -> std::string { return to_string(f(x...)); }) {}
};
template<typename... Ts> class TemplatableKeyValuePair { template<typename... Ts> class TemplatableKeyValuePair {
public: public:
template<typename T> TemplatableKeyValuePair(std::string key, T value) : key(std::move(key)), value(value) {} template<typename T> TemplatableKeyValuePair(std::string key, T value) : key(std::move(key)), value(value) {}
@ -19,7 +31,8 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
public: public:
explicit HomeAssistantServiceCallAction(APIServer *parent, bool is_event) : parent_(parent), is_event_(is_event) {} explicit HomeAssistantServiceCallAction(APIServer *parent, bool is_event) : parent_(parent), is_event_(is_event) {}
TEMPLATABLE_STRING_VALUE(service); template<typename T> void set_service(T service) { this->service_ = service; }
template<typename T> void add_data(std::string key, T value) { template<typename T> void add_data(std::string key, T value) {
this->data_.push_back(TemplatableKeyValuePair<Ts...>(key, value)); this->data_.push_back(TemplatableKeyValuePair<Ts...>(key, value));
} }
@ -58,6 +71,7 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
protected: protected:
APIServer *parent_; APIServer *parent_;
bool is_event_; bool is_event_;
TemplatableStringValue<Ts...> service_{};
std::vector<TemplatableKeyValuePair<Ts...>> data_; std::vector<TemplatableKeyValuePair<Ts...>> data_;
std::vector<TemplatableKeyValuePair<Ts...>> data_template_; std::vector<TemplatableKeyValuePair<Ts...>> data_template_;
std::vector<TemplatableKeyValuePair<Ts...>> variables_; std::vector<TemplatableKeyValuePair<Ts...>> variables_;

View file

@ -17,14 +17,50 @@ namespace esphome {
#define TEMPLATABLE_VALUE(type, name) TEMPLATABLE_VALUE_(type, name) #define TEMPLATABLE_VALUE(type, name) TEMPLATABLE_VALUE_(type, name)
#define TEMPLATABLE_STRING_VALUE_(name) \ template<typename T, typename... X> class TemplatableValue {
protected: \ public:
TemplatableStringValue<Ts...> name##_{}; \ TemplatableValue() : type_(EMPTY) {}
\
public: \
template<typename V> void set_##name(V name) { this->name##_ = name; }
#define TEMPLATABLE_STRING_VALUE(name) TEMPLATABLE_STRING_VALUE_(name) template<typename F, enable_if_t<!is_callable<F, X...>::value, int> = 0>
TemplatableValue(F value) : type_(VALUE), value_(value) {}
template<typename F, enable_if_t<is_callable<F, X...>::value, int> = 0>
TemplatableValue(F f) : type_(LAMBDA), f_(f) {}
bool has_value() { return this->type_ != EMPTY; }
T value(X... x) {
if (this->type_ == LAMBDA) {
return this->f_(x...);
}
// return value also when empty
return this->value_;
}
optional<T> optional_value(X... x) {
if (!this->has_value()) {
return {};
}
return this->value(x...);
}
T value_or(X... x, T default_value) {
if (!this->has_value()) {
return default_value;
}
return this->value(x...);
}
protected:
enum {
EMPTY,
VALUE,
LAMBDA,
} type_;
T value_{};
std::function<T(X...)> f_{};
};
/** Base class for all automation conditions. /** Base class for all automation conditions.
* *

View file

@ -255,63 +255,6 @@ struct is_callable // NOLINT
static constexpr auto value = decltype(test<T>(nullptr))::value; // NOLINT static constexpr auto value = decltype(test<T>(nullptr))::value; // NOLINT
}; };
template<typename T, typename... X> class TemplatableValue {
public:
TemplatableValue() : type_(EMPTY) {}
template<typename F, enable_if_t<!is_callable<F, X...>::value, int> = 0>
TemplatableValue(F value) : type_(VALUE), value_(value) {}
template<typename F, enable_if_t<is_callable<F, X...>::value, int> = 0>
TemplatableValue(F f) : type_(LAMBDA), f_(f) {}
bool has_value() { return this->type_ != EMPTY; }
T value(X... x) {
if (this->type_ == LAMBDA) {
return this->f_(x...);
}
// return value also when empty
return this->value_;
}
optional<T> optional_value(X... x) {
if (!this->has_value()) {
return {};
}
return this->value(x...);
}
T value_or(X... x, T default_value) {
if (!this->has_value()) {
return default_value;
}
return this->value(x...);
}
protected:
enum {
EMPTY,
VALUE,
LAMBDA,
} type_;
T value_{};
std::function<T(X...)> f_{};
};
template<typename... X> class TemplatableStringValue : public TemplatableValue<std::string, X...> {
public:
TemplatableStringValue() : TemplatableValue<std::string, X...>() {}
template<typename F, enable_if_t<!is_callable<F, X...>::value, int> = 0>
TemplatableStringValue(F value) : TemplatableValue<std::string, X...>(value) {}
template<typename F, enable_if_t<is_callable<F, X...>::value, int> = 0>
TemplatableStringValue(F f)
: TemplatableValue<std::string, X...>([f](X... x) -> std::string { return to_string(f(x...)); }) {}
};
void delay_microseconds_accurate(uint32_t usec); void delay_microseconds_accurate(uint32_t usec);
template<typename T> class Deduplicator { template<typename T> class Deduplicator {