Skip to content

Instantly share code, notes, and snippets.

@dnys1
Last active July 17, 2020 20:22
Show Gist options
  • Save dnys1/08770e275e65dedadbaaa88c0b3c70f1 to your computer and use it in GitHub Desktop.
Save dnys1/08770e275e65dedadbaaa88c0b3c70f1 to your computer and use it in GitHub Desktop.
import 'dart:async';
/// A [Bloc] transforms events of type [Event] into a [Stream] of [State]s.
abstract class Bloc<Event, State> {
final _eventController = StreamController<Event>.broadcast();
final _stateController = StreamController<State>.broadcast();
Bloc(this._initialState) {
init();
}
final State _initialState;
State _state;
State get state => _state ?? _initialState;
Stream<State> get states => _stateController.stream;
void init() {
_eventController.stream.asyncExpand(mapEventToState).listen((state) {
_state = state;
_stateController.add(state);
});
}
/// add adds the event to the bloc and awaits the first [State] emitted.
Future<void> add(Event event) async {
_eventController.add(event);
await _stateController.stream.first;
}
void dispose() {
_eventController.close();
_stateController.close();
}
Stream<State> mapEventToState(Event event);
}
enum CounterEvent { increment, decrement }
class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc(int initialState) : super(initialState);
@override
Stream<int> mapEventToState(CounterEvent event) {
switch (event) {
case CounterEvent.increment:
return Stream.value(state + 1);
case CounterEvent.decrement:
return Stream.value(state - 1);
}
throw StateError('Event $event not recognized.');
}
}
Future<void> main() async {
CounterBloc bloc = CounterBloc(0);
print(bloc.state); // Expect: 0
bloc.states.listen(print);
await bloc.add(CounterEvent.increment); // 1
await bloc.add(CounterEvent.increment); // 2
await bloc.add(CounterEvent.decrement); // 1
await bloc.add(CounterEvent.decrement); // 0
await bloc.add(CounterEvent.decrement); // -1
bloc.dispose();
// Expected output:
// 0
// 1
// 2
// 1
// 0
// -1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment