From c17b55170a35fa24d2c2a925a55bc2040c6a2b05 Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Thu, 2 Nov 2023 23:30:52 +0900 Subject: [PATCH] Avoid unnecessary observable notifications of `Iterable` or `Map` fields --- mobx/lib/src/core/atom_extensions.dart | 21 +++------------------ mobx/lib/src/core/observable.dart | 2 +- mobx/lib/src/utils.dart | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/mobx/lib/src/core/atom_extensions.dart b/mobx/lib/src/core/atom_extensions.dart index 936fed7b0..b532b4236 100644 --- a/mobx/lib/src/core/atom_extensions.dart +++ b/mobx/lib/src/core/atom_extensions.dart @@ -1,6 +1,7 @@ -import 'package:collection/collection.dart'; import 'package:mobx/mobx.dart'; +import '../utils.dart'; + extension AtomSpyReporter on Atom { void reportRead() { context.enforceReadPolicy(this); @@ -10,7 +11,7 @@ extension AtomSpyReporter on Atom { void reportWrite(T newValue, T oldValue, void Function() setNewValue, {EqualityComparer? equals}) { final areEqual = equals == null - ? _equals(oldValue, newValue) + ? equatable(oldValue, newValue) : equals(oldValue, newValue); // Avoid unnecessary observable notifications of @observable fields of Stores @@ -33,19 +34,3 @@ extension AtomSpyReporter on Atom { context.spyReport(EndedSpyEvent(type: 'observable', name: name)); } } - -/// Determines whether [a] and [b] are equal. -bool _equals(T a, T b) { - if (identical(a, b)) return true; - if (a is Iterable || a is Map) { - if (!_equality.equals(a, b)) return false; - } else if (a.runtimeType != b.runtimeType) { - return false; - } else if (a != b) { - return false; - } - - return true; -} - -const DeepCollectionEquality _equality = DeepCollectionEquality(); diff --git a/mobx/lib/src/core/observable.dart b/mobx/lib/src/core/observable.dart index a29230479..70290a094 100644 --- a/mobx/lib/src/core/observable.dart +++ b/mobx/lib/src/core/observable.dart @@ -105,7 +105,7 @@ class Observable extends Atom } final areEqual = - equals == null ? prepared == value : equals!(prepared, _value); + equals == null ? equatable(prepared, value) : equals!(prepared, _value); return (!areEqual) ? prepared : WillChangeNotification.unchanged; } diff --git a/mobx/lib/src/utils.dart b/mobx/lib/src/utils.dart index cd81d806b..80c30b828 100644 --- a/mobx/lib/src/utils.dart +++ b/mobx/lib/src/utils.dart @@ -1,5 +1,7 @@ import 'dart:async'; +import 'package:collection/collection.dart' show DeepCollectionEquality; + const Duration ms = Duration(milliseconds: 1); Timer Function(void Function()) createDelayedScheduler(int delayMs) => @@ -20,3 +22,19 @@ mixin DebugCreationStack { return result; }(); } + +/// Determines whether [a] and [b] are equal. +bool equatable(T a, T b) { + if (identical(a, b)) return true; + if (a is Iterable || a is Map) { + if (!_equality.equals(a, b)) return false; + } else if (a.runtimeType != b.runtimeType) { + return false; + } else if (a != b) { + return false; + } + + return true; +} + +const DeepCollectionEquality _equality = DeepCollectionEquality();