Skip to content

Commit

Permalink
feat(bloc): deprecate BlocOverrides (#3469)
Browse files Browse the repository at this point in the history
  • Loading branch information
felangel committed Aug 6, 2022
1 parent def9368 commit d62d947
Show file tree
Hide file tree
Showing 12 changed files with 2,835 additions and 646 deletions.
16 changes: 4 additions & 12 deletions packages/bloc/README.md
Expand Up @@ -172,12 +172,8 @@ class MyBlocObserver extends BlocObserver {

```dart
void main() {
BlocOverrides.runZoned(
() {
// Use cubits...
},
blocObserver: MyBlocObserver(),
);
Bloc.observer = MyBlocObserver();
// Use cubits...
}
```

Expand Down Expand Up @@ -327,12 +323,8 @@ class MyBlocObserver extends BlocObserver {

```dart
void main() {
BlocOverrides.runZoned(
() {
// Use blocs...
},
blocObserver: MyBlocObserver(),
);
Bloc.observer = MyBlocObserver();
// Use blocs...
}
```

Expand Down
7 changes: 3 additions & 4 deletions packages/bloc/example/main.dart
Expand Up @@ -41,10 +41,9 @@ class SimpleBlocObserver extends BlocObserver {
}

void main() {
BlocOverrides.runZoned(() {
cubitMain();
blocMain();
}, blocObserver: SimpleBlocObserver());
Bloc.observer = SimpleBlocObserver();
cubitMain();
blocMain();
}

void cubitMain() {
Expand Down
86 changes: 77 additions & 9 deletions packages/bloc/lib/src/bloc.dart
Expand Up @@ -36,12 +36,6 @@ typedef EventTransformer<Event> = Stream<Event> Function(
EventMapper<Event> mapper,
);

class _Handler {
const _Handler({required this.isType, required this.type});
final bool Function(dynamic value) isType;
final Type type;
}

/// {@template bloc}
/// Takes a `Stream` of `Events` as input
/// and transforms them into a `Stream` of `States` as output.
Expand All @@ -51,12 +45,33 @@ abstract class Bloc<Event, State> extends BlocBase<State>
/// {@macro bloc}
Bloc(State initialState) : super(initialState);

/// The current [BlocObserver] instance.
static BlocObserver observer = _DefaultBlocObserver();

/// The default [EventTransformer] used for all event handlers.
/// By default all events are processed concurrently.
///
/// If a custom transformer is specified for a particular event handler,
/// it will take precendence over the global transformer.
///
/// See also:
///
/// * [package:bloc_concurrency](https://pub.dev/packages/bloc_concurrency) for an
/// opinionated set of event transformers.
///
static EventTransformer<dynamic> transformer = (events, mapper) {
return events
.map(mapper)
.transform<dynamic>(const _FlatMapStreamTransformer<dynamic>());
};

final _eventController = StreamController<Event>.broadcast();
final _subscriptions = <StreamSubscription<dynamic>>[];
final _handlers = <_Handler>[];
final _emitters = <_Emitter>[];
final _eventTransformer =
BlocOverrides.current?.eventTransformer ?? _defaultEventTransformer;
// ignore: deprecated_member_use_from_same_package
BlocOverrides.current?.eventTransformer ?? Bloc.transformer;

/// Notifies the [Bloc] of a new [event] which triggers
/// all corresponding [EventHandler] instances.
Expand Down Expand Up @@ -110,7 +125,7 @@ abstract class Bloc<Event, State> extends BlocBase<State>
@mustCallSuper
void onEvent(Event event) {
// ignore: invalid_use_of_protected_member
_blocObserver?.onEvent(this, event);
_blocObserver.onEvent(this, event);
}

/// {@template emit}
Expand Down Expand Up @@ -250,7 +265,7 @@ abstract class Bloc<Event, State> extends BlocBase<State>
@mustCallSuper
void onTransition(Transition<Event, State> transition) {
// ignore: invalid_use_of_protected_member
_blocObserver?.onTransition(this, transition);
_blocObserver.onTransition(this, transition);
}

/// Closes the `event` and `state` `Streams`.
Expand All @@ -271,3 +286,56 @@ abstract class Bloc<Event, State> extends BlocBase<State>
return super.close();
}
}

class _Handler {
const _Handler({required this.isType, required this.type});
final bool Function(dynamic value) isType;
final Type type;
}

class _DefaultBlocObserver extends BlocObserver {}

class _FlatMapStreamTransformer<T> extends StreamTransformerBase<Stream<T>, T> {
const _FlatMapStreamTransformer();

@override
Stream<T> bind(Stream<Stream<T>> stream) {
final controller = StreamController<T>.broadcast(sync: true);

controller.onListen = () {
final subscriptions = <StreamSubscription<dynamic>>[];

final outerSubscription = stream.listen(
(inner) {
final subscription = inner.listen(
controller.add,
onError: controller.addError,
);

subscription.onDone(() {
subscriptions.remove(subscription);
if (subscriptions.isEmpty) controller.close();
});

subscriptions.add(subscription);
},
onError: controller.addError,
);

outerSubscription.onDone(() {
subscriptions.remove(outerSubscription);
if (subscriptions.isEmpty) controller.close();
});

subscriptions.add(outerSubscription);

controller.onCancel = () {
if (subscriptions.isEmpty) return null;
final cancels = [for (final s in subscriptions) s.cancel()];
return Future.wait(cancels).then((_) {});
};
};

return controller.stream;
}
}
11 changes: 6 additions & 5 deletions packages/bloc/lib/src/bloc_base.dart
Expand Up @@ -53,10 +53,11 @@ abstract class BlocBase<State>
/// {@macro bloc_base}
BlocBase(this._state) {
// ignore: invalid_use_of_protected_member
_blocObserver?.onCreate(this);
_blocObserver.onCreate(this);
}

final _blocObserver = BlocOverrides.current?.blocObserver;
// ignore: deprecated_member_use_from_same_package
final _blocObserver = BlocOverrides.current?.blocObserver ?? Bloc.observer;

late final _stateController = StreamController<State>.broadcast();

Expand Down Expand Up @@ -129,7 +130,7 @@ abstract class BlocBase<State>
@mustCallSuper
void onChange(Change<State> change) {
// ignore: invalid_use_of_protected_member
_blocObserver?.onChange(this, change);
_blocObserver.onChange(this, change);
}

/// Reports an [error] which triggers [onError] with an optional [StackTrace].
Expand Down Expand Up @@ -157,7 +158,7 @@ abstract class BlocBase<State>
@mustCallSuper
void onError(Object error, StackTrace stackTrace) {
// ignore: invalid_use_of_protected_member
_blocObserver?.onError(this, error, stackTrace);
_blocObserver.onError(this, error, stackTrace);
}

/// Closes the instance.
Expand All @@ -167,7 +168,7 @@ abstract class BlocBase<State>
@override
Future<void> close() async {
// ignore: invalid_use_of_protected_member
_blocObserver?.onClose(this);
_blocObserver.onClose(this);
await _stateController.close();
}
}
68 changes: 12 additions & 56 deletions packages/bloc/lib/src/bloc_overrides.dart
@@ -1,3 +1,5 @@
// ignore_for_file: deprecated_member_use_from_same_package

part of 'bloc.dart';

const _asyncRunZoned = runZoned;
Expand Down Expand Up @@ -34,9 +36,15 @@ abstract class BlocOverrides {
/// See also:
/// * [BlocOverrides.runZoned] to provide [BlocOverrides] in a fresh [Zone].
///
@Deprecated(
'This will be removed in v9.0.0. Use Bloc.observer/Bloc.transformer instead.',
)
static BlocOverrides? get current => Zone.current[_token] as BlocOverrides?;

/// Runs [body] in a fresh [Zone] using the provided overrides.
@Deprecated(
'This will be removed in v9.0.0. Use Bloc.observer/Bloc.transformer instead.',
)
static R runZoned<R>(
R Function() body, {
BlocObserver? blocObserver,
Expand All @@ -49,7 +57,8 @@ abstract class BlocOverrides {
/// The [BlocObserver] that will be used within the current [Zone].
///
/// By default, a base [BlocObserver] implementation is used.
BlocObserver get blocObserver => _defaultBlocObserver;
@Deprecated('This will be removed in v9.0.0. Use Bloc.observer instead.')
BlocObserver get blocObserver => Bloc.observer;

/// The [EventTransformer] that will be used within the current [Zone].
///
Expand All @@ -63,7 +72,8 @@ abstract class BlocOverrides {
/// * [package:bloc_concurrency](https://pub.dev/packages/bloc_concurrency) for an
/// opinionated set of event transformers.
///
EventTransformer get eventTransformer => _defaultEventTransformer;
@Deprecated('This will be removed in v9.0.0. Use Bloc.transformer instead.')
EventTransformer get eventTransformer => Bloc.transformer;
}

class _BlocOverridesScope extends BlocOverrides {
Expand Down Expand Up @@ -95,57 +105,3 @@ class _BlocOverridesScope extends BlocOverrides {
return super.eventTransformer;
}
}

late final _defaultBlocObserver = _DefaultBlocObserver();
late final _defaultEventTransformer = (Stream events, EventMapper mapper) {
return events
.map(mapper)
.transform<dynamic>(const _FlatMapStreamTransformer<dynamic>());
};

class _DefaultBlocObserver extends BlocObserver {}

class _FlatMapStreamTransformer<T> extends StreamTransformerBase<Stream<T>, T> {
const _FlatMapStreamTransformer();

@override
Stream<T> bind(Stream<Stream<T>> stream) {
final controller = StreamController<T>.broadcast(sync: true);

controller.onListen = () {
final subscriptions = <StreamSubscription<dynamic>>[];

final outerSubscription = stream.listen(
(inner) {
final subscription = inner.listen(
controller.add,
onError: controller.addError,
);

subscription.onDone(() {
subscriptions.remove(subscription);
if (subscriptions.isEmpty) controller.close();
});

subscriptions.add(subscription);
},
onError: controller.addError,
);

outerSubscription.onDone(() {
subscriptions.remove(outerSubscription);
if (subscriptions.isEmpty) controller.close();
});

subscriptions.add(outerSubscription);

controller.onCancel = () {
if (subscriptions.isEmpty) return null;
final cancels = [for (final s in subscriptions) s.cancel()];
return Future.wait(cancels).then((_) {});
};
};

return controller.stream;
}
}

0 comments on commit d62d947

Please sign in to comment.