Skip to content

Commit

Permalink
Avoid unnecessary observable notifications of Iterable or Map fields
Browse files Browse the repository at this point in the history
  • Loading branch information
amondnet committed Nov 2, 2023
1 parent 74dba7d commit 39e5f28
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 19 deletions.
21 changes: 3 additions & 18 deletions mobx/lib/src/core/atom_extensions.dart
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -10,7 +11,7 @@ extension AtomSpyReporter on Atom {
void reportWrite<T>(T newValue, T oldValue, void Function() setNewValue,
{EqualityComparer<T>? equals}) {
final areEqual = equals == null
? _equals(oldValue, newValue)
? equatable(oldValue, newValue)
: equals(oldValue, newValue);

Check warning on line 15 in mobx/lib/src/core/atom_extensions.dart

View check run for this annotation

Codecov / codecov/patch

mobx/lib/src/core/atom_extensions.dart#L15

Added line #L15 was not covered by tests

// Avoid unnecessary observable notifications of @observable fields of Stores
Expand All @@ -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>(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();
2 changes: 1 addition & 1 deletion mobx/lib/src/core/observable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class Observable<T> extends Atom
}

final areEqual =
equals == null ? prepared == value : equals!(prepared, _value);
equals == null ? equatable(prepared, value) : equals!(prepared, _value);

return (!areEqual) ? prepared : WillChangeNotification.unchanged;
}
Expand Down
18 changes: 18 additions & 0 deletions mobx/lib/src/utils.dart
Original file line number Diff line number Diff line change
@@ -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) =>
Expand All @@ -20,3 +22,19 @@ mixin DebugCreationStack {
return result;
}();
}

/// Determines whether [a] and [b] are equal.
bool equatable<T>(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();

0 comments on commit 39e5f28

Please sign in to comment.