diff --git a/DailyDesktop.Core/DailyDesktopCore.cs b/DailyDesktop.Core/DailyDesktopCore.cs
index 73cacf8..d7c00f5 100644
--- a/DailyDesktop.Core/DailyDesktopCore.cs
+++ b/DailyDesktop.Core/DailyDesktopCore.cs
@@ -19,12 +19,12 @@ namespace DailyDesktop.Core
/// module scanning, though is fully functional as
/// a standalone class.
///
- public class DailyDesktopCore : IDisposable
+ public sealed class DailyDesktopCore : IDisposable
{
private Microsoft.Win32.TaskScheduler.Task? task;
private string taskName;
- private readonly ProviderStore store = new ProviderStore();
+ private readonly ProviderStore store = new();
///
/// Read-only interface to the path configuration.
@@ -62,8 +62,12 @@ public string TaskName
///
/// The currently selected provider corresponding to .
///
- public IProvider? CurrentProvider => currentProvider;
- private IProvider? currentProvider;
+ public IProvider? CurrentProvider => Providers.ContainsKey(taskConfig.Dll) ? IProvider.Instantiate(Providers[taskConfig.Dll]) : null;
+
+ ///
+ /// The collection of currently loaded s.
+ ///
+ public IReadOnlyDictionary Providers => store.Providers;
///
/// The state of the desktop wallpaper update task.
@@ -79,35 +83,24 @@ public string TaskName
/// The .
public static async Task CreateCoreAsync(PathConfiguration pathConfig, string taskName, bool isAutoCreatingTask, CancellationToken cancellationToken)
{
- var core = new DailyDesktopCore(pathConfig, taskName);
-
- core.IsAutoCreatingTask = isAutoCreatingTask;
+ var core = new DailyDesktopCore(pathConfig, taskName)
+ {
+ IsAutoCreatingTask = isAutoCreatingTask
+ };
core.taskConfig.OnUpdateAsync += core.onTaskConfigUpdateAsync;
if (!await core.taskConfig.TryDeserializeAsync(cancellationToken))
await core.taskConfig.UpdateAsync(cancellationToken);
- var providers = await core.GetProvidersAsync(cancellationToken);
- if (providers.ContainsKey(core.taskConfig.Dll))
- core.currentProvider = IProvider.Instantiate(providers[core.taskConfig.Dll]);
-
- if (core.IsAutoCreatingTask)
- core.CreateTask();
-
return core;
}
///
- /// Get an asynchronously scanned dictionary of values and DLL module path keys.
+ /// Scans for s and populates .
///
/// The .
- /// The dictionary of DLL path s to s.
- public async Task> GetProvidersAsync(CancellationToken cancellationToken)
- {
- await store.ScanAsync(pathConfig.ProvidersDir, cancellationToken);
- return store.Providers;
- }
+ public async Task ScanProvidersAsync(CancellationToken cancellationToken) => await store.ScanAsync(pathConfig.ProvidersDir, cancellationToken);
///
/// Creates a under the name . If
@@ -190,11 +183,8 @@ private DailyDesktopCore(PathConfiguration pathConfig, string taskName)
private async Task onTaskConfigUpdateAsync(object? sender, EventArgs? args, CancellationToken cancellationToken)
{
- var providers = await GetProvidersAsync(cancellationToken);
- currentProvider = providers.ContainsKey(taskConfig.Dll) ? IProvider.Instantiate(providers[taskConfig.Dll]) : null;
-
if (IsAutoCreatingTask)
- CreateTask();
+ await Task.Run(CreateTask, cancellationToken);
}
///
diff --git a/DailyDesktop.Core/Providers/ProviderStore.cs b/DailyDesktop.Core/Providers/ProviderStore.cs
index 1a94db5..0c165c0 100644
--- a/DailyDesktop.Core/Providers/ProviderStore.cs
+++ b/DailyDesktop.Core/Providers/ProviderStore.cs
@@ -89,7 +89,7 @@ private Type addImpl(string dllPath, Assembly assembly)
public void Scan(string directory)
{
if (!Directory.Exists(directory))
- return;
+ throw new DirectoryNotFoundException($"{directory} does not exist");
foreach (var path in Directory.GetFiles(directory, PROVIDERS_SEARCH_PATTERN, SearchOption.AllDirectories))
{
@@ -113,10 +113,13 @@ public void Scan(string directory)
public async Task ScanAsync(string directory, CancellationToken cancellationToken)
{
if (!Directory.Exists(directory))
- return;
+ throw new DirectoryNotFoundException($"{directory} does not exist");
foreach (var path in Directory.GetFiles(directory, PROVIDERS_SEARCH_PATTERN, SearchOption.AllDirectories))
{
+ if (cancellationToken.IsCancellationRequested)
+ throw new OperationCanceledException();
+
try
{
await AddAsync(path, cancellationToken);
diff --git a/DailyDesktop.Desktop/MainForm.cs b/DailyDesktop.Desktop/MainForm.cs
index d2ddad7..8d3f0c3 100644
--- a/DailyDesktop.Desktop/MainForm.cs
+++ b/DailyDesktop.Desktop/MainForm.cs
@@ -36,6 +36,8 @@ public partial class MainForm : Form
private const string null_text = "null";
private const string fetched_text = "fetched on";
+ private const string failed_scan_text = "Could not load all providers. (took too long?)";
+
private readonly DailyDesktopCore core;
private readonly WallpaperConfiguration wallpaperConfig;
@@ -64,7 +66,7 @@ public static async Task CreateFormAsync()
AssemblyDir = assemblyDir,
ProvidersDir = providersDir,
SerializationDir = serializationDir,
- }, taskName, true, AsyncUtils.TimedCancel(2500)));
+ }, taskName, true, AsyncUtils.TimedCancel()));
}
private MainForm(DailyDesktopCore core)
@@ -129,40 +131,56 @@ private void MainForm_FormClosing(object? sender, EventArgs e)
private async void providerComboBox_SelectedIndexChanged(object? sender, EventArgs e)
{
- if (providerComboBox.SelectedItem is ProviderWrapper provider)
- await taskConfig.SetDllAsync(provider.Dll, AsyncUtils.TimedCancel());
+ if (providerComboBox.SelectedItem is not ProviderWrapper p)
+ return;
+
+ await taskConfig.SetDllAsync(p.Dll, AsyncUtils.TimedCancel());
- providerDescriptionLabel.Text = core.CurrentProvider?.Description ?? null_description;
- providerSourceLinkLabel.Text = core.CurrentProvider?.SourceUri ?? null_text;
- providerSourceLinkLabel.Links[0].Enabled = Uri.TryCreate(providerSourceLinkLabel.Text, UriKind.Absolute, out _);
- providerSourceLinkLabel.TabStop = wallpaperAuthorLinkLabel.Links[0].Enabled;
+ Invoke(() =>
+ {
+ var provider = core.CurrentProvider;
+ providerDescriptionLabel.Text = provider?.Description ?? null_description;
+ providerSourceLinkLabel.Text = provider?.SourceUri ?? null_text;
+ providerSourceLinkLabel.Links[0].Enabled = Uri.TryCreate(providerSourceLinkLabel.Text, UriKind.Absolute, out _);
+ providerSourceLinkLabel.TabStop = wallpaperAuthorLinkLabel.Links[0].Enabled;
+ });
}
private async Task repopulateProviderComboBox()
{
- var providers = await core.GetProvidersAsync(AsyncUtils.TimedCancel());
+ bool isFullyLoaded = true;
- providerComboBox.Items.Clear();
- providerComboBox.Items.Add(ProviderWrapper.Null);
+ try
+ {
+ await core.ScanProvidersAsync(AsyncUtils.TimedCancel(3000));
+ }
+ catch (OperationCanceledException)
+ {
+ isFullyLoaded = false;
+ }
- foreach (var keyVal in providers)
+ Invoke(() =>
{
- try
- {
- var provider = IProvider.Instantiate(keyVal.Value);
- var item = new ProviderWrapper(keyVal.Key, provider);
- providerComboBox.Items.Add(item);
- }
- catch (ProviderException pe)
+ providerComboBox.Items.Clear();
+ providerComboBox.Items.Add(isFullyLoaded ? ProviderWrapper.Null : failed_scan_text);
+
+ foreach (var keyVal in core.Providers)
{
- Console.WriteLine(pe.StackTrace);
+ try
+ {
+ var provider = IProvider.Instantiate(keyVal.Value);
+ var item = new ProviderWrapper(keyVal.Key, provider);
+ providerComboBox.Items.Add(item);
+ }
+ catch (ProviderException pe)
+ {
+ Console.WriteLine(pe.StackTrace);
+ }
}
- }
-
- int index = providerComboBox.FindString(core.CurrentProvider?.DisplayName ?? "");
- if (index >= 0)
- providerComboBox.SelectedIndex = index;
+ if (core.CurrentProvider != null)
+ providerComboBox.SelectedIndex = providerComboBox.FindString(core.CurrentProvider.DisplayName);
+ });
}
private async void providerComboBox_DropDown(object? sender, EventArgs e) => await repopulateProviderComboBox();