diff options
-rw-r--r-- | src/count.hpp | 27 | ||||
-rw-r--r-- | src/example/example.yaml | 8 | ||||
-rw-r--r-- | src/example/test.yaml | 2 | ||||
-rwxr-xr-x | src/pdmgen.py | 3 | ||||
-rw-r--r-- | src/templates/count.mako.cpp | 3 |
5 files changed, 38 insertions, 5 deletions
diff --git a/src/count.hpp b/src/count.hpp index f7b809f..51a76eb 100644 --- a/src/count.hpp +++ b/src/count.hpp @@ -26,6 +26,9 @@ namespace monitoring * one. In pass two, apply a second C++ relational operator * to the number of properties that pass the test from pass one * to a count provided by the configuration file. + * + * If the oneshot parameter is true, then this condition won't pass + * again until it fails at least once. */ template <typename T> class CountCondition : public IndexedConditional @@ -41,10 +44,12 @@ class CountCondition : public IndexedConditional CountCondition( const PropertyIndex& conditionIndex, const std::function<bool(size_t)>& _countOp, - const std::function<bool(T)>& _propertyOp) : + const std::function<bool(T)>& _propertyOp, + bool oneshot = false) : IndexedConditional(conditionIndex), countOp(_countOp), - propertyOp(_propertyOp) {} + propertyOp(_propertyOp), + oneshot(oneshot) {} bool operator()() override { @@ -70,7 +75,18 @@ class CountCondition : public IndexedConditional // *INDENT-ON* // Now apply the count condition to the count. - return countOp(count); + auto result = countOp(count); + + // If this was a oneshot and the the condition has already + // passed, then don't let it pass again until the condition + // has gone back to false. + if (oneshot && result && lastResult) + { + return false; + } + + lastResult = result; + return result; } private: @@ -78,6 +94,11 @@ class CountCondition : public IndexedConditional std::function<bool(size_t)> countOp; /** @brief The comparison to perform on each property. */ std::function<bool(T)> propertyOp; + /** @brief If the condition can be allowed to pass again + on subsequent checks that are also true. */ + const bool oneshot; + /** @brief The result of the previous check. */ + bool lastResult = false; }; } // namespace monitoring } // namespace dbus diff --git a/src/example/example.yaml b/src/example/example.yaml index 226f491..bfb1c62 100644 --- a/src/example/example.yaml +++ b/src/example/example.yaml @@ -181,7 +181,12 @@ For example, a callback that requires at least three temperature sensors in the group to be higher than 115 degrees might use a count condition - with an op of >, a count op of >=, a bound of 115, and a countbound of 3.' + with an op of >, a count op of >=, a bound of 115, and a countbound of 3. + + The optional oneshot parameter defaults to false. If it is specified and + set to true, then the callback will only be called once for as long as the + condition is repeatedly passing. The condition needs to fail at least + once to rearm the callback.' class: condition condition: count @@ -192,6 +197,7 @@ countbound: 3 op: '>=' bound: 115 + oneshot: true - name: example deferred condition description: > diff --git a/src/example/test.yaml b/src/example/test.yaml index fb37efe..6632891 100644 --- a/src/example/test.yaml +++ b/src/example/test.yaml @@ -317,6 +317,7 @@ countbound: 3 op: '<' bound: 115 + oneshot: true - name: test count lte class: condition @@ -329,6 +330,7 @@ countbound: 3 op: '<=' bound: 115 + oneshot: false - name: test count gt class: condition diff --git a/src/pdmgen.py b/src/pdmgen.py index fe3f826..7487015 100755 --- a/src/pdmgen.py +++ b/src/pdmgen.py @@ -645,6 +645,9 @@ class CountCondition(Condition, Renderer): self.countbound = kw.pop('countbound') self.op = kw.pop('op') self.bound = kw.pop('bound') + self.oneshot = TrivialArgument( + type='boolean', + value=kw.pop('oneshot', False)) super(CountCondition, self).__init__(**kw) def setup(self, objs): diff --git a/src/templates/count.mako.cpp b/src/templates/count.mako.cpp index 9ac9c3c..f4b4c8f 100644 --- a/src/templates/count.mako.cpp +++ b/src/templates/count.mako.cpp @@ -1,4 +1,5 @@ std::make_unique<CountCondition<${c.datatype}>>( ${indent(1)}ConfigPropertyIndicies::get()[${c.instances}], ${indent(1)}[](const auto& item){return item ${c.countop} ${c.countbound};}, -${indent(1)}[](const auto& item){return item ${c.op} ${c.bound.argument(loader, indent=indent +1)};})\ +${indent(1)}[](const auto& item){return item ${c.op} ${c.bound.argument(loader, indent=indent +1)};}, +${indent(1)}${c.oneshot.argument(loader, indent=indent +1)})\ |