mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
Plugins - Reworked most of the activation logic
This commit is contained in:
1 parent
1e0dc1894d
commit
b56966c585
34 files changed
+509
-362
No files matched your search
@@ -28,7 +28,7 @@ namespace Artemis.Core.Services
|
||||
private readonly Stopwatch _frameStopWatch;
|
||||
private readonly ILogger _logger;
|
||||
private readonly PluginSetting<LogEventLevel> _loggingLevel;
|
||||
private readonly IPluginService _pluginService;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly IProfileService _profileService;
|
||||
private readonly IRgbService _rgbService;
|
||||
private readonly ISurfaceService _surfaceService;
|
||||
@@ -36,14 +36,14 @@ namespace Artemis.Core.Services
|
||||
private List<Module> _modules;
|
||||
|
||||
// ReSharper disable once UnusedParameter.Local - Storage migration service is injected early to ensure it runs before anything else
|
||||
public CoreService(IKernel kernel, ILogger logger, StorageMigrationService _, ISettingsService settingsService, IPluginService pluginService,
|
||||
public CoreService(IKernel kernel, ILogger logger, StorageMigrationService _, ISettingsService settingsService, IPluginManagementService pluginManagementService,
|
||||
IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService, IModuleService moduleService)
|
||||
{
|
||||
Kernel = kernel;
|
||||
Constants.CorePluginInfo.Kernel = kernel;
|
||||
|
||||
_logger = logger;
|
||||
_pluginService = pluginService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_rgbService = rgbService;
|
||||
_surfaceService = surfaceService;
|
||||
_profileService = profileService;
|
||||
@@ -57,8 +57,8 @@ namespace Artemis.Core.Services
|
||||
_rgbService.Surface.Updated += SurfaceOnUpdated;
|
||||
_loggingLevel.SettingChanged += (sender, args) => ApplyLoggingLevel();
|
||||
|
||||
_pluginService.PluginEnabled += (sender, args) => UpdatePluginCache();
|
||||
_pluginService.PluginDisabled += (sender, args) => UpdatePluginCache();
|
||||
_pluginManagementService.PluginEnabled += (sender, args) => UpdatePluginCache();
|
||||
_pluginManagementService.PluginDisabled += (sender, args) => UpdatePluginCache();
|
||||
}
|
||||
|
||||
public TimeSpan FrameTime { get; private set; }
|
||||
@@ -68,7 +68,7 @@ namespace Artemis.Core.Services
|
||||
public void Dispose()
|
||||
{
|
||||
// Dispose services
|
||||
_pluginService.Dispose();
|
||||
_pluginManagementService.Dispose();
|
||||
}
|
||||
|
||||
public bool IsInitialized { get; set; }
|
||||
@@ -85,8 +85,8 @@ namespace Artemis.Core.Services
|
||||
DeserializationLogger.Initialize(Kernel);
|
||||
|
||||
// Initialize the services
|
||||
_pluginService.CopyBuiltInPlugins();
|
||||
_pluginService.LoadPlugins(StartupArguments.Contains("--ignore-plugin-lock"));
|
||||
_pluginManagementService.CopyBuiltInPlugins();
|
||||
_pluginManagementService.LoadPlugins(StartupArguments.Contains("--ignore-plugin-lock"));
|
||||
|
||||
ArtemisSurface surfaceConfig = _surfaceService.ActiveSurface;
|
||||
if (surfaceConfig != null)
|
||||
@@ -133,8 +133,8 @@ namespace Artemis.Core.Services
|
||||
|
||||
private void UpdatePluginCache()
|
||||
{
|
||||
_modules = _pluginService.GetPluginsOfType<Module>().Where(p => p.IsEnabled).ToList();
|
||||
_dataModelExpansions = _pluginService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled).ToList();
|
||||
_modules = _pluginManagementService.GetPluginsOfType<Module>().Where(p => p.IsEnabled).ToList();
|
||||
_dataModelExpansions = _pluginManagementService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled).ToList();
|
||||
}
|
||||
|
||||
private void ConfigureJsonConvert()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using RGB.NET.Core;
|
||||
|
||||
@@ -8,7 +9,7 @@ namespace Artemis.Core.Services
|
||||
/// <summary>
|
||||
/// A service providing plugin management
|
||||
/// </summary>
|
||||
public interface IPluginService : IArtemisService, IDisposable
|
||||
public interface IPluginManagementService : IArtemisService, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether or not plugins are currently being loaded
|
||||
@@ -35,7 +36,7 @@ namespace Artemis.Core.Services
|
||||
/// Loads the plugin defined in the provided <see cref="PluginInfo" />
|
||||
/// </summary>
|
||||
/// <param name="pluginInfo">The plugin info defining the plugin to load</param>
|
||||
void LoadPlugin(PluginInfo pluginInfo);
|
||||
void LoadPlugin(DirectoryInfo pluginInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Unloads the plugin defined in the provided <see cref="PluginInfo" />
|
||||
@@ -48,13 +49,13 @@ namespace Artemis.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="pluginImplementation"></param>
|
||||
/// <param name="isAutoEnable">If true, fails if there is a lock file present</param>
|
||||
void EnablePlugin(PluginImplementation pluginImplementation, bool isAutoEnable = false);
|
||||
void EnablePluginImplementation(PluginImplementation pluginImplementation, bool isAutoEnable = false);
|
||||
|
||||
/// <summary>
|
||||
/// Disables the provided plugin
|
||||
/// </summary>
|
||||
/// <param name="pluginImplementation"></param>
|
||||
void DisablePlugin(PluginImplementation pluginImplementation);
|
||||
void DisablePluginImplementation(PluginImplementation pluginImplementation);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the plugin info related to the plugin
|
||||
|
||||
@@ -17,22 +17,22 @@ namespace Artemis.Core.Services
|
||||
private static readonly SemaphoreSlim ActiveModuleSemaphore = new SemaphoreSlim(1, 1);
|
||||
private readonly ILogger _logger;
|
||||
private readonly IModuleRepository _moduleRepository;
|
||||
private readonly IPluginService _pluginService;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly IProfileService _profileService;
|
||||
|
||||
public ModuleService(ILogger logger, IModuleRepository moduleRepository, IPluginService pluginService, IProfileService profileService)
|
||||
public ModuleService(ILogger logger, IModuleRepository moduleRepository, IPluginManagementService pluginManagementService, IProfileService profileService)
|
||||
{
|
||||
_logger = logger;
|
||||
_moduleRepository = moduleRepository;
|
||||
_pluginService = pluginService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_profileService = profileService;
|
||||
_pluginService.PluginEnabled += PluginServiceOnPluginEnabled;
|
||||
_pluginManagementService.PluginEnabled += PluginManagementServiceOnPluginManagementEnabled;
|
||||
|
||||
Timer activationUpdateTimer = new Timer(2000);
|
||||
activationUpdateTimer.Start();
|
||||
activationUpdateTimer.Elapsed += ActivationUpdateTimerOnElapsed;
|
||||
|
||||
foreach (Module module in _pluginService.GetPluginsOfType<Module>())
|
||||
foreach (Module module in _pluginManagementService.GetPluginsOfType<Module>())
|
||||
InitialiseOrApplyPriority(module);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Artemis.Core.Services
|
||||
_logger.Information("Clearing active module override");
|
||||
|
||||
// Always deactivate all other modules whenever override is called
|
||||
List<Module> modules = _pluginService.GetPluginsOfType<Module>().ToList();
|
||||
List<Module> modules = _pluginManagementService.GetPluginsOfType<Module>().ToList();
|
||||
foreach (Module module in modules.Where(m => m != overrideModule))
|
||||
OverrideDeactivate(module, overrideModule != null);
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace Artemis.Core.Services
|
||||
Stopwatch stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
List<Module> modules = _pluginService.GetPluginsOfType<Module>().ToList();
|
||||
List<Module> modules = _pluginManagementService.GetPluginsOfType<Module>().ToList();
|
||||
List<Task> tasks = new List<Task>();
|
||||
foreach (Module module in modules)
|
||||
{
|
||||
@@ -128,7 +128,7 @@ namespace Artemis.Core.Services
|
||||
if (module.PriorityCategory == category && module.Priority == priority)
|
||||
return;
|
||||
|
||||
List<Module> modules = _pluginService.GetPluginsOfType<Module>().Where(m => m.PriorityCategory == category).OrderBy(m => m.Priority).ToList();
|
||||
List<Module> modules = _pluginManagementService.GetPluginsOfType<Module>().Where(m => m.PriorityCategory == category).OrderBy(m => m.Priority).ToList();
|
||||
if (modules.Contains(module))
|
||||
modules.Remove(module);
|
||||
|
||||
@@ -234,9 +234,9 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
|
||||
private void PluginManagementServiceOnPluginManagementEnabled(object sender, PluginEventArgs e)
|
||||
{
|
||||
if (e.PluginInfo.Instance is Module module)
|
||||
if (e.PluginInfo.Plugin is Module module)
|
||||
InitialiseOrApplyPriority(module);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,19 +22,19 @@ namespace Artemis.Core.Services
|
||||
/// <summary>
|
||||
/// Provides access to plugin loading and unloading
|
||||
/// </summary>
|
||||
internal class PluginService : IPluginService
|
||||
internal class PluginManagementService : IPluginManagementService
|
||||
{
|
||||
private readonly IKernel _kernel;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IPluginRepository _pluginRepository;
|
||||
private readonly List<PluginInfo> _plugins;
|
||||
private readonly List<Plugin> _plugins;
|
||||
|
||||
public PluginService(IKernel kernel, ILogger logger, IPluginRepository pluginRepository)
|
||||
public PluginManagementService(IKernel kernel, ILogger logger, IPluginRepository pluginRepository)
|
||||
{
|
||||
_kernel = kernel;
|
||||
_logger = logger;
|
||||
_pluginRepository = pluginRepository;
|
||||
_plugins = new List<PluginInfo>();
|
||||
_plugins = new List<Plugin>();
|
||||
|
||||
// Ensure the plugins directory exists
|
||||
if (!Directory.Exists(Constants.DataFolder + "plugins"))
|
||||
@@ -43,6 +43,8 @@ namespace Artemis.Core.Services
|
||||
|
||||
public bool LoadingPlugins { get; private set; }
|
||||
|
||||
#region Built in plugins
|
||||
|
||||
public void CopyBuiltInPlugins()
|
||||
{
|
||||
OnCopyingBuildInPlugins();
|
||||
@@ -101,6 +103,10 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Plugins
|
||||
|
||||
public void LoadPlugins(bool ignorePluginLock)
|
||||
{
|
||||
if (LoadingPlugins)
|
||||
@@ -119,15 +125,7 @@ namespace Artemis.Core.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
// Load the metadata
|
||||
string metadataFile = Path.Combine(subDirectory.FullName, "plugin.json");
|
||||
if (!File.Exists(metadataFile)) _logger.Warning(new ArtemisPluginException("Couldn't find the plugins metadata file at " + metadataFile), "Plugin exception");
|
||||
|
||||
// Locate the main entry
|
||||
PluginInfo pluginInfo = JsonConvert.DeserializeObject<PluginInfo>(File.ReadAllText(metadataFile));
|
||||
pluginInfo.Directory = subDirectory;
|
||||
|
||||
LoadPlugin(pluginInfo);
|
||||
LoadPlugin(subDirectory);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -136,15 +134,18 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
|
||||
// Activate plugins after they are all loaded
|
||||
foreach (PluginInfo pluginInfo in _plugins.Where(p => p.IsEnabled))
|
||||
foreach (Plugin plugin in _plugins.Where(p => p.Entity.IsEnabled))
|
||||
{
|
||||
try
|
||||
foreach (PluginImplementation pluginImplementation in plugin.Implementations.Where(i => i.Entity.IsEnabled))
|
||||
{
|
||||
EnablePlugin(pluginInfo.Instance, !ignorePluginLock);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored, logged in EnablePlugin
|
||||
try
|
||||
{
|
||||
EnablePluginImplementation(pluginImplementation, !ignorePluginLock);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored, logged in EnablePlugin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,30 +165,37 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadPlugin(PluginInfo pluginInfo)
|
||||
public void LoadPlugin(DirectoryInfo pluginDirectory)
|
||||
{
|
||||
lock (_plugins)
|
||||
{
|
||||
_logger.Debug("Loading plugin {pluginInfo}", pluginInfo);
|
||||
OnPluginLoading(new PluginEventArgs(pluginInfo));
|
||||
_logger.Debug("Loading plugin from {directory}", pluginDirectory.FullName);
|
||||
|
||||
// Unload the plugin first if it is already loaded
|
||||
if (_plugins.Contains(pluginInfo))
|
||||
UnloadPlugin(pluginInfo);
|
||||
// Load the metadata
|
||||
string metadataFile = Path.Combine(pluginDirectory.FullName, "plugin.json");
|
||||
if (!File.Exists(metadataFile))
|
||||
_logger.Warning(new ArtemisPluginException("Couldn't find the plugins metadata file at " + metadataFile), "Plugin exception");
|
||||
|
||||
PluginEntity pluginEntity = _pluginRepository.GetPluginByGuid(pluginInfo.Guid);
|
||||
if (pluginEntity == null)
|
||||
pluginEntity = new PluginEntity {Id = pluginInfo.Guid, IsEnabled = true};
|
||||
// PluginInfo contains the ID which we need to move on
|
||||
PluginInfo pluginInfo = JsonConvert.DeserializeObject<PluginInfo>(File.ReadAllText(metadataFile));
|
||||
|
||||
pluginInfo.PluginEntity = pluginEntity;
|
||||
pluginInfo.IsEnabled = pluginEntity.IsEnabled;
|
||||
// Ensure the plugin is not already loaded
|
||||
if (_plugins.Any(p => p.Guid == pluginInfo.Guid))
|
||||
throw new ArtemisCoreException("Cannot load a plugin that is already loaded");
|
||||
|
||||
string mainFile = Path.Combine(pluginInfo.Directory.FullName, pluginInfo.Main);
|
||||
Plugin plugin = new Plugin(pluginInfo, pluginDirectory);
|
||||
OnPluginLoading(new PluginEventArgs(plugin));
|
||||
|
||||
// Load the entity and fall back on creating a new one
|
||||
plugin.Entity = _pluginRepository.GetPluginByGuid(pluginInfo.Guid) ?? new PluginEntity { Id = plugin.Guid, IsEnabled = true };
|
||||
|
||||
// Locate the main assembly entry
|
||||
string? mainFile = plugin.ResolveRelativePath(plugin.Info.Main);
|
||||
if (!File.Exists(mainFile))
|
||||
throw new ArtemisPluginException(pluginInfo, "Couldn't find the plugins main entry at " + mainFile);
|
||||
throw new ArtemisPluginException(plugin, "Couldn't find the plugins main entry at " + mainFile);
|
||||
|
||||
// Load the plugin, all types implementing Plugin and register them with DI
|
||||
pluginInfo.PluginLoader = PluginLoader.CreateFromAssemblyFile(mainFile, configure =>
|
||||
plugin.PluginLoader = PluginLoader.CreateFromAssemblyFile(mainFile!, configure =>
|
||||
{
|
||||
configure.IsUnloadable = true;
|
||||
configure.PreferSharedTypes = true;
|
||||
@@ -195,57 +203,58 @@ namespace Artemis.Core.Services
|
||||
|
||||
try
|
||||
{
|
||||
pluginInfo.Assembly = pluginInfo.PluginLoader.LoadDefaultAssembly();
|
||||
plugin.Assembly = plugin.PluginLoader.LoadDefaultAssembly();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ArtemisPluginException(pluginInfo, "Failed to load the plugins assembly", e);
|
||||
throw new ArtemisPluginException(plugin, "Failed to load the plugins assembly", e);
|
||||
}
|
||||
|
||||
// Get the Plugin implementation from the main assembly and if there is only one, instantiate it
|
||||
List<Type> pluginTypes;
|
||||
List<Type> implementationTypes;
|
||||
try
|
||||
{
|
||||
pluginTypes = pluginInfo.Assembly.GetTypes().Where(t => typeof(PluginImplementation).IsAssignableFrom(t)).ToList();
|
||||
implementationTypes = plugin.Assembly.GetTypes().Where(t => typeof(PluginImplementation).IsAssignableFrom(t)).ToList();
|
||||
}
|
||||
catch (ReflectionTypeLoadException e)
|
||||
{
|
||||
throw new ArtemisPluginException(pluginInfo, "Failed to initialize the plugin assembly", new AggregateException(e.LoaderExceptions));
|
||||
throw new ArtemisPluginException(plugin, "Failed to initialize the plugin assembly", new AggregateException(e.LoaderExceptions));
|
||||
}
|
||||
|
||||
if (pluginTypes.Count > 1)
|
||||
throw new ArtemisPluginException(pluginInfo, $"Plugin contains {pluginTypes.Count} implementations of Plugin, only 1 allowed");
|
||||
if (pluginTypes.Count == 0)
|
||||
throw new ArtemisPluginException(pluginInfo, "Plugin contains no implementation of Plugin");
|
||||
// Create the Ninject child kernel and load the module
|
||||
plugin.Kernel = new ChildKernel(_kernel);
|
||||
plugin.Kernel.Load(new PluginModule(pluginInfo));
|
||||
|
||||
Type pluginType = pluginTypes.Single();
|
||||
try
|
||||
if (!implementationTypes.Any())
|
||||
_logger.Warning("Plugin {plugin} contains no implementations", plugin);
|
||||
|
||||
// Create instances of each implementation and add them to the plugin
|
||||
// Construction should be simple and not contain any logic so failure at this point means the entire plugin fails
|
||||
foreach (Type implementationType in implementationTypes)
|
||||
{
|
||||
IParameter[] parameters = {
|
||||
new Parameter("PluginInfo", pluginInfo, false)
|
||||
};
|
||||
pluginInfo.Kernel = new ChildKernel(_kernel);
|
||||
pluginInfo.Kernel.Load(new PluginModule(pluginInfo));
|
||||
pluginInfo.Instance = (PluginImplementation) pluginInfo.Kernel.Get(pluginType, constraint: null, parameters: parameters);
|
||||
pluginInfo.Instance.PluginInfo = pluginInfo;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ArtemisPluginException(pluginInfo, "Failed to instantiate the plugin", e);
|
||||
try
|
||||
{
|
||||
PluginImplementation instance = (PluginImplementation)plugin.Kernel.Get(implementationType);
|
||||
plugin.AddImplementation(instance);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ArtemisPluginException(plugin, "Failed to load instantiate implementation", e);
|
||||
}
|
||||
}
|
||||
|
||||
_plugins.Add(pluginInfo);
|
||||
OnPluginLoaded(new PluginEventArgs(pluginInfo));
|
||||
_plugins.Add(plugin);
|
||||
OnPluginLoaded(new PluginEventArgs(plugin));
|
||||
}
|
||||
}
|
||||
|
||||
public void UnloadPlugin(PluginInfo pluginInfo)
|
||||
public void UnloadPlugin(Plugin plugin)
|
||||
{
|
||||
lock (_plugins)
|
||||
{
|
||||
try
|
||||
{
|
||||
pluginInfo.Instance.SetEnabled(false);
|
||||
plugin.SetEnabled(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -253,23 +262,24 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
finally
|
||||
{
|
||||
OnPluginDisabled(new PluginEventArgs(pluginInfo));
|
||||
OnPluginDisabled(new PluginEventArgs(plugin));
|
||||
}
|
||||
|
||||
pluginInfo.Instance.Dispose();
|
||||
pluginInfo.PluginLoader.Dispose();
|
||||
pluginInfo.Kernel.Dispose();
|
||||
plugin.Dispose();
|
||||
_plugins.Remove(plugin);
|
||||
|
||||
_plugins.Remove(pluginInfo);
|
||||
|
||||
OnPluginUnloaded(new PluginEventArgs(pluginInfo));
|
||||
OnPluginUnloaded(new PluginEventArgs(plugin));
|
||||
}
|
||||
}
|
||||
|
||||
public void EnablePlugin(PluginImplementation pluginImplementation, bool isAutoEnable = false)
|
||||
#endregion
|
||||
|
||||
|
||||
#region Implementations
|
||||
|
||||
public void EnablePluginImplementation(PluginImplementation pluginImplementation, bool isAutoEnable = false)
|
||||
{
|
||||
_logger.Debug("Enabling plugin {pluginInfo}", pluginImplementation.PluginInfo);
|
||||
OnPluginEnabling(new PluginEventArgs(pluginImplementation.PluginInfo));
|
||||
_logger.Debug("Enabling plugin implementation {implementation} - {plugin}", pluginImplementation, pluginImplementation.Plugin);
|
||||
|
||||
lock (_plugins)
|
||||
{
|
||||
@@ -306,10 +316,10 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
OnPluginEnabled(new PluginEventArgs(pluginImplementation.PluginInfo));
|
||||
OnPluginImplementationEnabled(new PluginImplementationEventArgs(pluginImplementation));
|
||||
}
|
||||
|
||||
public void DisablePlugin(PluginImplementation pluginImplementation)
|
||||
public void DisablePluginImplementation(PluginImplementation pluginImplementation)
|
||||
{
|
||||
lock (_plugins)
|
||||
{
|
||||
@@ -335,9 +345,12 @@ namespace Artemis.Core.Services
|
||||
OnPluginDisabled(new PluginEventArgs(pluginImplementation.PluginInfo));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public PluginInfo GetPluginInfo(PluginImplementation pluginImplementation)
|
||||
{
|
||||
return _plugins.FirstOrDefault(p => p.Instance == pluginImplementation);
|
||||
return _plugins.FirstOrDefault(p => p.Plugin == pluginImplementation);
|
||||
}
|
||||
|
||||
public List<PluginInfo> GetAllPluginInfo()
|
||||
@@ -347,12 +360,12 @@ namespace Artemis.Core.Services
|
||||
|
||||
public List<T> GetPluginsOfType<T>() where T : PluginImplementation
|
||||
{
|
||||
return _plugins.Where(p => p.IsEnabled && p.Instance is T).Select(p => (T) p.Instance).ToList();
|
||||
return _plugins.Where(p => p.IsEnabled && p.Plugin is T).Select(p => (T) p.Plugin).ToList();
|
||||
}
|
||||
|
||||
public PluginImplementation GetPluginByAssembly(Assembly assembly)
|
||||
{
|
||||
return _plugins.FirstOrDefault(p => p.Assembly == assembly)?.Instance;
|
||||
return _plugins.FirstOrDefault(p => p.Assembly == assembly)?.Plugin;
|
||||
}
|
||||
|
||||
public PluginImplementation GetPluginByDevice(IRGBDevice rgbDevice)
|
||||
@@ -362,8 +375,8 @@ namespace Artemis.Core.Services
|
||||
|
||||
public PluginImplementation GetCallingPlugin()
|
||||
{
|
||||
StackTrace stackTrace = new StackTrace(); // get call stack
|
||||
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||
StackTrace stackTrace = new StackTrace(); // get call stack
|
||||
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||
|
||||
foreach (StackFrame stackFrame in stackFrames)
|
||||
{
|
||||
@@ -395,7 +408,7 @@ namespace Artemis.Core.Services
|
||||
if (createLockFile)
|
||||
File.Create(Path.Combine(pluginDirectory.FullName, "artemis.lock")).Close();
|
||||
}
|
||||
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler CopyingBuildInPlugins;
|
||||
@@ -406,6 +419,9 @@ namespace Artemis.Core.Services
|
||||
public event EventHandler<PluginEventArgs> PluginEnabled;
|
||||
public event EventHandler<PluginEventArgs> PluginDisabled;
|
||||
|
||||
public event EventHandler<PluginImplementationEventArgs> PluginImplementationEnabled;
|
||||
public event EventHandler<PluginImplementationEventArgs> PluginImplementationDisabled;
|
||||
|
||||
protected virtual void OnCopyingBuildInPlugins()
|
||||
{
|
||||
CopyingBuildInPlugins?.Invoke(this, EventArgs.Empty);
|
||||
@@ -441,6 +457,16 @@ namespace Artemis.Core.Services
|
||||
PluginDisabled?.Invoke(this, e);
|
||||
}
|
||||
|
||||
protected virtual void OnPluginImplementationDisabled(PluginImplementationEventArgs e)
|
||||
{
|
||||
PluginImplementationDisabled?.Invoke(this, e);
|
||||
}
|
||||
|
||||
protected virtual void OnPluginImplementationEnabled(PluginImplementationEventArgs e)
|
||||
{
|
||||
PluginImplementationEnabled?.Invoke(this, e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -8,16 +8,16 @@ namespace Artemis.Core.Services
|
||||
{
|
||||
internal class DataModelService : IDataModelService
|
||||
{
|
||||
public DataModelService(IPluginService pluginService)
|
||||
public DataModelService(IPluginManagementService pluginManagementService)
|
||||
{
|
||||
// Add data models of already loaded plugins
|
||||
foreach (Module module in pluginService.GetPluginsOfType<Module>().Where(p => p.IsEnabled))
|
||||
foreach (Module module in pluginManagementService.GetPluginsOfType<Module>().Where(p => p.IsEnabled))
|
||||
AddModuleDataModel(module);
|
||||
foreach (BaseDataModelExpansion dataModelExpansion in pluginService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
||||
foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
||||
AddDataModelExpansionDataModel(dataModelExpansion);
|
||||
|
||||
// Add data models of new plugins when they get enabled
|
||||
pluginService.PluginEnabled += PluginServiceOnPluginEnabled;
|
||||
pluginManagementService.PluginEnabled += PluginServiceOnPluginEnabled;
|
||||
}
|
||||
|
||||
public DataModelRegistration RegisterDataModel(DataModel dataModel)
|
||||
@@ -56,9 +56,9 @@ namespace Artemis.Core.Services
|
||||
|
||||
private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
|
||||
{
|
||||
if (e.PluginInfo.Instance is Module module)
|
||||
if (e.PluginInfo.Plugin is Module module)
|
||||
AddModuleDataModel(module);
|
||||
else if (e.PluginInfo.Instance is BaseDataModelExpansion dataModelExpansion)
|
||||
else if (e.PluginInfo.Plugin is BaseDataModelExpansion dataModelExpansion)
|
||||
AddDataModelExpansionDataModel(dataModelExpansion);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,19 +13,19 @@ namespace Artemis.Core.Services
|
||||
internal class ProfileService : IProfileService
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IPluginService _pluginService;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly IProfileRepository _profileRepository;
|
||||
private readonly ISurfaceService _surfaceService;
|
||||
|
||||
internal ProfileService(ILogger logger,
|
||||
IPluginService pluginService,
|
||||
IPluginManagementService pluginManagementService,
|
||||
ISurfaceService surfaceService,
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
IDataBindingService dataBindingService,
|
||||
IProfileRepository profileRepository)
|
||||
{
|
||||
_logger = logger;
|
||||
_pluginService = pluginService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_surfaceService = surfaceService;
|
||||
_profileRepository = profileRepository;
|
||||
|
||||
@@ -118,15 +118,15 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
|
||||
// This could happen during activation so subscribe to it
|
||||
_pluginService.PluginEnabled += ActivatingProfilePluginToggle;
|
||||
_pluginService.PluginDisabled += ActivatingProfilePluginToggle;
|
||||
_pluginManagementService.PluginEnabled += ActivatingProfilePluginToggle;
|
||||
_pluginManagementService.PluginDisabled += ActivatingProfilePluginToggle;
|
||||
_surfaceService.SurfaceConfigurationUpdated += ActivatingProfileSurfaceUpdate;
|
||||
|
||||
await profileDescriptor.ProfileModule.ChangeActiveProfileAnimated(profile, _surfaceService.ActiveSurface);
|
||||
SaveActiveProfile(profileDescriptor.ProfileModule);
|
||||
|
||||
_pluginService.PluginEnabled -= ActivatingProfilePluginToggle;
|
||||
_pluginService.PluginDisabled -= ActivatingProfilePluginToggle;
|
||||
_pluginManagementService.PluginEnabled -= ActivatingProfilePluginToggle;
|
||||
_pluginManagementService.PluginDisabled -= ActivatingProfilePluginToggle;
|
||||
_surfaceService.SurfaceConfigurationUpdated -= ActivatingProfileSurfaceUpdate;
|
||||
|
||||
return profile;
|
||||
@@ -285,7 +285,7 @@ namespace Artemis.Core.Services
|
||||
/// <param name="surface"></param>
|
||||
private void ActiveProfilesPopulateLeds(ArtemisSurface surface)
|
||||
{
|
||||
List<ProfileModule> profileModules = _pluginService.GetPluginsOfType<ProfileModule>();
|
||||
List<ProfileModule> profileModules = _pluginManagementService.GetPluginsOfType<ProfileModule>();
|
||||
foreach (ProfileModule profileModule in profileModules.Where(p => p.ActiveProfile != null).ToList())
|
||||
profileModule.ActiveProfile.PopulateLeds(surface);
|
||||
}
|
||||
|
||||
@@ -12,18 +12,18 @@ namespace Artemis.Core.Services
|
||||
internal class SurfaceService : ISurfaceService
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IPluginService _pluginService;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly PluginSetting<double> _renderScaleSetting;
|
||||
private readonly IRgbService _rgbService;
|
||||
private readonly List<ArtemisSurface> _surfaceConfigurations;
|
||||
private readonly ISurfaceRepository _surfaceRepository;
|
||||
|
||||
public SurfaceService(ILogger logger, ISurfaceRepository surfaceRepository, IRgbService rgbService, IPluginService pluginService, ISettingsService settingsService)
|
||||
public SurfaceService(ILogger logger, ISurfaceRepository surfaceRepository, IRgbService rgbService, IPluginManagementService pluginManagementService, ISettingsService settingsService)
|
||||
{
|
||||
_logger = logger;
|
||||
_surfaceRepository = surfaceRepository;
|
||||
_rgbService = rgbService;
|
||||
_pluginService = pluginService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_surfaceConfigurations = new List<ArtemisSurface>();
|
||||
_renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.5);
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Artemis.Core.Services
|
||||
// Add all current devices
|
||||
foreach (IRGBDevice rgbDevice in _rgbService.LoadedDevices)
|
||||
{
|
||||
PluginImplementation pluginImplementation = _pluginService.GetPluginByDevice(rgbDevice);
|
||||
PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(rgbDevice);
|
||||
configuration.Devices.Add(new ArtemisDevice(rgbDevice, pluginImplementation, configuration));
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace Artemis.Core.Services
|
||||
IRGBDevice device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceIdentifier() == position.DeviceIdentifier);
|
||||
if (device != null)
|
||||
{
|
||||
PluginImplementation pluginImplementation = _pluginService.GetPluginByDevice(device);
|
||||
PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(device);
|
||||
surfaceConfiguration.Devices.Add(new ArtemisDevice(device, pluginImplementation, surfaceConfiguration, position));
|
||||
}
|
||||
}
|
||||
@@ -178,7 +178,7 @@ namespace Artemis.Core.Services
|
||||
DeviceEntity existingDeviceConfig = surface.SurfaceEntity.DeviceEntities.FirstOrDefault(d => d.DeviceIdentifier == deviceIdentifier);
|
||||
if (existingDeviceConfig != null)
|
||||
{
|
||||
PluginImplementation pluginImplementation = _pluginService.GetPluginByDevice(rgbDevice);
|
||||
PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(rgbDevice);
|
||||
device = new ArtemisDevice(rgbDevice, pluginImplementation, surface, existingDeviceConfig);
|
||||
}
|
||||
// Fall back on creating a new device
|
||||
@@ -189,7 +189,7 @@ namespace Artemis.Core.Services
|
||||
rgbDevice.DeviceInfo,
|
||||
deviceIdentifier
|
||||
);
|
||||
PluginImplementation pluginImplementation = _pluginService.GetPluginByDevice(rgbDevice);
|
||||
PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(rgbDevice);
|
||||
device = new ArtemisDevice(rgbDevice, pluginImplementation, surface);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user