@@ -142,15 +142,6 @@ class QuieterReportingAttribute
142
142
};
143
143
}
144
144
145
- /* *
146
- * @brief Factory to generate a functor that forces reportable now.
147
- * @return a functor usable for the `changedPredicate` arg of `SetValue()`
148
- */
149
- static SufficientChangePredicate GetForceReportablePredicate ()
150
- {
151
- return [](const SufficientChangePredicateCandidate & candidate) -> bool { return true ; };
152
- }
153
-
154
145
Nullable<T> value () const { return mValue ; }
155
146
QuieterReportingPolicyFlags & policy () { return mPolicyFlags ; }
156
147
const QuieterReportingPolicyFlags & policy () const { return mPolicyFlags ; }
@@ -163,6 +154,7 @@ class QuieterReportingAttribute
163
154
* - The policies from `QuieterReportingPolicyEnum` and set via `SetPolicy()` are self-explanatory by name.
164
155
* - The changedPredicate will be called with last dirty <timestamp, value> and new <timestamp value> and may override
165
156
* the dirty state altogether when it returns true. Use sparingly and default to a functor returning false.
157
+ * The changedPredicate is only called on change.
166
158
*
167
159
* Internal recording will be done about last dirty value and last dirty timestamp based on the policies having applied.
168
160
*
@@ -172,13 +164,13 @@ class QuieterReportingAttribute
172
164
* @return AttributeDirtyState::kMustReport if attribute must be marked dirty right away, or
173
165
* AttributeDirtyState::kNoReportNeeded otherwise.
174
166
*/
175
- AttributeDirtyState SetValue (const chip::app::DataModel::Nullable<T> & newValue, Timestamp now,
176
- SufficientChangePredicate changedPredicate)
167
+ AttributeDirtyState SetValue (const DataModel::Nullable<T> & newValue, Timestamp now, SufficientChangePredicate changedPredicate)
177
168
{
178
- bool isChangeOfNull = newValue.IsNull () ^ mValue .IsNull ();
179
- bool areBothValuesNonNull = !newValue.IsNull () && !mValue .IsNull ();
169
+ bool isChangeOfNull = newValue.IsNull () != mValue .IsNull ();
170
+ bool areBothValuesNonNull = !newValue.IsNull () && !mValue .IsNull ();
171
+ bool areBothValuesDifferent = areBothValuesNonNull && (newValue.Value () != mValue .Value ());
180
172
181
- bool changeToFromZero = areBothValuesNonNull && (newValue.Value () == 0 || mValue .Value () == 0 );
173
+ bool changeToFromZero = areBothValuesNonNull && areBothValuesDifferent && (newValue.Value () == 0 || mValue .Value () == 0 );
182
174
bool isIncrement = areBothValuesNonNull && (newValue.Value () > mValue .Value ());
183
175
bool isDecrement = areBothValuesNonNull && (newValue.Value () < mValue .Value ());
184
176
@@ -188,13 +180,17 @@ class QuieterReportingAttribute
188
180
isNewlyDirty = isNewlyDirty || (mPolicyFlags .Has (QuieterReportingPolicyEnum::kMarkDirtyOnDecrement ) && isDecrement);
189
181
isNewlyDirty = isNewlyDirty || (mPolicyFlags .Has (QuieterReportingPolicyEnum::kMarkDirtyOnIncrement ) && isIncrement);
190
182
191
- SufficientChangePredicateCandidate candidate{
192
- mLastDirtyTimestampMillis , // lastDirtyTimestamp
193
- now, // nowTimestamp
194
- mLastDirtyValue , // lastDirtyValue
195
- newValue // newValue
196
- };
197
- isNewlyDirty = isNewlyDirty || changedPredicate (candidate);
183
+ // Only execute predicate on value change from last marked dirty.
184
+ if (newValue != mLastDirtyValue )
185
+ {
186
+ SufficientChangePredicateCandidate candidate{
187
+ mLastDirtyTimestampMillis , // lastDirtyTimestamp
188
+ now, // nowTimestamp
189
+ mLastDirtyValue , // lastDirtyValue
190
+ newValue // newValue
191
+ };
192
+ isNewlyDirty = isNewlyDirty || changedPredicate (candidate);
193
+ }
198
194
199
195
mValue = newValue;
200
196
@@ -217,20 +213,20 @@ class QuieterReportingAttribute
217
213
* @return AttributeDirtyState::kMustReport if attribute must be marked dirty right away, or
218
214
* AttributeDirtyState::kNoReportNeeded otherwise.
219
215
*/
220
- AttributeDirtyState SetValue (const chip::app:: DataModel::Nullable<T> & newValue, Timestamp now)
216
+ AttributeDirtyState SetValue (const DataModel::Nullable<T> & newValue, Timestamp now)
221
217
{
222
218
return SetValue (newValue, now, [](const SufficientChangePredicateCandidate &) -> bool { return false ; });
223
219
}
224
220
225
221
protected:
226
222
// Current value of the attribute.
227
- chip::app:: DataModel::Nullable<T> mValue ;
223
+ DataModel::Nullable<T> mValue ;
228
224
// Last value that was marked as dirty (to use in comparisons for change, e.g. by SufficientChangePredicate).
229
- chip::app:: DataModel::Nullable<T> mLastDirtyValue ;
225
+ DataModel::Nullable<T> mLastDirtyValue ;
230
226
// Enabled internal change detection policies.
231
227
QuieterReportingPolicyFlags mPolicyFlags { 0 };
232
228
// Timestamp associated with the last time the attribute was marked dirty (to use in comparisons for change).
233
- chip::System::Clock::Milliseconds64 mLastDirtyTimestampMillis {};
229
+ chip::System::Clock::Timestamp mLastDirtyTimestampMillis {};
234
230
};
235
231
236
232
} // namespace detail
0 commit comments