Modules - Added activation mechanism and conditions

This commit is contained in:
SpoinkyNL committed 2020-08-16 23:44:59 +02:00
1 parent 12456519d5
commit 6a32ecc3a4
17 files changed
+357 -149

No files matched your search

+46 -17
View File
@@ -39,6 +39,7 @@ namespace Artemis.Core.Services
private List<BaseDataModelExpansion> _dataModelExpansions;
private List<Module> _modules;
private IntroAnimation _introAnimation;
private DateTime _lastModuleActivationUpdate;
// ReSharper disable once UnusedParameter.Local - Storage migration service is injected early to ensure it runs before anything else
internal CoreService(ILogger logger, StorageMigrationService _, ISettingsService settingsService, IPluginService pluginService,
@@ -95,8 +96,6 @@ namespace Artemis.Core.Services
_logger.Information("Initialized without an active surface entity");
PlayIntroAnimation();
_profileService.ActivateLastActiveProfiles();
OnInitialized();
}
@@ -170,6 +169,11 @@ namespace Artemis.Core.Services
try
{
_frameStopWatch.Restart();
// Only run the module activation update every 2 seconds
if (DateTime.Now - _lastModuleActivationUpdate > TimeSpan.FromSeconds(2))
ModuleActivationUpdate();
lock (_dataModelExpansions)
{
// Update all active modules
@@ -177,13 +181,16 @@ namespace Artemis.Core.Services
dataModelExpansion.Update(args.DeltaTime);
}
List<Module> modules;
lock (_modules)
{
// Update all active modules
foreach (var module in _modules)
module.Update(args.DeltaTime);
modules = _modules.Where(m => m.IsActivated).ToList();
}
// Update all active modules
foreach (var module in modules)
module.Update(args.DeltaTime);
// If there is no ready bitmap brush, skip the frame
if (_rgbService.BitmapBrush == null)
return;
@@ -194,20 +201,15 @@ namespace Artemis.Core.Services
return;
// Render all active modules
using (var canvas = new SKCanvas(_rgbService.BitmapBrush.Bitmap))
using var canvas = new SKCanvas(_rgbService.BitmapBrush.Bitmap);
canvas.Clear(new SKColor(0, 0, 0));
if (!ModuleRenderingDisabled)
{
canvas.Clear(new SKColor(0, 0, 0));
if (!ModuleRenderingDisabled)
{
lock (_modules)
{
foreach (var module in _modules)
module.Render(args.DeltaTime, _surfaceService.ActiveSurface, canvas, _rgbService.BitmapBrush.Bitmap.Info);
}
}
OnFrameRendering(new FrameRenderingEventArgs(_modules, canvas, args.DeltaTime, _rgbService.Surface));
foreach (var module in modules)
module.Render(args.DeltaTime, _surfaceService.ActiveSurface, canvas, _rgbService.BitmapBrush.Bitmap.Info);
}
OnFrameRendering(new FrameRenderingEventArgs(modules, canvas, args.DeltaTime, _rgbService.Surface));
}
}
catch (Exception e)
@@ -221,6 +223,33 @@ namespace Artemis.Core.Services
}
}
private void ModuleActivationUpdate()
{
_lastModuleActivationUpdate = DateTime.Now;
var stopwatch = new Stopwatch();
stopwatch.Start();
lock (_modules)
{
foreach (var module in _modules)
{
var shouldBeActivated = module.EvaluateActivationRequirements();
if (shouldBeActivated && !module.IsActivated)
{
module.Activate();
// If this is a profile module, activate the last active profile after module activation
if (module is ProfileModule profileModule)
_profileService.ActivateLastProfile(profileModule);
}
else if (!shouldBeActivated && module.IsActivated)
module.Deactivate();
}
}
stopwatch.Stop();
if (stopwatch.ElapsedMilliseconds > 100)
_logger.Warning("Activation requirements evaluation took too long: {moduleCount} module(s) in {elapsed}", _modules.Count, stopwatch.Elapsed);
}
private void SurfaceOnUpdated(UpdatedEventArgs args)
{
if (_rgbService.IsRenderPaused)
@@ -11,11 +11,6 @@ namespace Artemis.Core.Services.Storage.Interfaces
/// </summary>
public interface IProfileService : IArtemisService
{
/// <summary>
/// Activates the last profile for each module
/// </summary>
void ActivateLastActiveProfiles();
/// <summary>
/// Creates a new profile for the given module and returns a descriptor pointing to it
/// </summary>
@@ -50,6 +45,12 @@ namespace Artemis.Core.Services.Storage.Interfaces
/// <param name="profileDescriptor">The descriptor pointing to the profile to delete</param>
void DeleteProfile(ProfileDescriptor profileDescriptor);
/// <summary>
/// Activates the last profile of the given profile module
/// </summary>
/// <param name="profileModule"></param>
void ActivateLastProfile(ProfileModule profileModule);
/// <summary>
/// Activates the profile described in the given <see cref="ProfileDescriptor" /> with the currently active surface
/// </summary>
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using Artemis.Core.Events;
@@ -11,7 +10,6 @@ using Artemis.Core.Plugins.Abstract;
using Artemis.Core.Plugins.LayerEffect.Abstract;
using Artemis.Core.Services.Interfaces;
using Artemis.Core.Services.Storage.Interfaces;
using Artemis.Core.Utilities;
using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Repositories.Interfaces;
using Newtonsoft.Json;
@@ -44,15 +42,6 @@ namespace Artemis.Core.Services.Storage
public JsonSerializerSettings MementoSettings { get; set; } = new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All};
public JsonSerializerSettings ExportSettings { get; set; } = new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All, Formatting = Formatting.Indented};
public void ActivateLastActiveProfiles()
{
foreach (var profileModule in _pluginService.GetPluginsOfType<ProfileModule>())
{
var activeProfile = GetLastActiveProfile(profileModule);
ActivateProfile(activeProfile);
}
}
public List<ProfileDescriptor> GetProfileDescriptors(ProfileModule module)
{
var profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
@@ -67,6 +56,12 @@ namespace Artemis.Core.Services.Storage
return new ProfileDescriptor(module, profileEntity);
}
public void ActivateLastProfile(ProfileModule profileModule)
{
var activeProfile = GetLastActiveProfile(profileModule);
ActivateProfile(activeProfile);
}
public Profile ActivateProfile(ProfileDescriptor profileDescriptor)
{
if (profileDescriptor.ProfileModule.ActiveProfile?.EntityId == profileDescriptor.Id)
@@ -109,16 +104,6 @@ namespace Artemis.Core.Services.Storage
SaveActiveProfile(module);
}
private void SaveActiveProfile(ProfileModule module)
{
var profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
foreach (var profileEntity in profileEntities)
{
profileEntity.IsActive = module.ActiveProfile.EntityId == profileEntity.Id;
_profileRepository.Save(profileEntity);
}
}
public async Task ClearActiveProfileAnimated(ProfileModule module)
{
await module.ChangeActiveProfileAnimated(null, _surfaceService.ActiveSurface);
@@ -210,13 +195,6 @@ namespace Artemis.Core.Services.Storage
}
}
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);
@@ -245,6 +223,23 @@ namespace Artemis.Core.Services.Storage
return new ProfileDescriptor(profileModule, profileEntity);
}
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);
}
private void SaveActiveProfile(ProfileModule module)
{
var profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
foreach (var profileEntity in profileEntities)
{
profileEntity.IsActive = module.ActiveProfile.EntityId == profileEntity.Id;
_profileRepository.Save(profileEntity);
}
}
/// <summary>
/// Initializes the properties on the layers of the given profile
/// </summary>
@@ -347,11 +342,6 @@ namespace Artemis.Core.Services.Storage
ActiveProfilesInstantiatePlugins();
if (e.PluginInfo.Instance is LayerEffectProvider)
ActiveProfilesInstantiatePlugins();
else if (e.PluginInfo.Instance is ProfileModule profileModule)
{
var activeProfile = GetLastActiveProfile(profileModule);
ActivateProfile(activeProfile);
}
}
#endregion