mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
Storage - Replace LiteDB with SQLite + EF Core (#843)
Storage - Added LiteDB to SQLite migration UI - Try to die a bit more gracefully Core - Delay start watching plugins for hot reload after initializing UI - Simplify category management logic UI - Avoid crash during profile icon load Storage - Fix entry metadata retrieval
This commit is contained in:
1 parent
9132301dbf
commit
551921db9f
130 files changed
+2965
-1135
No files matched your search
@@ -186,7 +186,7 @@ public partial class ProfileEditorViewModel : RoutableScreen<ProfileEditorViewMo
|
||||
/// <inheritdoc />
|
||||
public override async Task OnNavigating(ProfileEditorViewModelParameters parameters, NavigationArguments args, CancellationToken cancellationToken)
|
||||
{
|
||||
ProfileConfiguration? profileConfiguration = _profileService.ProfileConfigurations.FirstOrDefault(c => c.ProfileId == parameters.ProfileId);
|
||||
ProfileConfiguration? profileConfiguration = _profileService.ProfileCategories.SelectMany(c => c.ProfileConfigurations).FirstOrDefault(c => c.ProfileId == parameters.ProfileId);
|
||||
|
||||
// If the profile doesn't exist, cancel navigation
|
||||
if (profileConfiguration == null)
|
||||
|
||||
@@ -19,6 +19,7 @@ using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using Serilog;
|
||||
|
||||
namespace Artemis.UI.Screens.Root;
|
||||
|
||||
@@ -28,13 +29,15 @@ public class RootViewModel : RoutableHostScreen<RoutableScreen>, IMainWindowProv
|
||||
private readonly IDebugService _debugService;
|
||||
private readonly DefaultTitleBarViewModel _defaultTitleBarViewModel;
|
||||
private readonly IClassicDesktopStyleApplicationLifetime _lifeTime;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IRouter _router;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IUpdateService _updateService;
|
||||
private readonly IWindowService _windowService;
|
||||
private readonly ObservableAsPropertyHelper<ViewModelBase?> _titleBarViewModel;
|
||||
|
||||
public RootViewModel(IRouter router,
|
||||
public RootViewModel(ILogger logger,
|
||||
IRouter router,
|
||||
ICoreService coreService,
|
||||
ISettingsService settingsService,
|
||||
IRegistrationService registrationService,
|
||||
@@ -50,6 +53,7 @@ public class RootViewModel : RoutableHostScreen<RoutableScreen>, IMainWindowProv
|
||||
WindowSizeSetting = settingsService.GetSetting<WindowSize?>("WindowSize");
|
||||
SidebarViewModel = sidebarViewModel;
|
||||
|
||||
_logger = logger;
|
||||
_router = router;
|
||||
_coreService = coreService;
|
||||
_settingsService = settingsService;
|
||||
@@ -81,19 +85,27 @@ public class RootViewModel : RoutableHostScreen<RoutableScreen>, IMainWindowProv
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
// Before doing heavy lifting, initialize the update service which may prompt a restart
|
||||
// Only initialize with an update check if we're not going to show the UI
|
||||
if (_updateService.Initialize(!ShouldShowUI()))
|
||||
return;
|
||||
try
|
||||
{
|
||||
// Before doing heavy lifting, initialize the update service which may prompt a restart
|
||||
// Only initialize with an update check if we're not going to show the UI
|
||||
if (_updateService.Initialize(!ShouldShowUI()))
|
||||
return;
|
||||
|
||||
// Workshop service goes first so it has a chance to clean up old workshop entries and introduce new ones
|
||||
workshopService.Initialize();
|
||||
// Core is initialized now that everything is ready to go
|
||||
coreService.Initialize();
|
||||
// Workshop service goes first so it has a chance to clean up old workshop entries and introduce new ones
|
||||
workshopService.Initialize();
|
||||
// Core is initialized now that everything is ready to go
|
||||
coreService.Initialize();
|
||||
|
||||
registrationService.RegisterBuiltInDataModelDisplays();
|
||||
registrationService.RegisterBuiltInDataModelInputs();
|
||||
registrationService.RegisterBuiltInPropertyEditors();
|
||||
registrationService.RegisterBuiltInDataModelDisplays();
|
||||
registrationService.RegisterBuiltInDataModelInputs();
|
||||
registrationService.RegisterBuiltInPropertyEditors();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Fatal(e, "Error during initialization");
|
||||
_windowService.ShowExceptionDialog("Fatal error occured during initialization", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -174,16 +174,15 @@
|
||||
<StackPanel Grid.Row="0" Grid.Column="0">
|
||||
<TextBlock Classes="library-name">Avalonia</TextBlock>
|
||||
<TextBlock Classes="library-name">DryIoc</TextBlock>
|
||||
<TextBlock Classes="library-name">Entity Framework Core</TextBlock>
|
||||
<TextBlock Classes="library-name">FluentAvalonia</TextBlock>
|
||||
<TextBlock Classes="library-name">EmbedIO</TextBlock>
|
||||
<TextBlock Classes="library-name">Humanizer</TextBlock>
|
||||
<TextBlock Classes="library-name">LiteDB</TextBlock>
|
||||
<TextBlock Classes="library-name">McMaster.NETCore.Plugins</TextBlock>
|
||||
<TextBlock Classes="library-name">Newtonsoft.Json</TextBlock>
|
||||
<TextBlock Classes="library-name">RGB.NET</TextBlock>
|
||||
<TextBlock Classes="library-name">Serilog</TextBlock>
|
||||
<TextBlock Classes="library-name">SkiaSharp</TextBlock>
|
||||
<TextBlock Classes="library-name">Unclassified.NetRevisionTask</TextBlock>
|
||||
<TextBlock Classes="library-name">SQLite</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1">
|
||||
<controls:HyperlinkButton NavigateUri="https://avaloniaui.net/">
|
||||
@@ -192,6 +191,9 @@
|
||||
<controls:HyperlinkButton NavigateUri="https://github.com/dadhi/DryIoc">
|
||||
https://github.com/dadhi/DryIoc
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton NavigateUri="https://learn.microsoft.com/en-us/ef/core/">
|
||||
https://learn.microsoft.com/en-us/ef/core/
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton NavigateUri="https://github.com/amwx/FluentAvalonia">
|
||||
https://github.com/amwx/FluentAvalonia
|
||||
</controls:HyperlinkButton>
|
||||
@@ -201,15 +203,9 @@
|
||||
<controls:HyperlinkButton NavigateUri="https://github.com/Humanizr/Humanizer">
|
||||
https://github.com/Humanizr/Humanizer
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton NavigateUri="https://www.litedb.org/">
|
||||
https://www.litedb.org/
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton NavigateUri="https://github.com/natemcmaster/DotNetCorePlugins">
|
||||
https://github.com/natemcmaster/DotNetCorePlugins
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton NavigateUri="https://www.newtonsoft.com/json">
|
||||
https://www.newtonsoft.com/json
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton NavigateUri="https://github.com/DarthAffe/RGB.NET">
|
||||
https://github.com/DarthAffe/RGB.NET
|
||||
</controls:HyperlinkButton>
|
||||
@@ -218,9 +214,9 @@
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton NavigateUri="https://github.com/mono/SkiaSharp">
|
||||
https://github.com/mono/SkiaSharp
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton NavigateUri="https://unclassified.software/en/apps/netrevisiontask">
|
||||
https://unclassified.software/en/apps/netrevisiontask
|
||||
</controls:HyperlinkButton>
|
||||
<controls:HyperlinkButton NavigateUri="https://www.sqlite.org/">
|
||||
https://www.sqlite.org/
|
||||
</controls:HyperlinkButton>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -162,7 +162,7 @@ public class GeneralTabViewModel : RoutableScreen
|
||||
public PluginSetting<bool> ProfileEditorShowDataModelValues => _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
|
||||
public PluginSetting<LogEventLevel> CoreLoggingLevel => _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information);
|
||||
public PluginSetting<string> CorePreferredGraphicsContext => _settingsService.GetSetting("Core.PreferredGraphicsContext", "Software");
|
||||
public PluginSetting<double> CoreRenderScale => _settingsService.GetSetting("Core.RenderScale", 0.25);
|
||||
public PluginSetting<double> CoreRenderScale => _settingsService.GetSetting("Core.RenderScale", 0.5);
|
||||
public PluginSetting<int> CoreTargetFrameRate => _settingsService.GetSetting("Core.TargetFrameRate", 30);
|
||||
public PluginSetting<bool> WebServerEnabled => _settingsService.GetSetting("WebServer.Enabled", true);
|
||||
public PluginSetting<int> WebServerPort => _settingsService.GetSetting("WebServer.Port", 9696);
|
||||
|
||||
@@ -68,8 +68,8 @@ public class SidebarCategoryViewDropHandler : DropHandlerBase
|
||||
{
|
||||
int index = vm.ProfileConfigurations.IndexOf(targetItem);
|
||||
if (!before)
|
||||
index++;
|
||||
vm.AddProfileConfiguration(sourceItem.ProfileConfiguration, index);
|
||||
targetItem = index < vm.ProfileConfigurations.Count - 1 ? vm.ProfileConfigurations[index + 1] : null;
|
||||
vm.AddProfileConfiguration(sourceItem.ProfileConfiguration, targetItem?.ProfileConfiguration);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -122,8 +122,8 @@ public partial class ProfileConfigurationEditViewModel : DialogViewModelBase<Pro
|
||||
ProfileConfiguration.FadeInAndOut = FadeInAndOut;
|
||||
|
||||
await SaveIcon();
|
||||
ProfileConfiguration.Save();
|
||||
|
||||
_profileService.SaveProfileConfigurationIcon(ProfileConfiguration);
|
||||
_profileService.SaveProfileCategory(_profileCategory);
|
||||
Close(ProfileConfiguration);
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public partial class ProfileConfigurationEditViewModel : DialogViewModelBase<Pro
|
||||
{
|
||||
try
|
||||
{
|
||||
Stream? iconStream = _profileConfiguration.Icon.GetIconStream();
|
||||
Stream? iconStream = _profileConfiguration.Icon.IconBytes != null ? new MemoryStream(_profileConfiguration.Icon.IconBytes) : null;
|
||||
SelectedBitmapSource = iconStream != null ? new Bitmap(iconStream) : null;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -103,10 +103,10 @@ public partial class SidebarCategoryViewModel : ActivatableViewModelBase
|
||||
public bool IsCollapsed => _isCollapsed?.Value ?? false;
|
||||
public bool IsSuspended => _isSuspended?.Value ?? false;
|
||||
|
||||
public void AddProfileConfiguration(ProfileConfiguration profileConfiguration, int? index)
|
||||
public void AddProfileConfiguration(ProfileConfiguration profileConfiguration, ProfileConfiguration? target)
|
||||
{
|
||||
ProfileCategory oldCategory = profileConfiguration.Category;
|
||||
ProfileCategory.AddProfileConfiguration(profileConfiguration, index);
|
||||
ProfileCategory.AddProfileConfiguration(profileConfiguration, target);
|
||||
|
||||
_profileService.SaveProfileCategory(ProfileCategory);
|
||||
// If the profile moved to a new category, also save the old category
|
||||
|
||||
@@ -40,15 +40,6 @@ public class SidebarProfileConfigurationViewModel : ActivatableViewModelBase
|
||||
.Select(p => p == null)
|
||||
.ToProperty(this, vm => vm.IsDisabled)
|
||||
.DisposeWith(d));
|
||||
|
||||
try
|
||||
{
|
||||
_profileService.LoadProfileConfigurationIcon(ProfileConfiguration);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored, too bad but don't crash over corrupt icons
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileConfiguration ProfileConfiguration { get; }
|
||||
|
||||
@@ -97,7 +97,7 @@ public partial class SurfaceDeviceViewModel : ActivatableViewModelBase
|
||||
if (x < 0 || y < 0)
|
||||
return false;
|
||||
|
||||
double maxTextureSize = 4096 / _settingsService.GetSetting("Core.RenderScale", 0.25).Value;
|
||||
double maxTextureSize = 4096 / _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
|
||||
if (x + Device.Rectangle.Width > maxTextureSize || y + Device.Rectangle.Height > maxTextureSize)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public partial class SurfaceEditorViewModel : RoutableScreen, IMainScreenViewMod
|
||||
public ReactiveCommand<ArtemisDevice, Unit> SendToBack { get; }
|
||||
public ReactiveCommand<ArtemisDevice, Unit> SendBackward { get; }
|
||||
|
||||
public double MaxTextureSize => 4096 / _settingsService.GetSetting("Core.RenderScale", 0.25).Value;
|
||||
public double MaxTextureSize => 4096 / _settingsService.GetSetting("Core.RenderScale", 0.5).Value;
|
||||
|
||||
public void UpdateSelection(List<SurfaceDeviceViewModel> devices, bool expand, bool invert)
|
||||
{
|
||||
|
||||
+3
-5
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
@@ -27,10 +28,7 @@ public partial class ProfileSelectionStepViewModel : SubmissionViewModel
|
||||
_profileService = profileService;
|
||||
|
||||
// Use copies of the profiles, the originals are used by the core and could be disposed
|
||||
Profiles = new ObservableCollection<ProfileConfiguration>(_profileService.ProfileConfigurations.Select(_profileService.CloneProfileConfiguration));
|
||||
foreach (ProfileConfiguration profileConfiguration in Profiles)
|
||||
_profileService.LoadProfileConfigurationIcon(profileConfiguration);
|
||||
|
||||
Profiles = new ObservableCollection<ProfileConfiguration>(_profileService.ProfileCategories.SelectMany(c => c.ProfileConfigurations).Select(_profileService.CloneProfileConfiguration));
|
||||
ProfilePreview = profilePreviewViewModel;
|
||||
|
||||
GoBack = ReactiveCommand.Create(() => State.ChangeScreen<EntryTypeStepViewModel>());
|
||||
@@ -70,7 +68,7 @@ public partial class ProfileSelectionStepViewModel : SubmissionViewModel
|
||||
|
||||
State.EntrySource = new ProfileEntrySource(SelectedProfile, SelectedProfile.GetFeatureDependencies().Distinct().ToList());
|
||||
State.Name = SelectedProfile.Name;
|
||||
State.Icon = SelectedProfile.Icon.GetIconStream();
|
||||
State.Icon = SelectedProfile.Icon.IconBytes != null ? new MemoryStream(SelectedProfile.Icon.IconBytes) : null;
|
||||
|
||||
// Render the material icon of the profile
|
||||
if (State.Icon == null && SelectedProfile.Icon.IconName != null)
|
||||
|
||||
Reference in new issue
Block a user