public MainWindowViewModel(DiscChanger discChanger, LibraryManager libraryManager) { DiscChanger = new DiscChangerViewModel(discChanger); TrackStatus = new TrackStatusViewModel(discChanger, libraryManager); CollectionExplorer = new CollectionExplorerViewModel(libraryManager, discChanger); VolumeControl = new VolumeControlViewModel(discChanger); }
internal void Update(DiscChanger discChanger, string name, string type, string connection, string commandMode, string portName, bool?HardwareFlowControl, string networkHost, int?networkPort) { lock (this.DiscChangers) { if (DiscChangers.Any(dc => dc != discChanger && dc.Name == name)) { throw new Exception($"Name {name} already exists"); } if (DiscChangers.Any(dc => dc != discChanger && dc.Connection == connection && dc.PortName == portName && dc.NetworkHost == networkHost && dc.NetworkPort == networkPort)) { throw new Exception($"Connection {connection}:{portName} {networkHost} already in use"); } discChanger.Name = name; discChanger.Type = type; if (discChanger.Connection != connection || discChanger.PortName != portName || discChanger.CommandMode != commandMode || discChanger.HardwareFlowControl != HardwareFlowControl || discChanger.NetworkHost != networkHost || discChanger.NetworkPort != networkPort) { discChanger.Disconnect(); //discChanger.Protocol = protocol; discChanger.Connection = connection; discChanger.CommandMode = commandMode; discChanger.PortName = portName; discChanger.HardwareFlowControl = HardwareFlowControl; discChanger.NetworkHost = networkHost; discChanger.NetworkPort = networkPort; discChanger.Connect(this, this._hubContext, _logger); } } }
public MainWindowViewModel(DiscChanger discChanger, LibraryManager libraryManager) { DiscChanger = new DiscChangerViewModel(discChanger); TrackStatus = new TrackStatusViewModel(discChanger, libraryManager); CollectionExplorer = new CollectionExplorerViewModel(libraryManager, discChanger); VolumeControl = new VolumeControlViewModel(discChanger); PanelItems = new List <PanelItem> { new PanelItem() { IconID = "Icon_Hamburger", Title = "Test Menu Item" }, new PanelItem() { IconID = "Icon_Hamburger", Title = "Test Menu Item" }, new PanelItem() { IconID = "Icon_Hamburger", Title = "Test Menu Item" }, new PanelItem() { IconID = "HambIcon_urger", Title = "Test Menu Item" }, }; }
public VolumeControlViewModel(DiscChanger discChanger) { this.discChanger = discChanger; discChanger.WhenAnyValue(x => x.CurrentTrack) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => { if (IsMuted) { discChanger.Volume = 0; } else { discChanger.Volume = Volume; } }); this.WhenAnyValue(x => x.Volume, x => x.IsMuted) .Where(x => !x.Item2) .Subscribe(x => discChanger.Volume = x.Item1); this.WhenAnyValue(x => x.IsMuted) .Where(x => x) .Subscribe(_ => discChanger.Volume = 0); }
public CollectionExplorerViewModel(LibraryManager model, DiscChanger changer) { SelectArtwork = new SelectArtworkViewModel(); model.Albums.ToObservableChangeSet() .Transform(album => new AlbumViewModel(album, changer)) .ObserveOn(RxApp.MainThreadScheduler) .Bind(out _albums) .OnItemAdded(x => { if (SelectedAlbum is null) { SelectedAlbum = x; } }) .DisposeMany() .Subscribe(); ScanLibraryCommand = ReactiveCommand.CreateFromTask(async() => { await Task.Run(async() => await model.ScanMusicFolder( Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic)))); }); RxApp.MainThreadScheduler.Schedule(async() => { await model.LoadLibrary(); }); }
public TrackStatusViewModel(DiscChanger discChanger, LibraryManager libraryManager) { this.WhenAnyValue(x => x.SeekPosition) .Skip(1) .Subscribe(x => { discChanger.Seek(TimeSpan.FromSeconds(SeekPosition * Duration.TotalSeconds)); }); this.WhenAnyValue(x => x.Status) .Throttle(TimeSpan.FromSeconds(2)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => { Status = ""; }); Model = discChanger; Observable.FromEventPattern(Model, nameof(Model.TrackChanged)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => LoadTrack(Model.CurrentTrack)); Observable.FromEventPattern(Model, nameof(Model.TrackPositionChanged)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => UpdateCurrentPlayTime(Model.CurrentTrackPosition)); Observable.FromEventPattern(Model, nameof(Model.SpectrumDataReady)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => InFFTData = Model.CurrentSpectrumData); Observable.FromEventPattern <string>(libraryManager, nameof(libraryManager.StatusChanged)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => Status = x.EventArgs); }
public VolumeControlViewModel(DiscChanger discChanger) { this.discChanger = discChanger; Observable.FromEventPattern(discChanger, nameof(discChanger.TrackChanged)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => { if (IsMuted) { discChanger.Volume = 0; } else { discChanger.Volume = Volume; } }); this.WhenAnyValue(x => x.Volume, x => x.IsMuted) .Where(x => !x.Item2) .Subscribe(x => discChanger.Volume = x.Item1); this.WhenAnyValue(x => x.IsMuted) .Where(x => x) .Subscribe(_ => discChanger.Volume = 0); }
public AlbumViewModel(Album album, DiscChanger changer) { Model = album; GetArtworkCommand = ReactiveCommand.CreateFromTask(async() => { await MainWindowViewModel.Instance.CollectionExplorer.SelectArtwork.QueryAlbumCoverAsync(this); }); LoadAlbumCommand = ReactiveCommand.CreateFromTask(async() => { await changer.LoadTrackList(album); }); Model.Tracks.ToObservableChangeSet() .Transform(x => new TrackViewModel(x)) .ObserveOn(RxApp.MainThreadScheduler) .Bind(out _tracks) .OnItemAdded(async x => { if (!_coverLoaded) { _coverLoaded = true; try { Cover = await LoadCoverAsync(); } catch (Exception e) { } } }) .Subscribe(); }
public async Task UpdateMetaData(Disc d, HashSet <string> metaDataTypes, bool changed = false) { DiscChanger dc = d.DiscChanger; System.Diagnostics.Debug.WriteLine($"About to Lookup {String.Join(',', metaDataTypes)} {dc?.Key} {d.Slot}"); if (metaDataMusicBrainz != null && metaDataTypes.Contains(MetaDataMusicBrainz.Type)) { try { MetaDataMusicBrainz.Data mbd = await metaDataMusicBrainz.RetrieveMetaData(d); if (mbd != null && d.DataMusicBrainz != mbd) { d.DataMusicBrainz = mbd; changed = true; } } catch (Exception e) { System.Diagnostics.Debug.WriteLine($"MusicBrainz Lookup failed {dc.Key} {d.Slot}: {e.Message}"); _logger.LogInformation(e, "MusicBrainz Lookup failed {Key} {Slot}", dc.Key, d.Slot); } } if (metaDataGD3 != null) { MetaDataGD3.Match gd3d = d.DataGD3Match; try { if (metaDataTypes.Contains(MetaDataGD3.Type_Match)) { gd3d = await metaDataGD3.RetrieveMatch(d); if (gd3d != null && d.DataGD3Match != gd3d) { d.DataGD3Match = gd3d; changed = true; } } if (gd3d != null && !gd3d.HasMetaData() && metaDataTypes.Contains(MetaDataGD3.Type_MetaData)) { if (await gd3d.RetrieveMetaData()) { changed = true; } } } catch (Exception e) { System.Diagnostics.Debug.WriteLine($"GD3 Match failed {dc.Key} {d.Slot}: {e.Message}"); _logger.LogInformation(e, "GD3 Match failed {Key} {Slot}", dc.Key, d.Slot); } } if (dc != null && changed) { await _hubContext.Clients.All.SendAsync("DiscData", dc.Key, d.Slot, d.ToHtml()); } }
public DiscChangerViewModel(DiscChanger discChanger) { _discChanger = discChanger; _isPaused = _discChanger.WhenAnyValue(x => x.IsPaused) .ToProperty(this, nameof(IsPaused)); PlayCommand = ReactiveCommand.CreateFromTask(async() => { await _discChanger.Play(); }); ForwardCommand = ReactiveCommand.CreateFromTask(async() => { await _discChanger.Forward(); }); BackCommand = ReactiveCommand.CreateFromTask(async() => { await _discChanger.Back(); }); }
internal void Move(string key, int offset) { lock (this.DiscChangers) { int i = this.DiscChangers.FindIndex(dc => dc.Key == key); if (i >= 0) { int j = i + offset; if (j >= 0 && j < DiscChangers.Count) { DiscChanger dc = DiscChangers[i]; DiscChangers[i] = DiscChangers[i + offset]; DiscChangers[i + offset] = dc; Save(); _hubContext.Clients.All.SendAsync("Reload"); } } } }
public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { var dc = new DiscChanger(); MainWindowViewModel.Instance = new MainWindowViewModel(dc, new LibraryManager()); desktop.MainWindow = new MainWindow { DataContext = MainWindowViewModel.Instance }; desktop.MainWindow.Closing += (sender, e) => { dc.Dispose(); }; } base.OnFrameworkInitializationCompleted(); }
internal void Add(string name, string type, string connection, string commandMode, string portName, bool?HardwareFlowControl, string networkHost, int?networkPort) { lock (this.DiscChangers) { string keyBase = new String(name.ToLower().Where(c => !char.IsWhiteSpace(c)).Take(6).ToArray()); int i = 0; string key = keyBase; while (key2DiscChanger.ContainsKey(key)) { i++; key = keyBase + i.ToString(); } DiscChanger dc = DiscChanger.Create(type); dc.Key = key; Update(dc, name, type, connection, commandMode, portName, HardwareFlowControl, networkHost, networkPort); DiscChangers.Add(dc); key2DiscChanger[key] = dc; Save(); _hubContext.Clients.All.SendAsync("Reload"); } }
public DiscChangerViewModel(DiscChanger discChanger) { _discChanger = discChanger; _isPlaying = _discChanger.WhenAnyValue(x => x.IsPlaying) .ToProperty(this, nameof(IsPlaying)); PlayCommand = ReactiveCommand.Create(() => { if (_discChanger.IsPlaying) { _discChanger.Pause(); } else { _discChanger.Play(); } }); ForwardCommand = ReactiveCommand.Create(_discChanger.Forward); BackCommand = ReactiveCommand.Create(_discChanger.Back); }
internal async Task <string> Test(string key, string type, string connection, string commandMode, string portName, bool?HardwareFlowControl, string networkHost, int?networkPort) { DiscChanger d = null; bool b = key != null && key2DiscChanger.TryGetValue(key, out d) && connection == d.Connection && portName == d.PortName && networkHost == d.NetworkHost && networkPort == d.NetworkPort; if (b) { d.Disconnect(); } DiscChanger dc = DiscChanger.Create(type); try { dc.Connection = connection; dc.CommandMode = commandMode; dc.PortName = portName; dc.HardwareFlowControl = HardwareFlowControl; dc.NetworkHost = networkHost; dc.NetworkPort = networkPort; await dc.Connect(null, null, _logger); return(await dc.Test()); } catch (Exception e) { return($"Disc changer testing of ({key},{type},{connection},{commandMode},{portName},{HardwareFlowControl},{networkHost}) returned error: {e.Message}"); } finally { dc.Disconnect(); if (b) { await d.Connect(); } } }
protected override async Task ExecuteAsync(CancellationToken cancellationToken) { _logger.LogInformation("Hosted Service running."); System.Diagnostics.Debug.WriteLine("Hosted Service running."); Load(); metaDataMusicBrainz = new MetaDataMusicBrainz(Path.Combine(discsPath, "MusicBrainz"), discsRelPath + "/MusicBrainz"); metaDataGD3 = new MetaDataGD3(_provider, contentRootPath, Path.Combine(discsPath, "GD3"), discsRelPath + "/GD3"); key2DiscChanger = new Dictionary <string, DiscChanger>(DiscChangers.Count); List <Task> connectTasks = new List <Task>(DiscChangers.Count); foreach (var discChanger in DiscChangers) { key2DiscChanger[discChanger.Key] = discChanger; foreach (var kvp in discChanger.Discs) { Disc d = kvp.Value; d.DataMusicBrainz = metaDataMusicBrainz.Get(d); d.DataGD3Match = metaDataGD3.Get(d); } try { connectTasks.Add(discChanger.Connect(this, _hubContext, _logger)); } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Exception connecting disc changer: " + discChanger.Key + ": " + e.Message); await _hubContext.Clients.All.SendAsync("StatusData", discChanger.Key, null, null, null, "off", null); } } Task.WaitAll(connectTasks.ToArray()); _logger.LogInformation("Hosted service starting"); TimeSpan discDataTimeOut = TimeSpan.FromSeconds(3); const int NullStatusQueryFrequency = 40;//only query null status every 40x3 seconds var metaDataSet = new HashSet <string> { MetaDataMusicBrainz.Type, MetaDataGD3.Type_Match }; var metaDataSetWithGD3Lookup = new HashSet <string> { MetaDataMusicBrainz.Type, MetaDataGD3.Type_Match, MetaDataGD3.Type_MetaData }; await Task.Factory.StartNew(async() => { int countDown = NullStatusQueryFrequency; // loop until a cancellation is requested while (!cancellationToken.IsCancellationRequested) { _logger.LogInformation("Hosted service executing - {0}", DateTime.Now); try { Disc d = await discDataMessages.ReceiveAsync(discDataTimeOut, cancellationToken); DiscChanger dc = d.DiscChanger; await UpdateMetaData(d, (metaDataGD3?.AutoLookupEnabled(d) ?? false) ? metaDataSetWithGD3Lookup : metaDataSet, true); d.DateTimeAdded ??= DateTime.Now; dc.Discs[d.Slot] = d; needsSaving = true; } catch (OperationCanceledException) { } catch (TimeoutException) { if (needsSaving) { Save(); } countDown--; foreach (var discChanger in DiscChangers) { var status = discChanger.CurrentStatus(); if ((status == null && countDown == 0) /*||(status!=null&&status.IsOutDated())*/) //feature to refresh outdated status prevents auto off on DVP-CX777ES { discChanger.ClearStatus(); if (discChanger.Connected()) { discChanger.InitiateStatusUpdate(); } } } if (countDown <= 0) { countDown = NullStatusQueryFrequency; } } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Hosted Service Exception: " + e.Message); _logger.LogInformation(e, "Hosted Service Exception"); } } }, cancellationToken); }