mirror of
https://github.com/esphome/esphome.git
synced 2026-05-22 10:25:46 +08:00
[automation] Use std::array in And/Or/Xor conditions (#15282)
This commit is contained in:
+15
-5
@@ -250,7 +250,9 @@ async def and_condition_to_code(
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
conditions = await build_condition_list(config, template_arg, args)
|
||||
return cg.new_Pvariable(condition_id, template_arg, conditions)
|
||||
return cg.new_Pvariable(
|
||||
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
|
||||
)
|
||||
|
||||
|
||||
@register_condition("or", OrCondition, validate_condition_list)
|
||||
@@ -261,7 +263,9 @@ async def or_condition_to_code(
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
conditions = await build_condition_list(config, template_arg, args)
|
||||
return cg.new_Pvariable(condition_id, template_arg, conditions)
|
||||
return cg.new_Pvariable(
|
||||
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
|
||||
)
|
||||
|
||||
|
||||
@register_condition("all", AndCondition, validate_condition_list)
|
||||
@@ -272,7 +276,9 @@ async def all_condition_to_code(
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
conditions = await build_condition_list(config, template_arg, args)
|
||||
return cg.new_Pvariable(condition_id, template_arg, conditions)
|
||||
return cg.new_Pvariable(
|
||||
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
|
||||
)
|
||||
|
||||
|
||||
@register_condition("any", OrCondition, validate_condition_list)
|
||||
@@ -283,7 +289,9 @@ async def any_condition_to_code(
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
conditions = await build_condition_list(config, template_arg, args)
|
||||
return cg.new_Pvariable(condition_id, template_arg, conditions)
|
||||
return cg.new_Pvariable(
|
||||
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
|
||||
)
|
||||
|
||||
|
||||
@register_condition("not", NotCondition, validate_potentially_and_condition)
|
||||
@@ -305,7 +313,9 @@ async def xor_condition_to_code(
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
conditions = await build_condition_list(config, template_arg, args)
|
||||
return cg.new_Pvariable(condition_id, template_arg, conditions)
|
||||
return cg.new_Pvariable(
|
||||
condition_id, cg.TemplateArguments(len(conditions), *template_arg), conditions
|
||||
)
|
||||
|
||||
|
||||
@register_condition("lambda", LambdaCondition, cv.returning_lambda)
|
||||
|
||||
@@ -9,14 +9,17 @@
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
#include <array>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
template<typename... Ts> class AndCondition : public Condition<Ts...> {
|
||||
template<size_t N, typename... Ts> class AndCondition : public Condition<Ts...> {
|
||||
public:
|
||||
explicit AndCondition(std::initializer_list<Condition<Ts...> *> conditions) : conditions_(conditions) {}
|
||||
explicit AndCondition(std::initializer_list<Condition<Ts...> *> conditions) {
|
||||
init_array_from(this->conditions_, conditions);
|
||||
}
|
||||
bool check(const Ts &...x) override {
|
||||
for (auto *condition : this->conditions_) {
|
||||
if (!condition->check(x...))
|
||||
@@ -27,12 +30,14 @@ template<typename... Ts> class AndCondition : public Condition<Ts...> {
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVector<Condition<Ts...> *> conditions_;
|
||||
std::array<Condition<Ts...> *, N> conditions_{};
|
||||
};
|
||||
|
||||
template<typename... Ts> class OrCondition : public Condition<Ts...> {
|
||||
template<size_t N, typename... Ts> class OrCondition : public Condition<Ts...> {
|
||||
public:
|
||||
explicit OrCondition(std::initializer_list<Condition<Ts...> *> conditions) : conditions_(conditions) {}
|
||||
explicit OrCondition(std::initializer_list<Condition<Ts...> *> conditions) {
|
||||
init_array_from(this->conditions_, conditions);
|
||||
}
|
||||
bool check(const Ts &...x) override {
|
||||
for (auto *condition : this->conditions_) {
|
||||
if (condition->check(x...))
|
||||
@@ -43,7 +48,7 @@ template<typename... Ts> class OrCondition : public Condition<Ts...> {
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVector<Condition<Ts...> *> conditions_;
|
||||
std::array<Condition<Ts...> *, N> conditions_{};
|
||||
};
|
||||
|
||||
template<typename... Ts> class NotCondition : public Condition<Ts...> {
|
||||
@@ -55,9 +60,11 @@ template<typename... Ts> class NotCondition : public Condition<Ts...> {
|
||||
Condition<Ts...> *condition_;
|
||||
};
|
||||
|
||||
template<typename... Ts> class XorCondition : public Condition<Ts...> {
|
||||
template<size_t N, typename... Ts> class XorCondition : public Condition<Ts...> {
|
||||
public:
|
||||
explicit XorCondition(std::initializer_list<Condition<Ts...> *> conditions) : conditions_(conditions) {}
|
||||
explicit XorCondition(std::initializer_list<Condition<Ts...> *> conditions) {
|
||||
init_array_from(this->conditions_, conditions);
|
||||
}
|
||||
bool check(const Ts &...x) override {
|
||||
size_t result = 0;
|
||||
for (auto *condition : this->conditions_) {
|
||||
@@ -68,7 +75,7 @@ template<typename... Ts> class XorCondition : public Condition<Ts...> {
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVector<Condition<Ts...> *> conditions_;
|
||||
std::array<Condition<Ts...> *, N> conditions_{};
|
||||
};
|
||||
|
||||
template<typename... Ts> class LambdaCondition : public Condition<Ts...> {
|
||||
|
||||
@@ -500,7 +500,8 @@ template<typename T, size_t MAX_CAPACITY = std::numeric_limits<uint16_t>::max()>
|
||||
|
||||
/// Initialize a std::array from an initializer_list. Uses memcpy for trivially copyable types (optimal codegen),
|
||||
/// falls back to element-wise copy for non-trivially copyable types (e.g. TemplatableValue).
|
||||
/// N is set by code generation; assert catches mismatches in debug/integration tests.
|
||||
/// N is always set by code generation — the caller is responsible for ensuring src.size() == N.
|
||||
/// The debug assert is a safety net for development, not a runtime check.
|
||||
template<typename T, size_t N> inline void init_array_from(std::array<T, N> &dest, std::initializer_list<T> src) {
|
||||
#ifdef ESPHOME_DEBUG
|
||||
assert(src.size() == N);
|
||||
|
||||
Reference in New Issue
Block a user