示例#1
0
        private void OnChange(object sender, RpEvent e)
        {
            if (e.ChangedFieldName.Equals(nameof(_config.State.TooltipText)))
            {
                // Tooltip text update triggered every second - not intrusive, no need to spam the event queue
                OnTooltipTextRPChange();
                return;
            }

            EventCounter++;

            Task.Run(() =>
            {
                string valueMessageComponent = e.Content.ToString() == e.Content.GetType().FullName
                    ? $"Object[{e.Content.ToString()}]"
                    : e.Content.ToString();

                _log.Information(LogHelper.GetMethodName(this), $"Event [{EventCounter}] - Received - Type: {{ChangedType}} - Changed field: {{ChannelChanged}} - Value: {{ValueMessageComponent}}", e.SentEventType, e.ChangedFieldName, valueMessageComponent);

                try
                {
                    _rpTrayIcon.BuildContextMenu();

                    switch (e.ChangedFieldName)
                    {
                    case nameof(_config.ExternalConfig.ShowOnNewSong):
                        OnShowOnNewSongChange();
                        break;

                    case nameof(_config.ExternalConfig.EnableFoobar2000Watcher):
                        OnEnableFooBar2000WatcherChange();
                        break;

                    case nameof(_config.ExternalConfig.EnableMusicBeeWatcher):
                        OnEnableMusicBeeWatcherChange();
                        break;

                    case nameof(_config.ExternalConfig.LargeAlbumArt):
                        OnLargeAlbumArtChange();
                        break;

                    case nameof(_config.ExternalConfig.ShowSongRating):
                        OnShowSongRatingChange();
                        break;

                    case nameof(_config.ExternalConfig.PromptForRating):
                        OnPromptForRatingChange();
                        break;

                    case nameof(_config.ExternalConfig.Channel):
                        OnChannelChange();
                        break;

                    case nameof(_config.ExternalConfig.DeleteAllData):
                        OnDeleteAllDataChange();
                        break;

                    case nameof(_config.State.Foobar2000IsPlayingRP):
                        OnFoobar2000IsPlayingRPChange();
                        break;

                    case nameof(_config.State.MusicBeeIsPlayingRP):
                        OnMusicBeeIsPlayingRPChange();
                        break;

                    case nameof(_config.State.IsUserAuthenticated):
                        OnIsUserAuthenticatedChange();
                        break;

                    case nameof(_config.State.Playback):
                        OnPlaybackChange();
                        break;

                    case nameof(_config.State.RpTrackingConfig.ActivePlayerId):
                        OnActivePlayerIdChange();
                        break;

                    case nameof(_config.ExternalConfig.EnableRpOfficialTracking):
                        OnEnableRpOfficialTrackingChange();
                        break;

                    case nameof(_config.State.RpTrackingConfig.Players):
                        OnPlayersChange();
                        break;

                    default:
                        _log.Information(LogHelper.GetMethodName(this), $"Event [{EventCounter}] - Exit without action - Type: {{ChangedType}} - Changed field: {{ChannelChanged}} - Value: {{ValueMessageComponent}}", e.SentEventType, e.ChangedFieldName, valueMessageComponent);
                        break;
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(LogHelper.GetMethodName(this), ex);
                    _toastHandler.ErrorToast(ex);
                    Task.Delay(10000).Wait();
                    Application.Exit();
                }

                _log.Information(LogHelper.GetMethodName(this), $"Event [{EventCounter}] - Finished - Type: {{ChangedType}} - Changed field: {{ChannelChanged}} - Value: {{ValueMessageComponent}}", e.SentEventType, e.ChangedFieldName, valueMessageComponent);
            }).Wait();
        }
        private void Run()
        {
            _log.Information(LogHelper.GetMethodName(this), "Invoked");

            SongInfoListenerTask = Task.Run(async() =>
            {
                while (!listenerCancellationTokenSource.Token.IsCancellationRequested)     // keep getting new song info
                {
                    _log.Information(LogHelper.GetMethodName(this), "Start loop *****************");

                    try
                    {
                        NextSongWaiterCancellationTokenSource = new CancellationTokenSource();
                        var cancellationToken = NextSongWaiterCancellationTokenSource.Token;

                        try
                        {
                            Task update = Task.Run(() =>
                            {
                                CheckTrackedRpPlayerStatus();
                                UpdateSongInfo();
                            }, cancellationToken);

                            // if an RP player is tracked then wait this only at the end of the
                            // listener loop in order to don't potentially skip the rating prompt
                            // while checking song data
                            // in other cases it would cause unnecessary double API calls
                            if (_config.State.Playback == null ||
                                !_config.IsRpPlayerTrackingChannel())
                            {
                                update.Wait();
                            }

                            var timeLeftFromSongMilliseconds = (int)(_config.State.Playback.SongInfoExpiration - DateTime.Now).TotalMilliseconds;

                            // check more often when RP player is tracked
                            var loopWaitMilliseconds = _config.IsRpPlayerTrackingChannel()
                                ? Math.Min(10000, timeLeftFromSongMilliseconds)
                                : timeLeftFromSongMilliseconds;

                            // when Bill is talking
                            loopWaitMilliseconds = loopWaitMilliseconds > 0
                                ? loopWaitMilliseconds
                                : 5000;

                            var waitForNextSong = Task.Delay(loopWaitMilliseconds, cancellationToken);

                            while (!waitForNextSong.IsCompleted && !cancellationToken.IsCancellationRequested)
                            {
                                var RefreshDelay = Task.Delay(1000, cancellationToken);
                                SendUpdateTooltipEvent();
                                PromptRatingAtTheEndOfSongOrIfCanceled();
                                await RefreshDelay;
                            }
                            await update;
                        }
                        catch (TaskCanceledException)
                        {
                            PromptRatingAtTheEndOfSongOrIfCanceled();
                            _log.Information(LogHelper.GetMethodName(this), "Restart loop");
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Error(LogHelper.GetMethodName(this), ex);
                        _toastHandler.ErrorToast(ex);
                        Task.Delay(10000).Wait();
                        Application.Exit();
                    }
                }
            }, listenerCancellationTokenSource.Token);

            _log.Information(LogHelper.GetMethodName(this), "Running in background");
        }