diff --git a/src/Artemis.Core/Constants.cs b/src/Artemis.Core/Constants.cs
index c61aa021c..79d19cc48 100644
--- a/src/Artemis.Core/Constants.cs
+++ b/src/Artemis.Core/Constants.cs
@@ -6,6 +6,7 @@ using System.Linq;
using System.Reflection;
using System.Text.Json;
using Artemis.Core.JsonConverters;
+using Artemis.Storage.Entities.Plugins;
namespace Artemis.Core;
@@ -90,7 +91,7 @@ public static class Constants
///
/// The plugin used by core components of Artemis
///
- public static readonly Plugin CorePlugin = new(CorePluginInfo, new DirectoryInfo(ApplicationFolder), null);
+ public static readonly Plugin CorePlugin = new(CorePluginInfo, new DirectoryInfo(ApplicationFolder), new PluginEntity(){Id = CorePluginInfo.Guid}, false);
///
/// A read-only collection containing all primitive numeric types
diff --git a/src/Artemis.Core/DryIoc/ContainerExtensions.cs b/src/Artemis.Core/DryIoc/ContainerExtensions.cs
index ba0ede352..62712427f 100644
--- a/src/Artemis.Core/DryIoc/ContainerExtensions.cs
+++ b/src/Artemis.Core/DryIoc/ContainerExtensions.cs
@@ -30,7 +30,6 @@ public static class ContainerExtensions
container.RegisterMany(coreAssembly, type => type.IsAssignableTo(), Reuse.Singleton, setup: Setup.With(condition: HasAccessToProtectedService));
// Bind storage
- container.RegisterDelegate(() => StorageManager.CreateRepository(Constants.DataFolder), Reuse.Singleton);
container.RegisterDelegate(() => StorageManager.CreateDbContext(Constants.DataFolder), Reuse.Transient);
container.RegisterMany(storageAssembly, type => type.IsAssignableTo(), Reuse.Singleton);
diff --git a/src/Artemis.Core/Models/Profile/ProfileCategory.cs b/src/Artemis.Core/Models/Profile/ProfileCategory.cs
index 63dbafffa..cdab02e8a 100644
--- a/src/Artemis.Core/Models/Profile/ProfileCategory.cs
+++ b/src/Artemis.Core/Models/Profile/ProfileCategory.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Linq;
using Artemis.Storage.Entities.Profile;
namespace Artemis.Core;
@@ -15,7 +16,6 @@ public class ProfileCategory : CorePropertyChanged, IStorageModel
///
public static readonly ProfileCategory Empty = new("Empty", -1);
- private readonly List _profileConfigurations = new();
private bool _isCollapsed;
private bool _isSuspended;
private string _name;
@@ -31,14 +31,16 @@ public class ProfileCategory : CorePropertyChanged, IStorageModel
_name = name;
_order = order;
Entity = new ProfileCategoryEntity();
- ProfileConfigurations = new ReadOnlyCollection(_profileConfigurations);
+ ProfileConfigurations = new ReadOnlyCollection([]);
+
+ Save();
}
internal ProfileCategory(ProfileCategoryEntity entity)
{
_name = null!;
Entity = entity;
- ProfileConfigurations = new ReadOnlyCollection(_profileConfigurations);
+ ProfileConfigurations = new ReadOnlyCollection([]);
Load();
}
@@ -83,7 +85,7 @@ public class ProfileCategory : CorePropertyChanged, IStorageModel
///
/// Gets a read only collection of the profiles inside this category
///
- public ReadOnlyCollection ProfileConfigurations { get; }
+ public ReadOnlyCollection ProfileConfigurations { get; private set; }
///
/// Gets the unique ID of this category
@@ -98,27 +100,30 @@ public class ProfileCategory : CorePropertyChanged, IStorageModel
///
public void AddProfileConfiguration(ProfileConfiguration configuration, int? targetIndex)
{
+ List targetList = ProfileConfigurations.ToList();
+
// TODO: Look into this, it doesn't seem to make sense
// Removing the original will shift every item in the list forwards, keep that in mind with the target index
- if (configuration.Category == this && targetIndex != null && targetIndex.Value > _profileConfigurations.IndexOf(configuration))
+ if (configuration.Category == this && targetIndex != null && targetIndex.Value > targetList.IndexOf(configuration))
targetIndex -= 1;
configuration.Category.RemoveProfileConfiguration(configuration);
-
+
if (targetIndex != null)
{
- targetIndex = Math.Clamp(targetIndex.Value, 0, _profileConfigurations.Count);
- _profileConfigurations.Insert(targetIndex.Value, configuration);
+ targetIndex = Math.Clamp(targetIndex.Value, 0, targetList.Count);
+ targetList.Insert(targetIndex.Value, configuration);
}
else
{
- _profileConfigurations.Add(configuration);
+ targetList.Add(configuration);
}
configuration.Category = this;
+ ProfileConfigurations = new ReadOnlyCollection(targetList);
- for (int index = 0; index < _profileConfigurations.Count; index++)
- _profileConfigurations[index].Order = index;
+ for (int index = 0; index < ProfileConfigurations.Count; index++)
+ ProfileConfigurations[index].Order = index;
OnProfileConfigurationAdded(new ProfileConfigurationEventArgs(configuration));
}
@@ -156,11 +161,10 @@ public class ProfileCategory : CorePropertyChanged, IStorageModel
internal void RemoveProfileConfiguration(ProfileConfiguration configuration)
{
- if (!_profileConfigurations.Remove(configuration))
- return;
-
- for (int index = 0; index < _profileConfigurations.Count; index++)
- _profileConfigurations[index].Order = index;
+ ProfileConfigurations = new ReadOnlyCollection(ProfileConfigurations.Where(pc => pc != configuration).ToList());
+ for (int index = 0; index < ProfileConfigurations.Count; index++)
+ ProfileConfigurations[index].Order = index;
+
OnProfileConfigurationRemoved(new ProfileConfigurationEventArgs(configuration));
}
@@ -174,9 +178,7 @@ public class ProfileCategory : CorePropertyChanged, IStorageModel
IsSuspended = Entity.IsSuspended;
Order = Entity.Order;
- _profileConfigurations.Clear();
- foreach (ProfileContainerEntity entityProfileConfiguration in Entity.ProfileConfigurations)
- _profileConfigurations.Add(new ProfileConfiguration(this, entityProfileConfiguration));
+ ProfileConfigurations = new ReadOnlyCollection(Entity.ProfileConfigurations.Select(pc => new ProfileConfiguration(this, pc)).ToList());
}
///
@@ -188,7 +190,7 @@ public class ProfileCategory : CorePropertyChanged, IStorageModel
Entity.Order = Order;
Entity.ProfileConfigurations.Clear();
- foreach (ProfileConfiguration profileConfiguration in _profileConfigurations)
+ foreach (ProfileConfiguration profileConfiguration in ProfileConfigurations)
Entity.ProfileConfigurations.Add(profileConfiguration.Entity);
}
diff --git a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfigurationIcon.cs b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfigurationIcon.cs
index f2916190e..c935836db 100644
--- a/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfigurationIcon.cs
+++ b/src/Artemis.Core/Models/ProfileConfiguration/ProfileConfigurationIcon.cs
@@ -115,12 +115,12 @@ public class ProfileConfigurationIcon : CorePropertyChanged, IStorageModel
{
IconType = (ProfileConfigurationIconType) _entity.ProfileConfiguration.IconType;
Fill = _entity.ProfileConfiguration.IconFill;
- if (IconType != ProfileConfigurationIconType.MaterialIcon)
- return;
-
- IconName = _entity.ProfileConfiguration.MaterialIcon;
- IconBytes = IconType == ProfileConfigurationIconType.BitmapImage ? _entity.Icon : null;
+ if (IconType == ProfileConfigurationIconType.MaterialIcon)
+ IconName = _entity.ProfileConfiguration.MaterialIcon;
+ else
+ IconBytes = _entity.Icon;
+
OnIconUpdated();
}
diff --git a/src/Artemis.Core/Plugins/Plugin.cs b/src/Artemis.Core/Plugins/Plugin.cs
index ff90181bc..2b5ce51d1 100644
--- a/src/Artemis.Core/Plugins/Plugin.cs
+++ b/src/Artemis.Core/Plugins/Plugin.cs
@@ -23,14 +23,14 @@ public class Plugin : CorePropertyChanged, IDisposable
private bool _isEnabled;
- internal Plugin(PluginInfo info, DirectoryInfo directory, PluginEntity? pluginEntity)
+ internal Plugin(PluginInfo info, DirectoryInfo directory, PluginEntity pluginEntity, bool loadedFromStorage)
{
Info = info;
Directory = directory;
- Entity = pluginEntity ?? new PluginEntity {Id = Guid};
+ Entity = pluginEntity;
Info.Plugin = this;
- _loadedFromStorage = pluginEntity != null;
+ _loadedFromStorage = loadedFromStorage;
_features = new List();
_profilers = new List();
diff --git a/src/Artemis.Core/Services/DeviceService.cs b/src/Artemis.Core/Services/DeviceService.cs
index d110c90a4..46399722e 100644
--- a/src/Artemis.Core/Services/DeviceService.cs
+++ b/src/Artemis.Core/Services/DeviceService.cs
@@ -255,7 +255,6 @@ internal class DeviceService : IDeviceService
_logger.Information("No device config found for {DeviceInfo}, device hash: {DeviceHashCode}. Adding a new entry", rgbDevice.DeviceInfo, deviceIdentifier);
device = new ArtemisDevice(rgbDevice, deviceProvider);
_deviceRepository.Add(device.DeviceEntity);
- _deviceRepository.SaveChanges();
}
LoadDeviceLayout(device);
diff --git a/src/Artemis.Core/Services/PluginManagementService.cs b/src/Artemis.Core/Services/PluginManagementService.cs
index 033ed81ee..5b31b31d9 100644
--- a/src/Artemis.Core/Services/PluginManagementService.cs
+++ b/src/Artemis.Core/Services/PluginManagementService.cs
@@ -41,7 +41,7 @@ internal class PluginManagementService : IPluginManagementService
_pluginRepository = pluginRepository;
_deviceRepository = deviceRepository;
_plugins = new List();
-
+
StartHotReload();
}
@@ -372,7 +372,15 @@ internal class PluginManagementService : IPluginManagementService
}
// Load the entity and fall back on creating a new one
- Plugin plugin = new(pluginInfo, directory, _pluginRepository.GetPluginByGuid(pluginInfo.Guid));
+ PluginEntity? entity = _pluginRepository.GetPluginByGuid(pluginInfo.Guid);
+ bool loadedFromStorage = entity != null;
+ if (entity == null)
+ {
+ entity = new PluginEntity {Id = pluginInfo.Guid};
+ _pluginRepository.AddPlugin(entity);
+ }
+
+ Plugin plugin = new(pluginInfo, directory, entity, loadedFromStorage);
OnPluginLoading(new PluginEventArgs(plugin));
// Locate the main assembly entry
@@ -796,7 +804,7 @@ internal class PluginManagementService : IPluginManagementService
}
#endregion
-
+
#region Storage
private void SavePlugin(Plugin plugin)
diff --git a/src/Artemis.Core/Services/RenderService.cs b/src/Artemis.Core/Services/RenderService.cs
index bd73a0f0d..25c6e6185 100644
--- a/src/Artemis.Core/Services/RenderService.cs
+++ b/src/Artemis.Core/Services/RenderService.cs
@@ -40,7 +40,7 @@ internal class RenderService : IRenderService, IRenderer, IDisposable
_graphicsContextProviders = graphicsContextProviders;
_targetFrameRateSetting = settingsService.GetSetting("Core.TargetFrameRate", 30);
- _renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.25);
+ _renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.5);
_preferredGraphicsContext = settingsService.GetSetting("Core.PreferredGraphicsContext", "Software");
_targetFrameRateSetting.SettingChanged += OnRenderSettingsChanged;
_renderScaleSetting.SettingChanged += RenderScaleSettingOnSettingChanged;
diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs
index bf6aa0f4f..7e0112af7 100644
--- a/src/Artemis.Core/Services/Storage/ProfileService.cs
+++ b/src/Artemis.Core/Services/Storage/ProfileService.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
@@ -24,7 +25,6 @@ internal class ProfileService : IProfileService
private readonly IPluginManagementService _pluginManagementService;
private readonly IDeviceService _deviceService;
private readonly List _pendingKeyboardEvents = new();
- private readonly List _profileCategories;
private readonly List _profileMigrators;
private readonly List _renderExceptions = new();
private readonly List _updateExceptions = new();
@@ -44,17 +44,16 @@ internal class ProfileService : IProfileService
_pluginManagementService = pluginManagementService;
_deviceService = deviceService;
_profileMigrators = profileMigrators;
- _profileCategories = new List(_profileCategoryRepository.GetAll().Select(c => new ProfileCategory(c)).OrderBy(c => c.Order));
- ProfileCategories = new ReadOnlyCollection(_profileCategories);
-
+ ProfileCategories = new ReadOnlyCollection(_profileCategoryRepository.GetAll().Select(c => new ProfileCategory(c)).OrderBy(c => c.Order).ToList());
+
_deviceService.LedsChanged += DeviceServiceOnLedsChanged;
_pluginManagementService.PluginFeatureEnabled += PluginManagementServiceOnPluginFeatureToggled;
_pluginManagementService.PluginFeatureDisabled += PluginManagementServiceOnPluginFeatureToggled;
inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp;
- if (!_profileCategories.Any())
+ if (!ProfileCategories.Any())
CreateDefaultProfileCategories();
UpdateModules();
}
@@ -76,55 +75,52 @@ internal class ProfileService : IProfileService
return;
}
- lock (_profileCategories)
+ // Iterate the children in reverse because the first category must be rendered last to end up on top
+ for (int i = ProfileCategories.Count - 1; i > -1; i--)
{
- // Iterate the children in reverse because the first category must be rendered last to end up on top
- for (int i = _profileCategories.Count - 1; i > -1; i--)
+ ProfileCategory profileCategory = ProfileCategories[i];
+ for (int j = profileCategory.ProfileConfigurations.Count - 1; j > -1; j--)
{
- ProfileCategory profileCategory = _profileCategories[i];
- for (int j = profileCategory.ProfileConfigurations.Count - 1; j > -1; j--)
+ ProfileConfiguration profileConfiguration = profileCategory.ProfileConfigurations[j];
+
+ // Process hotkeys that where pressed since this profile last updated
+ ProcessPendingKeyEvents(profileConfiguration);
+
+ bool shouldBeActive = profileConfiguration.ShouldBeActive(false);
+ if (shouldBeActive)
{
- ProfileConfiguration profileConfiguration = profileCategory.ProfileConfigurations[j];
+ profileConfiguration.Update();
+ shouldBeActive = profileConfiguration.ActivationConditionMet;
+ }
- // Process hotkeys that where pressed since this profile last updated
- ProcessPendingKeyEvents(profileConfiguration);
-
- bool shouldBeActive = profileConfiguration.ShouldBeActive(false);
- if (shouldBeActive)
+ try
+ {
+ // Make sure the profile is active or inactive according to the parameters above
+ if (shouldBeActive && profileConfiguration.Profile == null && profileConfiguration.BrokenState != "Failed to activate profile")
+ profileConfiguration.TryOrBreak(() => ActivateProfile(profileConfiguration), "Failed to activate profile");
+ if (shouldBeActive && profileConfiguration.Profile != null && !profileConfiguration.Profile.ShouldDisplay)
+ profileConfiguration.Profile.ShouldDisplay = true;
+ else if (!shouldBeActive && profileConfiguration.Profile != null)
{
- profileConfiguration.Update();
- shouldBeActive = profileConfiguration.ActivationConditionMet;
+ if (!profileConfiguration.FadeInAndOut)
+ DeactivateProfile(profileConfiguration);
+ else if (!profileConfiguration.Profile.ShouldDisplay && profileConfiguration.Profile.Opacity <= 0)
+ DeactivateProfile(profileConfiguration);
+ else if (profileConfiguration.Profile.Opacity > 0)
+ RequestDeactivation(profileConfiguration);
}
- try
- {
- // Make sure the profile is active or inactive according to the parameters above
- if (shouldBeActive && profileConfiguration.Profile == null && profileConfiguration.BrokenState != "Failed to activate profile")
- profileConfiguration.TryOrBreak(() => ActivateProfile(profileConfiguration), "Failed to activate profile");
- if (shouldBeActive && profileConfiguration.Profile != null && !profileConfiguration.Profile.ShouldDisplay)
- profileConfiguration.Profile.ShouldDisplay = true;
- else if (!shouldBeActive && profileConfiguration.Profile != null)
- {
- if (!profileConfiguration.FadeInAndOut)
- DeactivateProfile(profileConfiguration);
- else if (!profileConfiguration.Profile.ShouldDisplay && profileConfiguration.Profile.Opacity <= 0)
- DeactivateProfile(profileConfiguration);
- else if (profileConfiguration.Profile.Opacity > 0)
- RequestDeactivation(profileConfiguration);
- }
-
- profileConfiguration.Profile?.Update(deltaTime);
- }
- catch (Exception e)
- {
- _updateExceptions.Add(e);
- }
+ profileConfiguration.Profile?.Update(deltaTime);
+ }
+ catch (Exception e)
+ {
+ _updateExceptions.Add(e);
}
}
-
- LogProfileUpdateExceptions();
- _pendingKeyboardEvents.Clear();
}
+
+ LogProfileUpdateExceptions();
+ _pendingKeyboardEvents.Clear();
}
///
@@ -137,35 +133,32 @@ internal class ProfileService : IProfileService
return;
}
- lock (_profileCategories)
+ // Iterate the children in reverse because the first category must be rendered last to end up on top
+ for (int i = ProfileCategories.Count - 1; i > -1; i--)
{
- // Iterate the children in reverse because the first category must be rendered last to end up on top
- for (int i = _profileCategories.Count - 1; i > -1; i--)
+ ProfileCategory profileCategory = ProfileCategories[i];
+ for (int j = profileCategory.ProfileConfigurations.Count - 1; j > -1; j--)
{
- ProfileCategory profileCategory = _profileCategories[i];
- for (int j = profileCategory.ProfileConfigurations.Count - 1; j > -1; j--)
+ try
{
- try
- {
- ProfileConfiguration profileConfiguration = profileCategory.ProfileConfigurations[j];
- // Ensure all criteria are met before rendering
- bool fadingOut = profileConfiguration.Profile?.ShouldDisplay == false && profileConfiguration.Profile?.Opacity > 0;
- if (!profileConfiguration.IsSuspended && !profileConfiguration.IsMissingModule && (profileConfiguration.ActivationConditionMet || fadingOut))
- profileConfiguration.Profile?.Render(canvas, SKPointI.Empty, null);
- }
- catch (Exception e)
- {
- _renderExceptions.Add(e);
- }
+ ProfileConfiguration profileConfiguration = profileCategory.ProfileConfigurations[j];
+ // Ensure all criteria are met before rendering
+ bool fadingOut = profileConfiguration.Profile?.ShouldDisplay == false && profileConfiguration.Profile?.Opacity > 0;
+ if (!profileConfiguration.IsSuspended && !profileConfiguration.IsMissingModule && (profileConfiguration.ActivationConditionMet || fadingOut))
+ profileConfiguration.Profile?.Render(canvas, SKPointI.Empty, null);
+ }
+ catch (Exception e)
+ {
+ _renderExceptions.Add(e);
}
}
-
- LogProfileRenderExceptions();
}
+
+ LogProfileRenderExceptions();
}
///
- public ReadOnlyCollection ProfileCategories { get; }
+ public ReadOnlyCollection ProfileCategories { get; private set; }
///
public ProfileConfiguration CloneProfileConfiguration(ProfileConfiguration profileConfiguration)
@@ -242,7 +235,7 @@ internal class ProfileService : IProfileService
if (addToTop)
{
profileCategory = new ProfileCategory(name, 1);
- foreach (ProfileCategory category in _profileCategories)
+ foreach (ProfileCategory category in ProfileCategories)
{
category.Order++;
category.Save();
@@ -250,11 +243,11 @@ internal class ProfileService : IProfileService
}
else
{
- profileCategory = new ProfileCategory(name, _profileCategories.Count + 1);
+ profileCategory = new ProfileCategory(name, ProfileCategories.Count + 1);
}
_profileCategoryRepository.Add(profileCategory.Entity);
- _profileCategories.Add(profileCategory);
+ ProfileCategories = new ReadOnlyCollection([..ProfileCategories, profileCategory]);
OnProfileCategoryAdded(new ProfileCategoryEventArgs(profileCategory));
return profileCategory;
@@ -266,7 +259,7 @@ internal class ProfileService : IProfileService
foreach (ProfileConfiguration profileConfiguration in profileCategory.ProfileConfigurations.ToList())
RemoveProfileConfiguration(profileConfiguration);
- _profileCategories.Remove(profileCategory);
+ ProfileCategories = new ReadOnlyCollection(ProfileCategories.Where(c => c != profileCategory).ToList());
_profileCategoryRepository.Remove(profileCategory.Entity);
OnProfileCategoryRemoved(new ProfileCategoryEventArgs(profileCategory));
@@ -299,16 +292,14 @@ internal class ProfileService : IProfileService
{
profileCategory.Save();
_profileCategoryRepository.SaveChanges();
-
- lock (_profileCategories)
- {
- _profileCategories.Sort((a, b) => a.Order - b.Order);
- }
+ ProfileCategories = new ReadOnlyCollection(ProfileCategories.OrderBy(c => c.Order).ToList());
}
///
public void SaveProfile(Profile profile, bool includeChildren)
{
+ Stopwatch sw = new();
+ sw.Start();
_logger.Debug("Updating profile - Saving {Profile}", profile);
profile.Save();
if (includeChildren)
@@ -329,9 +320,17 @@ internal class ProfileService : IProfileService
.SelectMany(c => c.ProfileConfigurations)
.FirstOrDefault(p => p.Profile != null && p.Profile != profile && p.ProfileId == profile.ProfileEntity.Id);
if (localInstance == null)
+ {
+ sw.Stop();
+ _logger.Debug("Updated profile - Saved {Profile} in {Time}ms", profile, sw.Elapsed.TotalMilliseconds);
return;
+ }
+
DeactivateProfile(localInstance);
ActivateProfile(localInstance);
+
+ sw.Stop();
+ _logger.Debug("Updated profile - Saved {Profile} in {Time}ms", profile, sw.Elapsed.TotalMilliseconds);
}
///
@@ -479,10 +478,7 @@ internal class ProfileService : IProfileService
private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e)
{
- lock (_profileCategories)
- {
- _pendingKeyboardEvents.Add(e);
- }
+ _pendingKeyboardEvents.Add(e);
}
private void MigrateProfile(JsonObject? configurationJson, JsonObject? profileJson)
diff --git a/src/Artemis.Storage.Migrator/Program.cs b/src/Artemis.Storage.Migrator/Program.cs
index 6ed140d3d..ba637973c 100644
--- a/src/Artemis.Storage.Migrator/Program.cs
+++ b/src/Artemis.Storage.Migrator/Program.cs
@@ -14,8 +14,6 @@ class Program
.WithoutThrowOnRegisteringDisposableTransient());
container.RegisterCore();
-
container.Resolve().Database.EnsureCreated();
-
}
}
\ No newline at end of file
diff --git a/src/Artemis.Storage/ArtemisDbContext.cs b/src/Artemis.Storage/ArtemisDbContext.cs
index 2063bbcf1..64ebbf963 100644
--- a/src/Artemis.Storage/ArtemisDbContext.cs
+++ b/src/Artemis.Storage/ArtemisDbContext.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
@@ -47,7 +46,7 @@ public class ArtemisDbContext : DbContext
.HasConversion(
v => JsonSerializer.Serialize(v, JsonSerializerOptions),
v => JsonSerializer.Deserialize(v, JsonSerializerOptions) ?? new ProfileConfigurationEntity());
-
+
modelBuilder.Entity()
.Property(e => e.Profile)
.HasConversion(
diff --git a/src/Artemis.Storage/Entities/Profile/FolderEntity.cs b/src/Artemis.Storage/Entities/Profile/FolderEntity.cs
index f47aa6bb8..f761dd98b 100644
--- a/src/Artemis.Storage/Entities/Profile/FolderEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/FolderEntity.cs
@@ -1,6 +1,5 @@
using System;
using Artemis.Storage.Entities.Profile.Abstract;
-using LiteDB;
namespace Artemis.Storage.Entities.Profile;
@@ -11,8 +10,5 @@ public class FolderEntity : RenderElementEntity
public bool IsExpanded { get; set; }
public bool Suspended { get; set; }
- [BsonRef("ProfileEntity")]
- public ProfileEntity Profile { get; set; } = null!;
-
public Guid ProfileId { get; set; }
}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Entities/Profile/LayerEntity.cs b/src/Artemis.Storage/Entities/Profile/LayerEntity.cs
index 521550b34..d7e9dfe09 100644
--- a/src/Artemis.Storage/Entities/Profile/LayerEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/LayerEntity.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.AdaptionHints;
-using LiteDB;
namespace Artemis.Storage.Entities.Profile;
@@ -25,8 +24,5 @@ public class LayerEntity : RenderElementEntity
public PropertyGroupEntity? TransformPropertyGroup { get; set; }
public LayerBrushEntity? LayerBrush { get; set; }
- [BsonRef("ProfileEntity")]
- public ProfileEntity Profile { get; set; } = null!;
-
public Guid ProfileId { get; set; }
}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Repositories/DeviceRepository.cs b/src/Artemis.Storage/Repositories/DeviceRepository.cs
index d438da17a..28387fa6e 100644
--- a/src/Artemis.Storage/Repositories/DeviceRepository.cs
+++ b/src/Artemis.Storage/Repositories/DeviceRepository.cs
@@ -31,9 +31,9 @@ internal class DeviceRepository : IDeviceRepository
return _dbContext.Devices.FirstOrDefault(d => d.Id == id);
}
- public List GetAll()
+ public IEnumerable GetAll()
{
- return _dbContext.Devices.ToList();
+ return _dbContext.Devices;
}
public void SaveChanges()
diff --git a/src/Artemis.Storage/Repositories/EntryRepository.cs b/src/Artemis.Storage/Repositories/EntryRepository.cs
index 8f719eb52..e378ace28 100644
--- a/src/Artemis.Storage/Repositories/EntryRepository.cs
+++ b/src/Artemis.Storage/Repositories/EntryRepository.cs
@@ -37,9 +37,9 @@ internal class EntryRepository : IEntryRepository
return _dbContext.Entries.FirstOrDefault(s => s.EntryId == entryId);
}
- public List GetAll()
+ public IEnumerable GetAll()
{
- return _dbContext.Entries.ToList();
+ return _dbContext.Entries;
}
public void SaveChanges()
diff --git a/src/Artemis.Storage/Repositories/Interfaces/IDeviceRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IDeviceRepository.cs
index 172f23e61..960f61d66 100644
--- a/src/Artemis.Storage/Repositories/Interfaces/IDeviceRepository.cs
+++ b/src/Artemis.Storage/Repositories/Interfaces/IDeviceRepository.cs
@@ -8,6 +8,6 @@ public interface IDeviceRepository : IRepository
void Add(DeviceEntity deviceEntity);
void Remove(DeviceEntity deviceEntity);
DeviceEntity? Get(string id);
- List GetAll();
+ IEnumerable GetAll();
void SaveChanges();
}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Repositories/Interfaces/IEntryRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IEntryRepository.cs
index 0e16c6dde..f1146de9f 100644
--- a/src/Artemis.Storage/Repositories/Interfaces/IEntryRepository.cs
+++ b/src/Artemis.Storage/Repositories/Interfaces/IEntryRepository.cs
@@ -10,6 +10,6 @@ public interface IEntryRepository : IRepository
void Remove(EntryEntity entryEntity);
EntryEntity? Get(Guid id);
EntryEntity? GetByEntryId(long entryId);
- List GetAll();
+ IEnumerable GetAll();
void SaveChanges();
}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs
index d6d766344..87e3e48e4 100644
--- a/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs
+++ b/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs
@@ -8,7 +8,6 @@ public interface IPluginRepository : IRepository
void AddPlugin(PluginEntity pluginEntity);
PluginEntity? GetPluginByGuid(Guid pluginGuid);
void AddSetting(PluginSettingEntity pluginSettingEntity);
- PluginSettingEntity? GetSettingByGuid(Guid pluginGuid);
PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid);
void RemoveSettings(Guid pluginGuid);
void SaveChanges();
diff --git a/src/Artemis.Storage/Repositories/PluginRepository.cs b/src/Artemis.Storage/Repositories/PluginRepository.cs
index 190530bbc..8c53d776c 100644
--- a/src/Artemis.Storage/Repositories/PluginRepository.cs
+++ b/src/Artemis.Storage/Repositories/PluginRepository.cs
@@ -2,6 +2,7 @@
using System.Linq;
using Artemis.Storage.Entities.Plugins;
using Artemis.Storage.Repositories.Interfaces;
+using Microsoft.EntityFrameworkCore;
namespace Artemis.Storage.Repositories;
@@ -22,7 +23,7 @@ internal class PluginRepository : IPluginRepository
public PluginEntity? GetPluginByGuid(Guid pluginGuid)
{
- return _dbContext.Plugins.FirstOrDefault(p => p.Id == pluginGuid);
+ return _dbContext.Plugins.Include(p => p.Features).FirstOrDefault(p => p.Id == pluginGuid);
}
public void AddSetting(PluginSettingEntity pluginSettingEntity)
@@ -31,11 +32,6 @@ internal class PluginRepository : IPluginRepository
SaveChanges();
}
- public PluginSettingEntity? GetSettingByGuid(Guid pluginGuid)
- {
- return _dbContext.PluginSettings.FirstOrDefault(p => p.PluginGuid == pluginGuid);
- }
-
public PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid)
{
return _dbContext.PluginSettings.FirstOrDefault(p => p.Name == name && p.PluginGuid == pluginGuid);
diff --git a/src/Artemis.Storage/StorageManager.cs b/src/Artemis.Storage/StorageManager.cs
index 7b612a927..d7c255363 100644
--- a/src/Artemis.Storage/StorageManager.cs
+++ b/src/Artemis.Storage/StorageManager.cs
@@ -1,12 +1,13 @@
using System;
using System.IO;
using System.Linq;
-using LiteDB;
+using Microsoft.EntityFrameworkCore;
namespace Artemis.Storage;
public static class StorageManager
{
+ private static bool _ranMigrations;
private static bool _inUse;
///
@@ -19,7 +20,7 @@ public static class StorageManager
if (_inUse)
throw new Exception("Storage is already in use, can't backup now.");
- string database = Path.Combine(dataFolder, "database.db");
+ string database = Path.Combine(dataFolder, "artemis.db");
if (!File.Exists(database))
return;
@@ -36,35 +37,20 @@ public static class StorageManager
oldest.Delete();
}
- File.Copy(database, Path.Combine(backupFolder, $"database-{DateTime.Now:yyyy-dd-M--HH-mm-ss}.db"));
+ File.Copy(database, Path.Combine(backupFolder, $"artemis-{DateTime.Now:yyyy-dd-M--HH-mm-ss}.db"));
}
-
- ///
- /// Creates the LiteRepository that will be managed by dependency injection
- ///
- /// The Artemis data folder
- public static LiteRepository CreateRepository(string dataFolder)
- {
- if (_inUse)
- throw new Exception("Storage is already in use, use dependency injection to get the repository.");
-
- try
- {
- _inUse = true;
- return new LiteRepository($"FileName={Path.Combine(dataFolder, "database.db")}");
- }
- catch (LiteException e)
- {
- // I don't like this way of error reporting, now I need to use reflection if I want a meaningful error message
- throw new Exception($"LiteDB threw error code {e.ErrorCode}. See inner exception for more details", e);
- }
- }
-
+
public static ArtemisDbContext CreateDbContext(string dataFolder)
{
- return new ArtemisDbContext()
- {
- DataFolder = dataFolder
- };
+ _inUse = true;
+
+ ArtemisDbContext dbContext = new() {DataFolder = dataFolder};
+ if (_ranMigrations)
+ return dbContext;
+
+ dbContext.Database.Migrate();
+ _ranMigrations = true;
+
+ return dbContext;
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml b/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml
index e29210098..70b2bc390 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml
+++ b/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml
@@ -174,16 +174,15 @@
Avalonia
DryIoc
+ Entity Framework Core
FluentAvalonia
EmbedIO
Humanizer
- LiteDB
McMaster.NETCore.Plugins
- Newtonsoft.Json
RGB.NET
Serilog
SkiaSharp
- Unclassified.NetRevisionTask
+ SQLite
@@ -192,6 +191,9 @@
https://github.com/dadhi/DryIoc
+
+ https://learn.microsoft.com/en-us/ef/core/
+
https://github.com/amwx/FluentAvalonia
@@ -201,15 +203,9 @@
https://github.com/Humanizr/Humanizer
-
- https://www.litedb.org/
-
https://github.com/natemcmaster/DotNetCorePlugins
-
- https://www.newtonsoft.com/json
-
https://github.com/DarthAffe/RGB.NET
@@ -218,9 +214,9 @@
https://github.com/mono/SkiaSharp
-
-
- https://unclassified.software/en/apps/netrevisiontask
+
+
+ https://www.sqlite.org/
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabViewModel.cs
index 6e3ee0d0b..87bb9c949 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabViewModel.cs
@@ -162,7 +162,7 @@ public class GeneralTabViewModel : RoutableScreen
public PluginSetting ProfileEditorShowDataModelValues => _settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
public PluginSetting CoreLoggingLevel => _settingsService.GetSetting("Core.LoggingLevel", LogEventLevel.Information);
public PluginSetting CorePreferredGraphicsContext => _settingsService.GetSetting("Core.PreferredGraphicsContext", "Software");
- public PluginSetting CoreRenderScale => _settingsService.GetSetting("Core.RenderScale", 0.25);
+ public PluginSetting CoreRenderScale => _settingsService.GetSetting("Core.RenderScale", 0.5);
public PluginSetting CoreTargetFrameRate => _settingsService.GetSetting("Core.TargetFrameRate", 30);
public PluginSetting WebServerEnabled => _settingsService.GetSetting("WebServer.Enabled", true);
public PluginSetting WebServerPort => _settingsService.GetSetting("WebServer.Port", 9696);
diff --git a/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditViewModel.cs b/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditViewModel.cs
index aa79c5e75..afa278f98 100644
--- a/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditViewModel.cs
+++ b/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditViewModel.cs
@@ -122,6 +122,7 @@ public partial class ProfileConfigurationEditViewModel : DialogViewModelBase maxTextureSize || y + Device.Rectangle.Height > maxTextureSize)
return false;
diff --git a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs
index 932313e96..248ca19de 100644
--- a/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs
+++ b/src/Artemis.UI/Screens/SurfaceEditor/SurfaceEditorViewModel.cs
@@ -87,7 +87,7 @@ public partial class SurfaceEditorViewModel : RoutableScreen, IMainScreenViewMod
public ReactiveCommand SendToBack { get; }
public ReactiveCommand 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 devices, bool expand, bool invert)
{
diff --git a/src/Artemis.WebClient.Workshop/Repositories/AuthenticationRepository.cs b/src/Artemis.WebClient.Workshop/Repositories/AuthenticationRepository.cs
index 9a3021c1f..8f96a314c 100644
--- a/src/Artemis.WebClient.Workshop/Repositories/AuthenticationRepository.cs
+++ b/src/Artemis.WebClient.Workshop/Repositories/AuthenticationRepository.cs
@@ -1,31 +1,30 @@
-using Artemis.WebClient.Workshop.Entities;
-using LiteDB;
+using Artemis.Core;
+using Artemis.Core.Services;
namespace Artemis.WebClient.Workshop.Repositories;
internal class AuthenticationRepository : IAuthenticationRepository
{
- private readonly LiteRepository _repository;
+ private readonly PluginSetting _refreshToken;
- public AuthenticationRepository(LiteRepository repository)
+ public AuthenticationRepository(ISettingsService settingsService)
{
- _repository = repository;
- _repository.Database.GetCollection().EnsureIndex(s => s.RefreshToken);
+ // Of course anyone can grab these indirectly, but that goes for whatever we do.
+ // ISettingsService is a protected service so we at least don't make it very straightforward.
+ _refreshToken = settingsService.GetSetting("Workshop.RefreshToken");
}
///
public void SetRefreshToken(string? refreshToken)
{
- _repository.Database.GetCollection().DeleteAll();
-
- if (refreshToken != null)
- _repository.Insert(new RefreshTokenEntity {RefreshToken = refreshToken});
+ _refreshToken.Value = refreshToken;
+ _refreshToken.Save();
}
///
public string? GetRefreshToken()
{
- return _repository.Query().FirstOrDefault()?.RefreshToken;
+ return _refreshToken.Value;
}
}
diff --git a/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs b/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs
index 6d2d36e9a..3da255d12 100644
--- a/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs
+++ b/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs
@@ -171,7 +171,12 @@ public class WorkshopService : IWorkshopService
public void SaveInstalledEntry(InstalledEntry entry)
{
entry.Save();
- _entryRepository.SaveChanges();
+
+ // Upsert for plebs
+ if (entry.Entity.Id == Guid.Empty)
+ _entryRepository.Add(entry.Entity);
+ else
+ _entryRepository.SaveChanges();
}
///