// Copyright (c) Arlo Godfrey. All Rights Reserved. // Licensed under the GNU Lesser General Public License, Version 3.0 with additional terms. // See the LICENSE, LICENSE.LESSER and LICENSE.ADDITIONAL files in the project root for more information. using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using OwlCore.AbstractUI.Models; using OwlCore.AbstractUI.ViewModels; using OwlCore.Events; using StrixMusic.Sdk.AppModels; using StrixMusic.Sdk.CoreModels; using StrixMusic.Sdk.MediaPlayback; namespace StrixMusic.Sdk.ViewModels { /// /// A ViewModel for . /// public sealed class CoreViewModel : ObservableObject, ISdkViewModel, ICore { private readonly ICore _core; private readonly SynchronizationContext _syncContext; /// /// Initializes a new instance of the class. /// /// The to wrap around. public CoreViewModel(ICore core) : this(core, core.Registration) { } /// /// Initializes a new instance of the class. /// /// The to wrap around. /// The metadata that was used to construct this core instance. public CoreViewModel(ICore core, CoreMetadata coreMetadata) { _syncContext = SynchronizationContext.Current; _core = core; DisplayName = coreMetadata.DisplayName; LogoUri = coreMetadata.LogoUri; CoreState = _core.CoreState; AbstractConfigPanel = new AbstractUICollectionViewModel(_core.AbstractConfigPanel); AttachEvents(); } private void AttachEvents() { _core.CoreStateChanged += Core_CoreStateChanged; _core.InstanceDescriptorChanged += Core_InstanceDescriptorChanged; _core.AbstractConfigPanelChanged += OnAbstractConfigPanelChanged; } private void OnAbstractConfigPanelChanged(object sender, EventArgs e) => _syncContext.Post(_ => { AbstractConfigPanel = new AbstractUICollectionViewModel(_core.AbstractConfigPanel); OnPropertyChanged(nameof(AbstractConfigPanel)); }, null); private void DetachEvents() { _core.CoreStateChanged -= Core_CoreStateChanged; _core.InstanceDescriptorChanged -= Core_InstanceDescriptorChanged; _core.AbstractConfigPanelChanged -= OnAbstractConfigPanelChanged; } private void Core_InstanceDescriptorChanged(object sender, string e) => _syncContext.Post(_ => { OnPropertyChanged(nameof(InstanceDescriptor)); InstanceDescriptorChanged?.Invoke(sender, e); }, null); /// private void Core_CoreStateChanged(object sender, CoreState e) { CoreState = e; _syncContext.Post(_ => { OnPropertyChanged(nameof(CoreState)); OnPropertyChanged(nameof(IsCoreStateUnloaded)); OnPropertyChanged(nameof(IsCoreStateConfiguring)); OnPropertyChanged(nameof(IsCoreStateConfigured)); OnPropertyChanged(nameof(IsCoreStateLoading)); OnPropertyChanged(nameof(IsCoreStateLoaded)); }, null); } /// public string InstanceId => _core.InstanceId; /// public string InstanceDescriptor => _core.InstanceDescriptor; /// AbstractUICollection ICore.AbstractConfigPanel => _core.AbstractConfigPanel; /// public AbstractUICollectionViewModel AbstractConfigPanel { get; private set; } /// public MediaPlayerType PlaybackType => _core.PlaybackType; /// /// A local path or url pointing to a SVG file containing the logo for this core. /// public Uri LogoUri { get; } /// /// The user-friendly name of the core. /// public string DisplayName { get; } /// public ICoreUser? User => _core.User; /// public CoreState CoreState { get; internal set; } /// public ICore SourceCore => _core.SourceCore; /// /// True when is . /// public bool IsCoreStateUnloaded => CoreState == CoreState.Unloaded; /// /// True when is . /// public bool IsCoreStateConfiguring => CoreState == CoreState.NeedsConfiguration; /// /// True when is . /// public bool IsCoreStateConfigured => CoreState == CoreState.Configured; /// /// True when is . /// public bool IsCoreStateLoading => CoreState == CoreState.Loading; /// /// True when is . /// public bool IsCoreStateLoaded => CoreState == CoreState.Loaded; /// public event EventHandler? CoreStateChanged { add => _core.CoreStateChanged += value; remove => _core.CoreStateChanged -= value; } /// public event CollectionChangedEventHandler? DevicesChanged; /// public event EventHandler? AbstractConfigPanelChanged; /// public event EventHandler? InstanceDescriptorChanged; /// IReadOnlyList ICore.Devices => _core.Devices; /// ICoreLibrary ICore.Library => _core.Library; /// ICoreSearch? ICore.Search { get; } /// ICoreRecentlyPlayed? ICore.RecentlyPlayed => _core.RecentlyPlayed; /// ICoreDiscoverables? ICore.Discoverables => _core.Discoverables; /// ICorePlayableCollectionGroup? ICore.Pins => _core.Pins; /// public CoreMetadata Registration => _core.Registration; /// public async ValueTask DisposeAsync() { DetachEvents(); await _core.DisposeAsync(); } /// public Task GetContextByIdAsync(string id, CancellationToken cancellationToken = default) => _core.GetContextByIdAsync(id, cancellationToken); /// public Task GetMediaSourceAsync(ICoreTrack track, CancellationToken cancellationToken = default) => _core.GetMediaSourceAsync(track, cancellationToken); /// public Task InitAsync(CancellationToken cancellationToken = default) => _core.InitAsync(cancellationToken); /// public bool IsInitialized => _core.IsInitialized; } }