[sensor] Use std::array in OrFilter (#15262)

This commit is contained in:
J. Nick Koston
2026-03-29 14:55:46 -10:00
committed by GitHub
parent 66754fa376
commit 508ec295a4
3 changed files with 34 additions and 30 deletions
+1 -1
View File
@@ -620,7 +620,7 @@ async def delta_filter_to_code(config, filter_id):
@FILTER_REGISTRY.register("or", OrFilter, validate_filters)
async def or_filter_to_code(config, filter_id):
filters = await build_filters(config)
return cg.new_Pvariable(filter_id, filters)
return cg.new_Pvariable(filter_id, cg.TemplateArguments(len(filters)), filters)
@FILTER_REGISTRY.register(
+9 -21
View File
@@ -295,32 +295,20 @@ optional<float> DeltaFilter::new_value(float value) {
return {};
}
// OrFilter
OrFilter::OrFilter(std::initializer_list<Filter *> filters) : filters_(filters), phi_(this) {}
OrFilter::PhiNode::PhiNode(OrFilter *or_parent) : or_parent_(or_parent) {}
optional<float> OrFilter::PhiNode::new_value(float value) {
if (!this->or_parent_->has_value_) {
this->or_parent_->output(value);
this->or_parent_->has_value_ = true;
// OrFilter helpers
void or_filter_initialize(Filter **filters, size_t count, Sensor *parent, Filter *phi) {
for (size_t i = 0; i < count; i++) {
filters[i]->initialize(parent, phi);
}
return {};
phi->initialize(parent, nullptr);
}
optional<float> OrFilter::new_value(float value) {
this->has_value_ = false;
for (auto *filter : this->filters_)
filter->input(value);
optional<float> or_filter_new_value(Filter **filters, size_t count, float value, bool &has_value) {
has_value = false;
for (size_t i = 0; i < count; i++)
filters[i]->input(value);
return {};
}
void OrFilter::initialize(Sensor *parent, Filter *next) {
Filter::initialize(parent, next);
for (auto *filter : this->filters_) {
filter->initialize(parent, &this->phi_);
}
this->phi_.initialize(parent, nullptr);
}
// TimeoutFilterBase - shared loop logic
void TimeoutFilterBase::loop() {
+24 -8
View File
@@ -489,26 +489,42 @@ class DeltaFilter : public Filter {
float last_value_{NAN};
};
class OrFilter : public Filter {
/// Non-template helpers for OrFilter (implementation in filter.cpp)
void or_filter_initialize(Filter **filters, size_t count, Sensor *parent, Filter *phi);
optional<float> or_filter_new_value(Filter **filters, size_t count, float value, bool &has_value);
/// N is set by code generation to match the exact number of filters configured in YAML.
template<size_t N> class OrFilter : public Filter {
public:
explicit OrFilter(std::initializer_list<Filter *> filters);
explicit OrFilter(std::initializer_list<Filter *> filters) { init_array_from(this->filters_, filters); }
void initialize(Sensor *parent, Filter *next) override;
void initialize(Sensor *parent, Filter *next) override {
Filter::initialize(parent, next);
or_filter_initialize(this->filters_.data(), N, parent, &this->phi_);
}
optional<float> new_value(float value) override;
optional<float> new_value(float value) override {
return or_filter_new_value(this->filters_.data(), N, value, this->has_value_);
}
protected:
class PhiNode : public Filter {
public:
PhiNode(OrFilter *or_parent);
optional<float> new_value(float value) override;
PhiNode(OrFilter *or_parent) : or_parent_(or_parent) {}
optional<float> new_value(float value) override {
if (!this->or_parent_->has_value_) {
this->or_parent_->output(value);
this->or_parent_->has_value_ = true;
}
return {};
}
protected:
OrFilter *or_parent_;
};
FixedVector<Filter *> filters_;
PhiNode phi_;
std::array<Filter *, N> filters_{};
PhiNode phi_{this};
bool has_value_{false};
};