mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Profiles - Finished dispose implementation
Profiles - Added transition between active profiles Core - Added startup animation
This commit is contained in:
1 parent
c0bdd8cf26
commit
d955bc8635
43 files changed
+1908
-361
No files matched your search
@@ -1,10 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Plugins.Abstract;
|
||||
using Artemis.Core.Services.Interfaces;
|
||||
|
||||
namespace Artemis.Core.Services.Storage.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to profile storage and is responsible for activating default profiles
|
||||
/// </summary>
|
||||
public interface IProfileService : IArtemisService
|
||||
{
|
||||
/// <summary>
|
||||
@@ -18,14 +22,14 @@ namespace Artemis.Core.Services.Storage.Interfaces
|
||||
/// <param name="module">The profile module to create the profile for</param>
|
||||
/// <param name="name">The name of the new profile</param>
|
||||
/// <returns></returns>
|
||||
ProfileDescriptor CreateProfile(ProfileModule module, string name);
|
||||
ProfileDescriptor CreateProfileDescriptor(ProfileModule module, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a descriptor for each profile stored for the given <see cref="ProfileModule" />
|
||||
/// </summary>
|
||||
/// <param name="module">The module to return profile descriptors for</param>
|
||||
/// <returns></returns>
|
||||
List<ProfileDescriptor> GetProfiles(ProfileModule module);
|
||||
List<ProfileDescriptor> GetProfileDescriptors(ProfileModule module);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the profile to persistent storage
|
||||
@@ -40,30 +44,53 @@ namespace Artemis.Core.Services.Storage.Interfaces
|
||||
/// <param name="profile">The profile to delete</param>
|
||||
void DeleteProfile(Profile profile);
|
||||
|
||||
/// <summary>
|
||||
/// Permanently deletes the profile described by the provided profile descriptor
|
||||
/// </summary>
|
||||
/// <param name="profileDescriptor">The descriptor pointing to the profile to delete</param>
|
||||
void DeleteProfile(ProfileDescriptor profileDescriptor);
|
||||
|
||||
/// <summary>
|
||||
/// Activates the profile described in the given <see cref="ProfileDescriptor" /> with the currently active surface
|
||||
/// </summary>
|
||||
/// <param name="profileDescriptor">The descriptor describing the profile to activate</param>
|
||||
Profile ActivateProfile(ProfileDescriptor profileDescriptor);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously activates the profile described in the given <see cref="ProfileDescriptor" /> with the currently
|
||||
/// active surface using a fade animation
|
||||
/// </summary>
|
||||
/// <param name="profileDescriptor">The descriptor describing the profile to activate</param>
|
||||
Task<Profile> ActivateProfileAnimated(ProfileDescriptor profileDescriptor);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the active profile on the given <see cref="ProfileModule" />
|
||||
/// </summary>
|
||||
/// <param name="module">The profile module to deactivate the active profile on</param>
|
||||
void ClearActiveProfile(ProfileModule module);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously clears the active profile on the given <see cref="ProfileModule" /> using a fade animation
|
||||
/// </summary>
|
||||
/// <param name="module">The profile module to deactivate the active profile on</param>
|
||||
Task ClearActiveProfileAnimated(ProfileModule module);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to restore the profile to the state it had before the last <see cref="UpdateProfile" /> call.
|
||||
/// </summary>
|
||||
/// <param name="selectedProfile"></param>
|
||||
/// <param name="module"></param>
|
||||
bool UndoUpdateProfile(Profile selectedProfile, ProfileModule module);
|
||||
/// <param name="profile"></param>
|
||||
bool UndoUpdateProfile(Profile profile);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to restore the profile to the state it had before the last <see cref="UndoUpdateProfile" /> call.
|
||||
/// </summary>
|
||||
/// <param name="selectedProfile"></param>
|
||||
/// <param name="module"></param>
|
||||
bool RedoUpdateProfile(Profile selectedProfile, ProfileModule module);
|
||||
/// <param name="profile"></param>
|
||||
bool RedoUpdateProfile(Profile profile);
|
||||
|
||||
/// <summary>
|
||||
/// Prepares the profile for rendering. You should not need to call this, it is exposed for some niche usage in the core
|
||||
/// </summary>
|
||||
/// <param name="profile"></param>
|
||||
void InstantiateProfile(Profile profile);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.Events;
|
||||
using Artemis.Core.Models.Profile;
|
||||
using Artemis.Core.Models.Surface;
|
||||
@@ -15,9 +16,6 @@ using Serilog;
|
||||
|
||||
namespace Artemis.Core.Services.Storage
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to profile storage and is responsible for activating default profiles
|
||||
/// </summary>
|
||||
public class ProfileService : IProfileService
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
@@ -51,20 +49,13 @@ namespace Artemis.Core.Services.Storage
|
||||
}
|
||||
}
|
||||
|
||||
public List<ProfileDescriptor> GetProfiles(ProfileModule module)
|
||||
public List<ProfileDescriptor> GetProfileDescriptors(ProfileModule module)
|
||||
{
|
||||
var profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
|
||||
return profileEntities.Select(e => new ProfileDescriptor(module, e)).ToList();
|
||||
}
|
||||
|
||||
public ProfileDescriptor GetLastActiveProfile(ProfileModule module)
|
||||
{
|
||||
var moduleProfiles = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
|
||||
var profileEntity = moduleProfiles.FirstOrDefault(p => p.IsActive) ?? moduleProfiles.FirstOrDefault();
|
||||
return profileEntity == null ? null : new ProfileDescriptor(module, profileEntity);
|
||||
}
|
||||
|
||||
public ProfileDescriptor CreateProfile(ProfileModule module, string name)
|
||||
public ProfileDescriptor CreateProfileDescriptor(ProfileModule module, string name)
|
||||
{
|
||||
var profileEntity = new ProfileEntity {Id = Guid.NewGuid(), Name = name, PluginGuid = module.PluginInfo.Guid};
|
||||
return new ProfileDescriptor(module, profileEntity);
|
||||
@@ -72,31 +63,59 @@ namespace Artemis.Core.Services.Storage
|
||||
|
||||
public Profile ActivateProfile(ProfileDescriptor profileDescriptor)
|
||||
{
|
||||
if (profileDescriptor.ProfileModule.ActiveProfile.EntityId == profileDescriptor.Id)
|
||||
if (profileDescriptor.ProfileModule.ActiveProfile?.EntityId == profileDescriptor.Id)
|
||||
return profileDescriptor.ProfileModule.ActiveProfile;
|
||||
|
||||
var profile = new Profile(profileDescriptor.ProfileModule, profileDescriptor.ProfileEntity);
|
||||
InitializeLayerProperties(profile);
|
||||
InstantiateLayers(profile);
|
||||
InstantiateFolders(profile);
|
||||
var profileEntity = _profileRepository.Get(profileDescriptor.Id);
|
||||
var profile = new Profile(profileDescriptor.ProfileModule, profileEntity);
|
||||
InstantiateProfile(profile);
|
||||
|
||||
profileDescriptor.ProfileModule.ChangeActiveProfile(profile, _surfaceService.ActiveSurface);
|
||||
return profile;
|
||||
}
|
||||
|
||||
public async Task<Profile> ActivateProfileAnimated(ProfileDescriptor profileDescriptor)
|
||||
{
|
||||
if (profileDescriptor.ProfileModule.ActiveProfile?.EntityId == profileDescriptor.Id)
|
||||
return profileDescriptor.ProfileModule.ActiveProfile;
|
||||
|
||||
var profileEntity = _profileRepository.Get(profileDescriptor.Id);
|
||||
var profile = new Profile(profileDescriptor.ProfileModule, profileEntity);
|
||||
InstantiateProfile(profile);
|
||||
|
||||
await profileDescriptor.ProfileModule.ChangeActiveProfileAnimated(profile, _surfaceService.ActiveSurface);
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void ClearActiveProfile(ProfileModule module)
|
||||
{
|
||||
module.ChangeActiveProfile(null, _surfaceService.ActiveSurface);
|
||||
}
|
||||
|
||||
public async Task ClearActiveProfileAnimated(ProfileModule module)
|
||||
{
|
||||
await module.ChangeActiveProfileAnimated(null, _surfaceService.ActiveSurface);
|
||||
}
|
||||
|
||||
public void DeleteProfile(Profile profile)
|
||||
{
|
||||
_logger.Debug("Removing profile " + profile);
|
||||
|
||||
|
||||
// If the given profile is currently active, disable it first (this also disposes it)
|
||||
if (profile.Module.ActiveProfile == profile)
|
||||
profile.Module.ChangeActiveProfile(null, _surfaceService.ActiveSurface);
|
||||
else
|
||||
profile.Dispose();
|
||||
|
||||
_profileRepository.Remove(profile.ProfileEntity);
|
||||
}
|
||||
|
||||
public void DeleteProfile(ProfileDescriptor profileDescriptor)
|
||||
{
|
||||
var profileEntity = _profileRepository.Get(profileDescriptor.Id);
|
||||
_profileRepository.Remove(profileEntity);
|
||||
}
|
||||
|
||||
public void UpdateProfile(Profile profile, bool includeChildren)
|
||||
{
|
||||
_logger.Debug("Updating profile " + profile);
|
||||
@@ -116,46 +135,73 @@ namespace Artemis.Core.Services.Storage
|
||||
_profileRepository.Save(profile.ProfileEntity);
|
||||
}
|
||||
|
||||
public bool UndoUpdateProfile(Profile profile, ProfileModule module)
|
||||
public bool UndoUpdateProfile(Profile profile)
|
||||
{
|
||||
if (!profile.UndoStack.Any())
|
||||
// Keep the profile from being rendered by locking it
|
||||
lock (profile)
|
||||
{
|
||||
_logger.Debug("Undo profile update - Failed, undo stack empty");
|
||||
return false;
|
||||
}
|
||||
if (!profile.UndoStack.Any())
|
||||
{
|
||||
_logger.Debug("Undo profile update - Failed, undo stack empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
ActivateProfile(module, null);
|
||||
var top = profile.UndoStack.Pop();
|
||||
var memento = JsonConvert.SerializeObject(profile.ProfileEntity, MementoSettings);
|
||||
profile.RedoStack.Push(memento);
|
||||
profile.ProfileEntity = JsonConvert.DeserializeObject<ProfileEntity>(top, MementoSettings);
|
||||
profile.ApplyToProfile();
|
||||
ActivateProfile(module, profile);
|
||||
var top = profile.UndoStack.Pop();
|
||||
var memento = JsonConvert.SerializeObject(profile.ProfileEntity, MementoSettings);
|
||||
profile.RedoStack.Push(memento);
|
||||
profile.ProfileEntity = JsonConvert.DeserializeObject<ProfileEntity>(top, MementoSettings);
|
||||
|
||||
profile.ApplyToProfile();
|
||||
InstantiateProfile(profile);
|
||||
}
|
||||
|
||||
_logger.Debug("Undo profile update - Success");
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RedoUpdateProfile(Profile profile, ProfileModule module)
|
||||
public bool RedoUpdateProfile(Profile profile)
|
||||
{
|
||||
if (!profile.RedoStack.Any())
|
||||
// Keep the profile from being rendered by locking it
|
||||
lock (profile)
|
||||
{
|
||||
_logger.Debug("Redo profile update - Failed, redo empty");
|
||||
return false;
|
||||
if (!profile.RedoStack.Any())
|
||||
{
|
||||
_logger.Debug("Redo profile update - Failed, redo empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
var top = profile.RedoStack.Pop();
|
||||
var memento = JsonConvert.SerializeObject(profile.ProfileEntity, MementoSettings);
|
||||
profile.UndoStack.Push(memento);
|
||||
profile.ProfileEntity = JsonConvert.DeserializeObject<ProfileEntity>(top, MementoSettings);
|
||||
|
||||
profile.ApplyToProfile();
|
||||
InstantiateProfile(profile);
|
||||
|
||||
_logger.Debug("Redo profile update - Success");
|
||||
return true;
|
||||
}
|
||||
|
||||
ActivateProfile(module, null);
|
||||
var top = profile.RedoStack.Pop();
|
||||
var memento = JsonConvert.SerializeObject(profile.ProfileEntity, MementoSettings);
|
||||
profile.UndoStack.Push(memento);
|
||||
profile.ProfileEntity = JsonConvert.DeserializeObject<ProfileEntity>(top, MementoSettings);
|
||||
profile.ApplyToProfile();
|
||||
ActivateProfile(module, profile);
|
||||
|
||||
_logger.Debug("Redo profile update - Success");
|
||||
return true;
|
||||
}
|
||||
|
||||
public ProfileDescriptor GetLastActiveProfile(ProfileModule module)
|
||||
{
|
||||
var moduleProfiles = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
|
||||
var profileEntity = moduleProfiles.FirstOrDefault(p => p.IsActive) ?? moduleProfiles.FirstOrDefault();
|
||||
return profileEntity == null ? null : new ProfileDescriptor(module, profileEntity);
|
||||
}
|
||||
|
||||
public void InstantiateProfile(Profile profile)
|
||||
{
|
||||
profile.PopulateLeds(_surfaceService.ActiveSurface);
|
||||
InitializeLayerProperties(profile);
|
||||
InstantiateLayers(profile);
|
||||
InstantiateFolders(profile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the properties on the layers of the given profile
|
||||
/// </summary>
|
||||
/// <param name="profile"></param>
|
||||
private void InitializeLayerProperties(Profile profile)
|
||||
{
|
||||
foreach (var layer in profile.GetAllLayers())
|
||||
@@ -167,6 +213,9 @@ namespace Artemis.Core.Services.Storage
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates all plugin-related classes on the folders of the given profile
|
||||
/// </summary>
|
||||
private void InstantiateFolders(Profile profile)
|
||||
{
|
||||
foreach (var folder in profile.GetAllFolders())
|
||||
@@ -182,6 +231,9 @@ namespace Artemis.Core.Services.Storage
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates all plugin-related classes on the layers of the given profile
|
||||
/// </summary>
|
||||
private void InstantiateLayers(Profile profile)
|
||||
{
|
||||
foreach (var layer in profile.GetAllLayers())
|
||||
@@ -204,6 +256,10 @@ namespace Artemis.Core.Services.Storage
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates all missing LEDs on all currently active profiles
|
||||
/// </summary>
|
||||
/// <param name="surface"></param>
|
||||
private void ActiveProfilesPopulateLeds(ArtemisSurface surface)
|
||||
{
|
||||
var profileModules = _pluginService.GetPluginsOfType<ProfileModule>();
|
||||
@@ -211,6 +267,10 @@ namespace Artemis.Core.Services.Storage
|
||||
profileModule.ActiveProfile.PopulateLeds(surface);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates all missing plugin-related classes on the profile trees of all currently active profiles
|
||||
/// </summary>
|
||||
private void ActiveProfilesInstantiatePlugins()
|
||||
{
|
||||
var profileModules = _pluginService.GetPluginsOfType<ProfileModule>();
|
||||
@@ -242,8 +302,8 @@ namespace Artemis.Core.Services.Storage
|
||||
ActiveProfilesInstantiatePlugins();
|
||||
else if (e.PluginInfo.Instance is ProfileModule profileModule)
|
||||
{
|
||||
var activeProfile = GetActiveProfile(profileModule);
|
||||
ActivateProfile(profileModule, activeProfile);
|
||||
var activeProfile = GetLastActiveProfile(profileModule);
|
||||
ActivateProfile(activeProfile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user