// 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;
}
}