public DownloadManager(IPinballXManager pinballXManager, IJobManager jobManager, IVpdbManager vpdbManager, ISettingsManager settingsManager, IMessageManager messageManager, IDatabaseManager databaseManager, ILogger logger, CrashManager crashManager) { _pinballXManager = pinballXManager; _jobManager = jobManager; _vpdbManager = vpdbManager; _settingsManager = settingsManager; _messageManager = messageManager; _databaseManager = databaseManager; _logger = logger; _crashManager = crashManager; // setup download callbacks jobManager.WhenDownloaded.Subscribe(OnDownloadCompleted); // setup flavor matchers as soon as settings are available. _settingsManager.Settings.WhenAny( s => s.DownloadOrientation, s => s.DownloadOrientationFallback, s => s.DownloadLighting, s => s.DownloadLightingFallback, (a, b, c, d) => Unit.Default).Subscribe(_ => { _logger.Info("Setting up flavor matchers."); _flavorMatchers.Clear(); _flavorMatchers.Add(new OrientationMatcher(_settingsManager.Settings)); _flavorMatchers.Add(new LightingMatcher(_settingsManager.Settings)); }); }
public GameManager(IPinballXManager pinballXManager, IVpdbClient vpdbClient, IVpdbManager vpdbManager, ISettingsManager settingsManager, IDownloadManager downloadManager, IDatabaseManager databaseManager, IVersionManager versionManager, IMessageManager messageManager, IRealtimeManager realtimeManager, IVisualPinballManager visualPinballManager, IThreadManager threadManager, IJobManager jobManager, IFile file, ILogger logger) { _pinballXManager = pinballXManager; _vpdbClient = vpdbClient; _vpdbManager = vpdbManager; _settingsManager = settingsManager; _downloadManager = downloadManager; _databaseManager = databaseManager; _versionManager = versionManager; _messageManager = messageManager; _realtimeManager = realtimeManager; _visualPinballManager = visualPinballManager; _threadManager = threadManager; _file = file; _logger = logger; _jobManager = jobManager; // update releases from VPDB on the first run, but delay it a bit so it // doesn't do all that shit at the same time! _settingsManager.ApiAuthenticated .Where(user => user != null) .Take(1) .Delay(TimeSpan.FromSeconds(2)) .Subscribe(_ => UpdateReleaseData()); // subscribe to downloaded releases _downloadManager.WhenReleaseDownloaded.Subscribe(OnReleaseDownloaded); // link games if new games are added //Games.Changed.Subscribe(_ => CheckGameLinks()); // when game is linked or unlinked, update profile with channel info /*IDisposable gameLinked = null; * Games.Changed.Subscribe(_ => { * gameLinked?.Dispose(); * gameLinked = Games * .Select(g => g.Changed.Where(x => x.PropertyName == "ReleaseId")) * .Merge() * .Subscribe(__ => UpdateChannelConfig()); * });*/ // setup pusher messages SetupRealtime(); }
public GameItemViewModel(AggregatedGame game, IDependencyResolver resolver) { Game = game; _logger = resolver.GetService <ILogger>(); _vpdbClient = resolver.GetService <IVpdbClient>(); _gameManager = resolver.GetService <IGameManager>(); _pinballXManager = resolver.GetService <IPinballXManager>(); _messageManager = resolver.GetService <IMessageManager>(); var threadManager = resolver.GetService <IThreadManager>(); game.WhenAnyValue(g => g.IsDownloading).ToProperty(this, vm => vm.IsDownloading, out _isDownloading); game.WhenAnyValue(g => g.IsQueued).ToProperty(this, vm => vm.IsQueued, out _isQueued); // release identify IdentifyRelease = ReactiveCommand.CreateFromObservable(() => _vpdbClient.Api.GetReleasesBySize(Game.FileSize, MatchThreshold).SubscribeOn(threadManager.WorkerScheduler)); IdentifyRelease.Select(releases => releases .Select(release => new { release, release.Versions }) .SelectMany(x => x.Versions.Select(version => new { x.release, version, version.Files })) .SelectMany(x => x.Files.Select(file => new GameResultItemViewModel(game, x.release, x.version, file, CloseResults))) ).Subscribe(x => { var releases = x as GameResultItemViewModel[] ?? x.ToArray(); var numMatches = 0; _logger.Info("Found {0} releases for game to identify.", releases.Length); GameResultItemViewModel match = null; foreach (var vm in releases) { if (game.FileName == vm.TableFile.Reference.Name && game.FileSize == vm.TableFile.Reference.Bytes) { numMatches++; match = vm; } } _logger.Info("Found {0} identical match(es).", numMatches); // if file name and file size are identical, directly match. if (numMatches == 1 && match != null) { _logger.Info("File name and size are equal to local release, linking."); _gameManager.MapGame(match.Game, match.Release, match.TableFile.Reference.Id); //_messageManager.LogReleaseLinked(match.Game, match.Release, match.TableFile.Reference.Id); } else { _logger.Info("View model updated with identified releases."); IdentifiedReleases = releases; ShowResults = true; } }, exception => _vpdbClient.HandleApiError(exception, "identifying a game by file size")); //var canSync = this.WhenAnyValue(x => x.Game.IsSynced, x => x.Game.HasRelease, (isSynced, hasRelease) => isSynced && hasRelease); //var canSync = this.WhenAnyValue(x => x.Game.Mapping.IsSynced, x => x.Game.MappedRelease, (isSynced, rls) => isSynced && rls != null); //SyncToggled = ReactiveCommand.Create(() => { _gameManager.Sync(Game); }, canSync); // handle errors IdentifyRelease.ThrownExceptions.Subscribe(e => { _logger.Error(e, "Error matching game."); }); // result switch IdentifyRelease.Select(r => r.Count > 0).Subscribe(hasResults => { HasResults = hasResults; }); // add to db button AddGame = ReactiveCommand.Create(() => _gameManager.AddGame(Game)); // remove from db button RemoveGame = ReactiveCommand.Create(() => _pinballXManager.RemoveGame(Game.XmlGame)); // close button CloseResults = ReactiveCommand.Create(() => { ShowResults = false; }); // hide button HideGame = ReactiveCommand.Create(() => _gameManager.HideGame(Game)); // unhide button UnHideGame = ReactiveCommand.Create(() => _gameManager.UnHideGame(Game)); // download button DownloadMissing = ReactiveCommand.Create(() => _gameManager.DownloadGame(Game)); // spinner IdentifyRelease.IsExecuting.ToProperty(this, vm => vm.IsExecuting, out _isExecuting); // global buttons hide this.WhenAnyValue( vm => vm.ShowResults, vm => vm.IsExecuting, vm => vm.IsDownloading, vm => vm.IsQueued, (showResults, isExecuting, isDownloading, isQueued) => !showResults && !isExecuting && !isDownloading && !isQueued ).ToProperty(this, vm => vm.ShowButtons, out _showButtons); // identify button visibility this.WhenAny( vm => vm.Game.HasLocalFile, vm => vm.Game.MappedTableFile, vm => vm.ShowButtons, (hasLocalFile, mappedFile, showButtons) => hasLocalFile.Value && mappedFile.Value == null && showButtons.Value ).ToProperty(this, vm => vm.ShowIdentifyButton, out _showIdentifyButton); // hide button visibility this.WhenAny( vm => vm.Game.Mapping, vm => vm.Game.HasLocalFile, vm => vm.Game.HasMappedRelease, vm => vm.Game.HasXmlGame, vm => vm.ShowButtons, (mapping, hasLocalFile, hasMappedRelease, hasXmlGame, showButtons) => (mapping.Value == null || !mapping.Value.IsHidden) && hasLocalFile.Value && !hasMappedRelease.Value && !hasXmlGame.Value && showButtons.Value ).ToProperty(this, vm => vm.ShowHideButton, out _showHideButton); // unhide button visibility this.WhenAny( vm => vm.Game.Mapping, vm => vm.ShowButtons, (mapping, showButtons) => mapping.Value != null && mapping.Value.IsHidden && showButtons.Value ).ToProperty(this, vm => vm.ShowUnHideButton, out _showUnHideButton); // add to db button visibility this.WhenAny( vm => vm.Game.HasLocalFile, vm => vm.Game.HasXmlGame, vm => vm.Game.MappedTableFile, vm => vm.ShowButtons, (hasLocalFile, hasXmlGame, mappedFile, showButtons) => hasLocalFile.Value && !hasXmlGame.Value && mappedFile.Value != null && showButtons.Value ).ToProperty(this, vm => vm.ShowAddToDbButton, out _showAddToDbButton); // remove from db button visibility this.WhenAny( vm => vm.Game.HasLocalFile, vm => vm.Game.HasXmlGame, vm => vm.ShowButtons, (hasLocalFile, hasXmlGame, showButtons) => !hasLocalFile.Value && hasXmlGame.Value && showButtons.Value ).ToProperty(this, vm => vm.ShowRemoveFromDbButton, out _showRemoveFromDbButton); // download button visibility this.WhenAny( vm => vm.Game.HasLocalFile, vm => vm.Game.MappedTableFile, vm => vm.ShowButtons, (hasLocalFile, mappedFile, showButtons) => !hasLocalFile.Value && mappedFile.Value != null && showButtons.Value ).ToProperty(this, vm => vm.ShowDownloadMissingButton, out _showDownloadMissingButton); // download progress this.WhenAnyValue(vm => vm.IsDownloading).Subscribe(isDownloading => { if (isDownloading) { Game.MappedJob.WhenAnyValue(j => j.TransferPercent) .Sample(TimeSpan.FromMilliseconds(300)) .Where(x => !Game.MappedJob.IsFinished) .Subscribe(progress => { // on main thread System.Windows.Application.Current.Dispatcher.Invoke(() => { DownloadPercent = progress; }); }); } }); }