private async Task <AlternativeRoutesComposition> UpdateRoutesComposition(DrivingRouteObject drivingRouteObject, bool moveCamera) { _logger.Method().Start($"Route id = {drivingRouteObject.Route.RouteId}, move camera = {moveCamera}"); _updateRoutesCompositionCts?.Cancel(); _updateRoutesCompositionCts = new CancellationTokenSource(); Route route = drivingRouteObject.Route; IReadOnlyList <DrivingRouteObject> routes = await _internalRouteService.Value.GetAlternativeRouteObjects(route, _dringGuide.Value.RoutePosition ?? new PolylinePosition(0, 0), _updateRoutesCompositionCts.Token); var composition = new AlternativeRoutesComposition(_drivingRouteObjectFactory.Value.Create(drivingRouteObject.Route), routes, _localizationService.Value); _renderDisposable?.Dispose(); _renderDisposable = await _alternativeRoutesRenderer.Value.Render(composition, _updateRoutesCompositionCts.Token); _subscriptions?.Dispose(); _subscriptions = OverviewShownStream.Where(show => !show).ToUnitObservable().Subscribe(_ => HideAlternativeRoutes()); if (moveCamera) { await MoveCameraToOverview(composition, _updateRoutesCompositionCts.Token); } return(composition); }
public RoutesOverviewPresenter(Lazy <AlternativeRoutesRenderer> alternativeRoutesRenderer, Lazy <IInternalRouteService> internalRouteService, Lazy <ILocalizationService> localizationService, Lazy <IMapCameraPositionPresenter> cameraPresenter, Lazy <IDrivingGuide> dringGuide, Lazy <ICameraManager> cameraManager, Lazy <IDrivingRouteObjectFactory> drivingRouteObjectFactory, ILogManager logManager, IObservable <DrivingRouteObject> routesStream) { _logger = logManager.GetLogger(Scopes.RoutesOverview, LogManagerFactory.DefaultConfiguration); _alternativeRoutesRenderer = alternativeRoutesRenderer; _internalRouteService = internalRouteService; _localizationService = localizationService; _cameraPresenter = cameraPresenter; _dringGuide = dringGuide; _cameraManager = cameraManager; _drivingRouteObjectFactory = drivingRouteObjectFactory; IObservable <(DrivingRouteObject CurRoute, DrivingRouteObject PrevRoute)> routesChangeStream = routesStream.Skip(1).Zip(routesStream, (cur, prev) => (cur, prev)).Publish().RefCount(); IObservable <DrivingRouteObject> viaPointsChangedStream = routesChangeStream.Where(it => it.CurRoute.ViaPoints.Count != it.PrevRoute.ViaPoints.Count) .Select(it => it.CurRoute) .Do(it => _logger.Info($"Via point added or removed, show routes overview, route id={it.Route.RouteId}")); IObservable <DrivingRouteObject> viaPointsNotChangedStream = routesChangeStream.Where(it => it.CurRoute.ViaPoints.Count == it.PrevRoute.ViaPoints.Count) .Select(it => it.CurRoute) .Do(it => _logger.Info($"Via points are not changed, update routes overview, route id={it.Route.RouteId}")); IObservable <DrivingRouteObject> showOverviewIfHidden = _showOverviewRequestSubject.WithLatestFrom(routesStream, (_, route) => route) .Do(it => _logger.Info($"Overview button tapped, show routes overview, route id={it.Route.RouteId}")) .Merge(viaPointsChangedStream) .Publish() .RefCount(); OverviewShownStream = showOverviewIfHidden.Select(_ => true).Merge(_hideOverviewRequestSubject.Select(_ => false)).DistinctUntilChanged().Publish().RefCount(); IObservable <DrivingRouteObject> updateOverviewIfShown = viaPointsNotChangedStream .Where(route => _currentComposition != null && _currentComposition.Routes.All(r => r.Route.RouteId != route.Route.RouteId)) .Do(it => _logger.Info($"Route updated when overview shown, update routes overview, route id={it.Route.RouteId}")); IObservable <Unit> hideOverfiewIfShown = OverviewShownStream.Where(show => !show).ToUnitObservable().Do(_ => _logger.Info("Hide overview request")); IObservable <AlternativeRoutesComposition> compostitionsStream = updateOverviewIfShown.Merge(showOverviewIfHidden) .Select(r => Observable.Interval(TimeSpan.FromMinutes(1)) .ObserveOnDispatcher() .Select(_ => (Route: r, MoveCamera: false)) .Do(it => _logger.Info($"Update overview by timer, route id={it.Route.Route.RouteId}")) .StartWith((Route: r, MoveCamera: true))) .Merge(hideOverfiewIfShown.Select(_ => Observable.Empty <(DrivingRouteObject Route, bool MoveCamera)>())) .Switch() .Select(t => UpdateRoutesComposition(t.Route, t.MoveCamera) .ToObservable() .Catch <AlternativeRoutesComposition, OperationCanceledException>(_ => Observable.Empty <AlternativeRoutesComposition>()) .Catch <AlternativeRoutesComposition, Exception>(ex => { ExceptionHandler.FailInDebugTrackInRelease(ex); return(Observable.Empty <AlternativeRoutesComposition>()); })) .Switch() .Do(compostion => _currentComposition = compostion); SelectedRouteStream = compostitionsStream.Select(c => c.AlternativeRouteSelected).Switch().Publish().RefCount(); _subscriptions = OverviewShownStream.Where(show => !show).ToUnitObservable().Subscribe(_ => HideAlternativeRoutes()); }