[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) @FILTER_REGISTRY.register("or", OrFilter, validate_filters)
async def or_filter_to_code(config, filter_id): async def or_filter_to_code(config, filter_id):
filters = await build_filters(config) 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( @FILTER_REGISTRY.register(
+9 -21
View File
@@ -295,32 +295,20 @@ optional<float> DeltaFilter::new_value(float value) {
return {}; return {};
} }
// OrFilter // OrFilter helpers
OrFilter::OrFilter(std::initializer_list<Filter *> filters) : filters_(filters), phi_(this) {} void or_filter_initialize(Filter **filters, size_t count, Sensor *parent, Filter *phi) {
OrFilter::PhiNode::PhiNode(OrFilter *or_parent) : or_parent_(or_parent) {} for (size_t i = 0; i < count; i++) {
filters[i]->initialize(parent, phi);
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;
} }
phi->initialize(parent, nullptr);
return {};
} }
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 {}; 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 // TimeoutFilterBase - shared loop logic
void TimeoutFilterBase::loop() { void TimeoutFilterBase::loop() {
+24 -8
View File
@@ -489,26 +489,42 @@ class DeltaFilter : public Filter {
float last_value_{NAN}; 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: 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: protected:
class PhiNode : public Filter { class PhiNode : public Filter {
public: public:
PhiNode(OrFilter *or_parent); PhiNode(OrFilter *or_parent) : or_parent_(or_parent) {}
optional<float> new_value(float value) override; 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: protected:
OrFilter *or_parent_; OrFilter *or_parent_;
}; };
FixedVector<Filter *> filters_; std::array<Filter *, N> filters_{};
PhiNode phi_; PhiNode phi_{this};
bool has_value_{false}; bool has_value_{false};
}; };