Skip to content

Commit

Permalink
Merge pull request #1 from Flutterando/listen-other-notifiers-after-f…
Browse files Browse the repository at this point in the history
…irst-value

Fix some issues and remove invalid functionalities
  • Loading branch information
jacobaraujo7 authored Jun 30, 2024
2 parents 4f5085f + 86cbed3 commit a62c939
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 226 deletions.
96 changes: 0 additions & 96 deletions lib/src/async_value_selector.dart

This file was deleted.

55 changes: 37 additions & 18 deletions lib/src/value_selector.dart
Original file line number Diff line number Diff line change
@@ -1,44 +1,63 @@
part of '../value_selectable.dart';
import 'package:flutter/foundation.dart';

/// A selector that computes a synchronous value based on a given scope.
class ValueSelector<T> extends ValueSelectable<T> {
class ValueSelector<T> extends ChangeNotifier implements ValueListenable<T> {
final T Function(GetValue get) scope;
final Function? _set;
late final bool kActionWithArguments;
late T _value;
final _listenables = <Listenable>{};

@override
T get value => _value;

set value(dynamic newValue) {
if (_set != null) {
Function.apply(_set!, kActionWithArguments ? [newValue] : []);
late final _get = GetValue._(onListenableIdentified);

void onListenableIdentified(Listenable listenable) {
if (_listenables.add(listenable)) {
listenable.addListener(notifyListeners);
}
}

late final _get = GetValue._(notifyListeners);

/// Constructs a ValueSelector with an initial value and a scope function.
ValueSelector(this.scope, [this._set]) {
if (_set != null) {
var funcText = _set.runtimeType.toString();
assert(!funcText.contains(','), 'Function must have one argument.');
kActionWithArguments = !funcText.startsWith('() =>');
}

ValueSelector(this.scope) {
_value = scope(_get);
_get._tracking = false;
}

@override
void notifyListeners() {
_value = scope(_get);
_listenables.clear();
final newValue = scope(_get);

if (newValue == _value) return;
_value = newValue;
super.notifyListeners();
}

@override
void dispose() {
_get.dispose();
for (var listenable in _listenables) {
listenable.removeListener(notifyListeners);
}
super.dispose();
}
}

/// Helper class to manage value dependencies and tracking for selectors.
final class GetValue {
final void Function(Listenable listenable) _selectorIdentifyListenable;
GetValue._(this._selectorIdentifyListenable);

bool _isDisposed = false;

/// Registers a notifier and returns its value.
R call<R>(ValueListenable<R> notifier) {
if (_isDisposed) throw Exception('It is disposed');
_selectorIdentifyListenable.call(notifier);
return notifier.value;
}

/// Disposes of all registered listeners.
void dispose() {
_isDisposed = true;
}
}
23 changes: 6 additions & 17 deletions lib/value_selectable.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
library value_selectable;

import 'dart:async';
import 'dart:collection';

import 'package:flutter/foundation.dart';

part 'src/async_value_selector.dart';
part 'src/value_selector.dart';
export 'src/value_selector.dart';

/// Abstract class for a selectable value, extending ChangeNotifier.
abstract class ValueSelectable<T> extends ChangeNotifier
Expand All @@ -16,27 +12,20 @@ typedef SetValue<T> = void Function(T value);

/// Helper class to manage value dependencies and tracking for selectors.
final class GetValue {
final void Function() _selectorNotifyListeners;
final List<void Function()> _disposers = [];
var _tracking = true;
bool _isDisposed = false;
final void Function(Listenable listenable) _selectorIdentifyListenable;
GetValue._(this._selectorIdentifyListenable);

GetValue._(this._selectorNotifyListeners);
bool _isDisposed = false;

/// Registers a notifier and returns its value.
R call<R>(ValueListenable<R> notifier) {
if (_tracking) {
notifier.addListener(_selectorNotifyListeners);
_disposers.add(() => notifier.removeListener(_selectorNotifyListeners));
}
if (_isDisposed) throw Exception('It is disposed');
_selectorIdentifyListenable.call(notifier);
return notifier.value;
}

/// Disposes of all registered listeners.
void dispose() {
_isDisposed = true;
for (final disposer in _disposers) {
disposer();
}
}
}
64 changes: 0 additions & 64 deletions test/src/async_value_selector_test.dart

This file was deleted.

Loading

0 comments on commit a62c939

Please sign in to comment.