| // Copyright 2019 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:flutter/foundation.dart'; |
| |
| typedef BrookCallback<T> = void Function(T event); |
| |
| /// A source of events of type T. |
| /// |
| /// This is a light-weight stream, hence the name of the class. |
| /// |
| /// Listeners cannot be registered multiple times simultaneously. |
| class Brook<T> { |
| Brook(); |
| |
| final Set<BrookCallback<T>> _listeners = <BrookCallback<T>>{}; |
| |
| void addListener(BrookCallback<T> listener) { |
| assert(!_listeners.contains(listener)); |
| _listeners.add(listener); |
| } |
| |
| void removeListener(BrookCallback<T> listener) { |
| assert(_listeners.contains(listener)); |
| _listeners.remove(listener); |
| } |
| } |
| |
| /// A place to send events of type T. |
| /// |
| /// Instances of this class can be given to consumers, as the type [Brook]. |
| /// This allows consumers to register for events without being able to send |
| /// events. |
| class BrookSink<T> extends Brook<T> { |
| BrookSink(); |
| |
| void send(T event) { |
| final List<BrookCallback<T>> frozenListeners = _listeners.toList(); |
| for (final BrookCallback<T> listener in frozenListeners) { |
| try { |
| if (_listeners.contains(listener)) { |
| listener(event); |
| } |
| } catch (exception, stack) { |
| FlutterError.reportError( |
| FlutterErrorDetails( |
| exception: exception, |
| stack: stack, |
| library: 'Flutter Dashboard', |
| context: ErrorDescription('while sending event'), |
| informationCollector: () sync* { |
| yield DiagnosticsProperty<BrookSink<T>>( |
| 'The $runtimeType sending the event was', |
| this, |
| style: DiagnosticsTreeStyle.errorProperty, |
| ); |
| yield DiagnosticsProperty<T>( |
| 'The $T event was', |
| event, |
| style: DiagnosticsTreeStyle.errorProperty, |
| ); |
| }, |
| ), |
| ); |
| } |
| } |
| } |
| } |
| |
| class ErrorSink extends BrookSink<String> { |
| ErrorSink(); |
| |
| @override |
| void send(String event) { |
| // TODO(ianh): log errors to a service as well, https://github.com/flutter/flutter/issues/52697 |
| debugPrint(event); // to allow for copy/paste |
| super.send(event); |
| } |
| } |