import 'dart:async'; import 'package:location/location.dart'; import 'package:gps/models/gps_point.dart'; import 'package:gps/utils/gps_persister.dart'; import 'bloc_provider.dart'; // An action which is triggert by the UI enum GpsBlocAction { toggleRecording, save } // A state change triggert by the Business Logic enum GpsBlocState { recording, notRecording } class GpsBloc implements BlocBase { final GpsPersister _persister; bool _recording = false; GpsPoint _currentLocation = GpsPoint(); List _recordedLocations = []; final StreamController _gpsOutController = StreamController.broadcast(); Stream get gpsPoint => _gpsOutController.stream; final StreamController _gpsInController = StreamController.broadcast(); StreamSink get gpsIn => _gpsInController.sink; final StreamController _stateOutController = StreamController.broadcast(); Stream get stateOut => _stateOutController.stream; final StreamController _actionInController = StreamController.broadcast(); StreamSink get actionIn => _actionInController.sink; GpsBloc(this._persister) { _gpsInController.stream.listen(_handleNewPosition); _actionInController.stream.listen(_handleActions); } void _handleNewPosition(LocationData event) { _currentLocation = GpsPoint( latitude: event.latitude ?? 0.0, longitude: event.longitude ?? 0.0, accuracy: event.accuracy ?? 0.0, speed: event.speed ?? 0.0, heading: event.heading ?? 0.0, time: event.time ?? 0.0, satelliteNumber: event.satelliteNumber ?? 0, provider: event.provider ?? "none"); if (_recording) { _recordedLocations.add(_currentLocation); } _gpsOutController.sink.add(_currentLocation); } void _handleActions(GpsBlocAction event) { switch (event) { case GpsBlocAction.toggleRecording: _recording = !_recording; _stateOutController.sink.add( _recording ? GpsBlocState.recording : GpsBlocState.notRecording); break; case GpsBlocAction.save: _persister.save(_recordedLocations); _recordedLocations = []; break; } } @override void dispose() { _gpsOutController.close(); _gpsInController.close(); _stateOutController.close(); _actionInController.close(); } }