mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Added plugin unloading
This commit is contained in:
parent
dba48a2b6a
commit
cdda228713
@ -1,5 +1,4 @@
|
|||||||
using Artemis.Core.Plugins.Interfaces;
|
using Artemis.Core.Plugins.Interfaces;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core.Plugins.Abstract
|
namespace Artemis.Core.Plugins.Abstract
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using Artemis.Core.Plugins.Interfaces;
|
using Artemis.Core.Plugins.Interfaces;
|
||||||
using Artemis.Core.Plugins.Models;
|
|
||||||
using Stylet;
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.Core.Plugins.Abstract
|
namespace Artemis.Core.Plugins.Abstract
|
||||||
|
|||||||
@ -17,11 +17,6 @@ namespace Artemis.Core.Plugins.Abstract
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public abstract bool ExpandsMainDataModel { get; }
|
public abstract bool ExpandsMainDataModel { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void EnablePlugin()
|
|
||||||
{
|
|
||||||
// Load and activate the last active profile
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual void Update(double deltaTime)
|
public virtual void Update(double deltaTime)
|
||||||
@ -47,9 +42,13 @@ namespace Artemis.Core.Plugins.Abstract
|
|||||||
public abstract IScreen GetMainViewModel();
|
public abstract IScreen GetMainViewModel();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public abstract void EnablePlugin();
|
||||||
{
|
|
||||||
}
|
/// <inheritdoc />
|
||||||
|
public abstract void DisablePlugin();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract void Dispose();
|
||||||
|
|
||||||
public void ChangeActiveProfile(Profile profile)
|
public void ChangeActiveProfile(Profile profile)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,14 +2,21 @@
|
|||||||
|
|
||||||
namespace Artemis.Core.Plugins.Interfaces
|
namespace Artemis.Core.Plugins.Interfaces
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the base plugin type, use the other interfaces such as IModule to create plugins
|
/// This is the base plugin type, use the other interfaces such as IModule to create plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPlugin : IDisposable
|
public interface IPlugin : IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the plugin is loaded
|
/// Called when the plugin is activated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void EnablePlugin();
|
void EnablePlugin();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the plugin is deactivated
|
||||||
|
/// </summary>
|
||||||
|
void DisablePlugin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using AppDomainToolkit;
|
using AppDomainToolkit;
|
||||||
using Artemis.Core.Plugins.Interfaces;
|
using Artemis.Core.Plugins.Interfaces;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -7,6 +8,10 @@ namespace Artemis.Core.Plugins.Models
|
|||||||
{
|
{
|
||||||
public class PluginInfo
|
public class PluginInfo
|
||||||
{
|
{
|
||||||
|
internal PluginInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The plugins GUID
|
/// The plugins GUID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -28,10 +33,10 @@ namespace Artemis.Core.Plugins.Models
|
|||||||
public string Main { get; set; }
|
public string Main { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Full path to the plugin's current folder
|
/// The plugins root directory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string Folder { get; set; }
|
public DirectoryInfo Directory { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A reference to the type implementing IPlugin, available after successful load
|
/// A reference to the type implementing IPlugin, available after successful load
|
||||||
@ -48,6 +53,7 @@ namespace Artemis.Core.Plugins.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The AppDomain context of this plugin
|
/// The AppDomain context of this plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
internal AppDomainContext<AssemblyTargetLoader, PathBasedAssemblyResolver> Context { get; set; }
|
internal AppDomainContext<AssemblyTargetLoader, PathBasedAssemblyResolver> Context { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|||||||
@ -61,12 +61,10 @@ namespace Artemis.Core.ProfileElements
|
|||||||
public void UpdateLayerType(ILayerType layerType)
|
public void UpdateLayerType(ILayerType layerType)
|
||||||
{
|
{
|
||||||
if (LayerType != null)
|
if (LayerType != null)
|
||||||
{
|
|
||||||
lock (LayerType)
|
lock (LayerType)
|
||||||
{
|
{
|
||||||
LayerType.Dispose();
|
LayerType.Dispose();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LayerType = layerType;
|
LayerType = layerType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core.Exceptions;
|
using Artemis.Core.Exceptions;
|
||||||
using Artemis.Core.Plugins.Interfaces;
|
using Artemis.Core.Plugins.Interfaces;
|
||||||
@ -38,7 +37,7 @@ namespace Artemis.Core.Services
|
|||||||
throw new ArtemisCoreException("Cannot initialize the core as it is already initialized.");
|
throw new ArtemisCoreException("Cannot initialize the core as it is already initialized.");
|
||||||
|
|
||||||
// Initialize the services
|
// Initialize the services
|
||||||
await _pluginService.LoadPlugins();
|
await Task.Run(() => _pluginService.LoadPlugins());
|
||||||
await _rgbService.LoadDevices();
|
await _rgbService.LoadDevices();
|
||||||
|
|
||||||
OnInitialized();
|
OnInitialized();
|
||||||
@ -48,7 +47,7 @@ namespace Artemis.Core.Services
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var modules = _pluginService.GetModules();
|
var modules = _pluginService.GetPluginsOfType<IModule>();
|
||||||
|
|
||||||
// Update all active modules
|
// Update all active modules
|
||||||
foreach (var module in modules)
|
foreach (var module in modules)
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Artemis.Core.Events;
|
using Artemis.Core.Events;
|
||||||
using Artemis.Core.Plugins.Interfaces;
|
using Artemis.Core.Plugins.Interfaces;
|
||||||
using Artemis.Core.Plugins.Models;
|
using Artemis.Core.Plugins.Models;
|
||||||
@ -11,46 +9,81 @@ namespace Artemis.Core.Services.Interfaces
|
|||||||
public interface IPluginService : IArtemisService, IDisposable
|
public interface IPluginService : IArtemisService, IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates wether or not plugins are currently being loaded
|
/// Indicates whether or not plugins are currently being loaded
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool LoadingPlugins { get; }
|
bool LoadingPlugins { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All loaded plugins
|
|
||||||
/// </summary>
|
|
||||||
ReadOnlyCollection<PluginInfo> Plugins { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads all installed plugins. If plugins already loaded this will reload them all
|
/// Loads all installed plugins. If plugins already loaded this will reload them all
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task LoadPlugins();
|
void LoadPlugins();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a single plugin has loaded
|
/// Unloads all installed plugins.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event EventHandler<PluginEventArgs> PluginLoaded;
|
void UnloadPlugins();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when loading all plugins has started
|
/// Loads the plugin defined in the provided <see cref="PluginInfo" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event EventHandler StartedLoadingPlugins;
|
/// <param name="pluginInfo">The plugin info defining the plugin to load</param>
|
||||||
|
void LoadPlugin(PluginInfo pluginInfo);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when loading all plugins has finished
|
/// Unloads the plugin defined in the provided <see cref="PluginInfo" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event EventHandler FinishedLoadedPlugins;
|
/// <param name="pluginInfo">The plugin info defining the plugin to unload</param>
|
||||||
|
void UnloadPlugin(PluginInfo pluginInfo);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If found, returns an instance of the layer type matching the given GUID
|
/// Finds the plugin info related to the plugin
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin">The plugin you want to find the plugin info for</param>
|
||||||
|
/// <returns>The plugins PluginInfo</returns>
|
||||||
|
PluginInfo GetPluginInfo(IPlugin plugin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the plugin info of all loaded plugins
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A list containing all the plugin info</returns>
|
||||||
|
List<PluginInfo> GetAllPluginInfo();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds an instance of the layer type matching the given GUID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="layerTypeGuid">The GUID of the layer type to find</param>
|
/// <param name="layerTypeGuid">The GUID of the layer type to find</param>
|
||||||
/// <returns>An instance of the layer type</returns>
|
/// <returns>An instance of the layer type</returns>
|
||||||
ILayerType GetLayerTypeByGuid(Guid layerTypeGuid);
|
ILayerType GetLayerTypeByGuid(Guid layerTypeGuid);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns all the plugins implementing <see cref="IModule" />
|
/// Finds all enabled <see cref="IPlugin" /> instances of type <see cref="T" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <typeparam name="T">Either <see cref="IPlugin" /> or a plugin type implementing <see cref="IPlugin" /></typeparam>
|
||||||
IReadOnlyList<IModule> GetModules();
|
/// <returns>Returns a list of plug instances of type <see cref="T" /></returns>
|
||||||
|
List<T> GetPluginsOfType<T>() where T : IPlugin;
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a plugin has loaded
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<PluginEventArgs> PluginLoaded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a plugin has been unloaded
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<PluginEventArgs> PluginUnloaded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a plugin has been enabled
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<PluginEventArgs> PluginEnabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a plugin has been disabled
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<PluginEventArgs> PluginDisabled;
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,9 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AppDomainToolkit;
|
using AppDomainToolkit;
|
||||||
using Artemis.Core.Events;
|
using Artemis.Core.Events;
|
||||||
using Artemis.Core.Exceptions;
|
using Artemis.Core.Exceptions;
|
||||||
@ -23,7 +21,7 @@ namespace Artemis.Core.Services
|
|||||||
private readonly List<PluginInfo> _plugins;
|
private readonly List<PluginInfo> _plugins;
|
||||||
private IKernel _childKernel;
|
private IKernel _childKernel;
|
||||||
|
|
||||||
public PluginService(IKernel kernel)
|
internal PluginService(IKernel kernel)
|
||||||
{
|
{
|
||||||
_kernel = kernel;
|
_kernel = kernel;
|
||||||
_plugins = new List<PluginInfo>();
|
_plugins = new List<PluginInfo>();
|
||||||
@ -32,19 +30,20 @@ namespace Artemis.Core.Services
|
|||||||
Directory.CreateDirectory(Constants.DataFolder + "plugins");
|
Directory.CreateDirectory(Constants.DataFolder + "plugins");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool LoadingPlugins { get; private set; }
|
public bool LoadingPlugins { get; private set; }
|
||||||
public ReadOnlyCollection<PluginInfo> Plugins => _plugins.AsReadOnly();
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task LoadPlugins()
|
public void LoadPlugins()
|
||||||
{
|
{
|
||||||
if (LoadingPlugins)
|
if (LoadingPlugins)
|
||||||
throw new ArtemisCoreException("Cannot load plugins while a previous load hasn't been completed yet.");
|
throw new ArtemisCoreException("Cannot load plugins while a previous load hasn't been completed yet.");
|
||||||
|
|
||||||
OnStartedLoadingPlugins();
|
lock (_plugins)
|
||||||
|
|
||||||
await Task.Run(() =>
|
|
||||||
{
|
{
|
||||||
|
LoadingPlugins = true;
|
||||||
|
|
||||||
|
// Unload all currently loaded plugins first
|
||||||
UnloadPlugins();
|
UnloadPlugins();
|
||||||
|
|
||||||
// Create a child kernel and app domain that will only contain the plugins
|
// Create a child kernel and app domain that will only contain the plugins
|
||||||
@ -53,6 +52,7 @@ namespace Artemis.Core.Services
|
|||||||
// Load the plugin assemblies into the plugin context
|
// Load the plugin assemblies into the plugin context
|
||||||
var directory = new DirectoryInfo(Path.Combine(Constants.DataFolder, "plugins"));
|
var directory = new DirectoryInfo(Path.Combine(Constants.DataFolder, "plugins"));
|
||||||
foreach (var subDirectory in directory.EnumerateDirectories())
|
foreach (var subDirectory in directory.EnumerateDirectories())
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Load the metadata
|
// Load the metadata
|
||||||
@ -62,61 +62,145 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
// Locate the main entry
|
// Locate the main entry
|
||||||
var pluginInfo = JsonConvert.DeserializeObject<PluginInfo>(File.ReadAllText(metadataFile));
|
var pluginInfo = JsonConvert.DeserializeObject<PluginInfo>(File.ReadAllText(metadataFile));
|
||||||
// TODO Just temporarily until settings are in place
|
pluginInfo.Directory = subDirectory;
|
||||||
pluginInfo.Enabled = true;
|
LoadPlugin(pluginInfo);
|
||||||
var mainFile = Path.Combine(subDirectory.FullName, pluginInfo.Main);
|
|
||||||
if (!File.Exists(mainFile))
|
|
||||||
throw new ArtemisPluginException(pluginInfo, "Couldn't find the plugins main entry at " + mainFile);
|
|
||||||
|
|
||||||
// Load the plugin, all types implementing IPlugin and register them with DI
|
|
||||||
var setupInfo = new AppDomainSetup
|
|
||||||
{
|
|
||||||
ApplicationName = pluginInfo.Guid.ToString(),
|
|
||||||
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
|
|
||||||
PrivateBinPath = subDirectory.FullName
|
|
||||||
};
|
|
||||||
pluginInfo.Context = AppDomainContext.Create(setupInfo);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pluginInfo.Context.LoadAssemblyWithReferences(LoadMethod.LoadFrom, mainFile);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new ArtemisPluginException(pluginInfo, "Failed to load the plugins assembly", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the IPlugin implementation from the main assembly and if there is only one, instantiate it
|
|
||||||
var mainAssembly = pluginInfo.Context.Domain.GetAssemblies().First(a => a.Location == mainFile);
|
|
||||||
var pluginTypes = mainAssembly.GetTypes().Where(t => typeof(IPlugin).IsAssignableFrom(t)).ToList();
|
|
||||||
if (pluginTypes.Count > 1)
|
|
||||||
throw new ArtemisPluginException(pluginInfo, $"Plugin contains {pluginTypes.Count} implementations of IPlugin, only 1 allowed");
|
|
||||||
if (pluginTypes.Count == 0)
|
|
||||||
throw new ArtemisPluginException(pluginInfo, "Plugin contains no implementation of IPlugin");
|
|
||||||
|
|
||||||
var pluginType = pluginTypes.Single();
|
|
||||||
_childKernel.Bind<IPlugin>().To(pluginType).InSingletonScope();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pluginInfo.Instance = (IPlugin) _childKernel.Get(pluginType);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new ArtemisPluginException(pluginInfo, "Failed to instantiate the plugin", e);
|
|
||||||
}
|
|
||||||
_plugins.Add(pluginInfo);
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new ArtemisPluginException("Failed to load plugin", e);
|
throw new ArtemisPluginException("Failed to load plugin", e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Activate plugins after they are all loaded
|
// Activate plugins after they are all loaded
|
||||||
foreach (var pluginInfo in _plugins.Where(p => p.Enabled))
|
foreach (var pluginInfo in _plugins.Where(p => p.Enabled))
|
||||||
|
{
|
||||||
pluginInfo.Instance.EnablePlugin();
|
pluginInfo.Instance.EnablePlugin();
|
||||||
});
|
OnPluginEnabled(new PluginEventArgs(pluginInfo));
|
||||||
|
}
|
||||||
|
|
||||||
OnFinishedLoadedPlugins();
|
LoadingPlugins = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void UnloadPlugins()
|
||||||
|
{
|
||||||
|
lock (_plugins)
|
||||||
|
{
|
||||||
|
// Unload all plugins
|
||||||
|
while (_plugins.Count > 0)
|
||||||
|
{
|
||||||
|
UnloadPlugin(_plugins[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispose the child kernel and therefore any leftover plugins instantiated with it
|
||||||
|
if (_childKernel != null)
|
||||||
|
{
|
||||||
|
_childKernel.Dispose();
|
||||||
|
_childKernel = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_plugins.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void LoadPlugin(PluginInfo pluginInfo)
|
||||||
|
{
|
||||||
|
lock (_plugins)
|
||||||
|
{
|
||||||
|
// Unload the plugin first if it is already loaded
|
||||||
|
if (_plugins.Contains(pluginInfo))
|
||||||
|
UnloadPlugin(pluginInfo);
|
||||||
|
|
||||||
|
// TODO Just temporarily until settings are in place
|
||||||
|
pluginInfo.Enabled = true;
|
||||||
|
var mainFile = Path.Combine(pluginInfo.Directory.FullName, pluginInfo.Main);
|
||||||
|
if (!File.Exists(mainFile))
|
||||||
|
throw new ArtemisPluginException(pluginInfo, "Couldn't find the plugins main entry at " + mainFile);
|
||||||
|
|
||||||
|
// Load the plugin, all types implementing IPlugin and register them with DI
|
||||||
|
var setupInfo = new AppDomainSetup
|
||||||
|
{
|
||||||
|
ApplicationName = pluginInfo.Guid.ToString(),
|
||||||
|
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
|
||||||
|
PrivateBinPath = pluginInfo.Directory.FullName
|
||||||
|
};
|
||||||
|
pluginInfo.Context = AppDomainContext.Create(setupInfo);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pluginInfo.Context.LoadAssemblyWithReferences(LoadMethod.LoadFrom, mainFile);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new ArtemisPluginException(pluginInfo, "Failed to load the plugins assembly", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the IPlugin implementation from the main assembly and if there is only one, instantiate it
|
||||||
|
var mainAssembly = pluginInfo.Context.Domain.GetAssemblies().First(a => a.Location == mainFile);
|
||||||
|
var pluginTypes = mainAssembly.GetTypes().Where(t => typeof(IPlugin).IsAssignableFrom(t)).ToList();
|
||||||
|
if (pluginTypes.Count > 1)
|
||||||
|
throw new ArtemisPluginException(pluginInfo, $"Plugin contains {pluginTypes.Count} implementations of IPlugin, only 1 allowed");
|
||||||
|
if (pluginTypes.Count == 0)
|
||||||
|
throw new ArtemisPluginException(pluginInfo, "Plugin contains no implementation of IPlugin");
|
||||||
|
|
||||||
|
var pluginType = pluginTypes.Single();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pluginInfo.Instance = (IPlugin) _childKernel.Get(pluginType);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new ArtemisPluginException(pluginInfo, "Failed to instantiate the plugin", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
_plugins.Add(pluginInfo);
|
||||||
|
OnPluginLoaded(new PluginEventArgs(pluginInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void UnloadPlugin(PluginInfo pluginInfo)
|
||||||
|
{
|
||||||
|
lock (_plugins)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pluginInfo.Instance.DisablePlugin();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// TODO: Log these
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
OnPluginDisabled(new PluginEventArgs(pluginInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
_childKernel.Unbind(pluginInfo.Instance.GetType());
|
||||||
|
|
||||||
|
pluginInfo.Instance.Dispose();
|
||||||
|
pluginInfo.Context.Dispose();
|
||||||
|
_plugins.Remove(pluginInfo);
|
||||||
|
|
||||||
|
OnPluginUnloaded(new PluginEventArgs(pluginInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public PluginInfo GetPluginInfo(IPlugin plugin)
|
||||||
|
{
|
||||||
|
lock (_plugins)
|
||||||
|
{
|
||||||
|
return _plugins.FirstOrDefault(p => p.Instance == plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public List<PluginInfo> GetAllPluginInfo()
|
||||||
|
{
|
||||||
|
return new List<PluginInfo>(_plugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -132,9 +216,13 @@ namespace Artemis.Core.Services
|
|||||||
return layerType;
|
return layerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<IModule> GetModules()
|
/// <inheritdoc />
|
||||||
|
public List<T> GetPluginsOfType<T>() where T : IPlugin
|
||||||
{
|
{
|
||||||
return Plugins.Where(p => p.Instance is IModule).Select(p => (IModule) p.Instance).ToList();
|
lock (_plugins)
|
||||||
|
{
|
||||||
|
return _plugins.Where(p => p.Enabled && p.Instance is T).Select(p => (T) p.Instance).ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@ -142,38 +230,32 @@ namespace Artemis.Core.Services
|
|||||||
UnloadPlugins();
|
UnloadPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnloadPlugins()
|
|
||||||
{
|
|
||||||
_plugins.Clear();
|
|
||||||
|
|
||||||
if (_childKernel != null)
|
|
||||||
{
|
|
||||||
_childKernel.Dispose();
|
|
||||||
_childKernel = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public event EventHandler<PluginEventArgs> PluginLoaded;
|
public event EventHandler<PluginEventArgs> PluginLoaded;
|
||||||
public event EventHandler StartedLoadingPlugins;
|
public event EventHandler<PluginEventArgs> PluginUnloaded;
|
||||||
public event EventHandler FinishedLoadedPlugins;
|
public event EventHandler<PluginEventArgs> PluginEnabled;
|
||||||
|
public event EventHandler<PluginEventArgs> PluginDisabled;
|
||||||
|
|
||||||
private void OnPluginLoaded(PluginEventArgs e)
|
protected virtual void OnPluginLoaded(PluginEventArgs e)
|
||||||
{
|
{
|
||||||
PluginLoaded?.Invoke(this, e);
|
PluginLoaded?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStartedLoadingPlugins()
|
protected virtual void OnPluginUnloaded(PluginEventArgs e)
|
||||||
{
|
{
|
||||||
LoadingPlugins = true;
|
PluginUnloaded?.Invoke(this, e);
|
||||||
StartedLoadingPlugins?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFinishedLoadedPlugins()
|
protected virtual void OnPluginEnabled(PluginEventArgs e)
|
||||||
{
|
{
|
||||||
LoadingPlugins = false;
|
PluginEnabled?.Invoke(this, e);
|
||||||
FinishedLoadedPlugins?.Invoke(this, EventArgs.Empty);
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPluginDisabled(PluginEventArgs e)
|
||||||
|
{
|
||||||
|
PluginDisabled?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -13,8 +13,8 @@ namespace Artemis.Core.Services
|
|||||||
{
|
{
|
||||||
public class RgbService : IRgbService, IDisposable
|
public class RgbService : IRgbService, IDisposable
|
||||||
{
|
{
|
||||||
private readonly TimerUpdateTrigger _updateTrigger;
|
|
||||||
private readonly List<IRGBDevice> _loadedDevices;
|
private readonly List<IRGBDevice> _loadedDevices;
|
||||||
|
private readonly TimerUpdateTrigger _updateTrigger;
|
||||||
|
|
||||||
public RgbService()
|
public RgbService()
|
||||||
{
|
{
|
||||||
@ -68,7 +68,9 @@ namespace Artemis.Core.Services
|
|||||||
OnDeviceLoaded(new DeviceEventArgs(surfaceDevice));
|
OnDeviceLoaded(new DeviceEventArgs(surfaceDevice));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
OnDeviceReloaded(new DeviceEventArgs(surfaceDevice));
|
OnDeviceReloaded(new DeviceEventArgs(surfaceDevice));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -28,7 +28,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
@ -52,7 +53,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.CodeAnalysis.CSharp.Scripting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
<assemblyIdentity name="Microsoft.CodeAnalysis.CSharp.Scripting" publicKeyToken="31bf3856ad364e35"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
@ -68,7 +70,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-2.6.0.0" newVersion="2.6.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-2.6.0.0" newVersion="2.6.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
<assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
@ -84,7 +87,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
@ -92,7 +96,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.1" newVersion="4.0.3.1" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.3.1" newVersion="4.0.3.1" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<packages>
|
<packages>
|
||||||
<package id="AppDomainToolkit" version="1.0.4.3" targetFramework="net461" />
|
<package id="AppDomainToolkit" version="1.0.4.3" targetFramework="net461" />
|
||||||
<package id="Castle.Core" version="4.4.0" targetFramework="net461" />
|
<package id="Castle.Core" version="4.4.0" targetFramework="net461" />
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Drawing;
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
using Artemis.Core.Plugins.Interfaces;
|
using Artemis.Core.Plugins.Interfaces;
|
||||||
using Artemis.Core.ProfileElements;
|
using Artemis.Core.ProfileElements;
|
||||||
using QRCoder;
|
using QRCoder;
|
||||||
@ -17,6 +18,11 @@ namespace Artemis.Plugins.LayerTypes.Brush
|
|||||||
var qrGenerator = new QRCodeGenerator();
|
var qrGenerator = new QRCodeGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DisablePlugin()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public void Update(Layer layer)
|
public void Update(Layer layer)
|
||||||
{
|
{
|
||||||
var config = layer.LayerTypeConfiguration as BrushConfiguration;
|
var config = layer.LayerTypeConfiguration as BrushConfiguration;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<packages>
|
<packages>
|
||||||
<package id="QRCoder" version="1.2.5" targetFramework="net461" />
|
<package id="QRCoder" version="1.2.5" targetFramework="net461" />
|
||||||
<package id="RGB.NET.Core" version="0.1.22" targetFramework="net461" />
|
<package id="RGB.NET.Core" version="0.1.22" targetFramework="net461" />
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Plugins.Interfaces;
|
using Artemis.Core.Plugins.Interfaces;
|
||||||
@ -70,6 +71,11 @@ namespace Artemis.Plugins.Modules.General
|
|||||||
PopulateColors();
|
PopulateColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DisablePlugin()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateLedColor(Led led, double deltaTime)
|
private void UpdateLedColor(Led led, double deltaTime)
|
||||||
{
|
{
|
||||||
if (_colors.ContainsKey(led))
|
if (_colors.ContainsKey(led))
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<packages>
|
<packages>
|
||||||
<package id="QRCoder" version="1.3.5" targetFramework="net461" />
|
<package id="QRCoder" version="1.3.5" targetFramework="net461" />
|
||||||
<package id="RGB.NET.Core" version="0.1.22" targetFramework="net461" />
|
<package id="RGB.NET.Core" version="0.1.22" targetFramework="net461" />
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
{
|
{
|
||||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "2.0.2-rtm-10011");
|
.HasAnnotation("ProductVersion", "2.0.2-rtm-10011");
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("RootFolderGuid");
|
.HasForeignKey("RootFolderGuid");
|
||||||
});
|
});
|
||||||
#pragma warning restore 612, 618
|
#pragma warning restore 612, 618
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,7 +31,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
@ -55,7 +56,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Microsoft.CodeAnalysis.CSharp.Scripting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
<assemblyIdentity name="Microsoft.CodeAnalysis.CSharp.Scripting" publicKeyToken="31bf3856ad364e35"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
@ -71,7 +73,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-2.6.0.0" newVersion="2.6.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-2.6.0.0" newVersion="2.6.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
<assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
@ -87,7 +90,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
@ -95,7 +99,8 @@
|
|||||||
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51"
|
||||||
|
culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.1" newVersion="4.0.3.1" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.3.1" newVersion="4.0.3.1" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
|
|||||||
@ -22,6 +22,8 @@ namespace Artemis.UI
|
|||||||
|
|
||||||
protected override void ConfigureIoC(IKernel kernel)
|
protected override void ConfigureIoC(IKernel kernel)
|
||||||
{
|
{
|
||||||
|
kernel.Settings.InjectNonPublic = true;
|
||||||
|
|
||||||
// Load this assembly's module
|
// Load this assembly's module
|
||||||
kernel.Load<UIModule>();
|
kernel.Load<UIModule>();
|
||||||
// Load the core assembly's module
|
// Load the core assembly's module
|
||||||
|
|||||||
@ -70,10 +70,8 @@ namespace Artemis.UI.Controls.Visualizers
|
|||||||
private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args)
|
private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.DeviceAdded)
|
if (args.DeviceAdded)
|
||||||
{
|
|
||||||
foreach (var device in args.Devices)
|
foreach (var device in args.Devices)
|
||||||
_newDevices.Add(device);
|
_newDevices.Add(device);
|
||||||
}
|
|
||||||
|
|
||||||
UpdateSurface();
|
UpdateSurface();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@ namespace Artemis.UI.Stylet
|
|||||||
{
|
{
|
||||||
public ArtemisViewManager(ViewManagerConfig config) : base(config)
|
public ArtemisViewManager(ViewManagerConfig config) : base(config)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ namespace Artemis.UI.Stylet
|
|||||||
kernel.Bind<IViewManager>().ToConstant(new ViewManager(viewManagerConfig));
|
kernel.Bind<IViewManager>().ToConstant(new ViewManager(viewManagerConfig));
|
||||||
|
|
||||||
kernel.Bind<IWindowManagerConfig>().ToConstant(this).InTransientScope();
|
kernel.Bind<IWindowManagerConfig>().ToConstant(this).InTransientScope();
|
||||||
kernel.Bind<IWindowManager>().ToMethod(c => new WindowManager(c.Kernel.Get<IViewManager>(),() => c.Kernel.Get<IMessageBoxViewModel>(), c.Kernel.Get<IWindowManagerConfig>())).InSingletonScope();
|
kernel.Bind<IWindowManager>().ToMethod(c => new WindowManager(c.Kernel.Get<IViewManager>(), () => c.Kernel.Get<IMessageBoxViewModel>(), c.Kernel.Get<IWindowManagerConfig>())).InSingletonScope();
|
||||||
kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
|
kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
|
||||||
kernel.Bind<IMessageBoxViewModel>().To<MessageBoxViewModel>(); // Not singleton!
|
kernel.Bind<IMessageBoxViewModel>().To<MessageBoxViewModel>(); // Not singleton!
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using Artemis.Core.Events;
|
||||||
using Artemis.Core.Plugins.Interfaces;
|
using Artemis.Core.Plugins.Interfaces;
|
||||||
using Artemis.Core.Services.Interfaces;
|
using Artemis.Core.Services.Interfaces;
|
||||||
using Artemis.UI.ViewModels.Interfaces;
|
using Artemis.UI.ViewModels.Interfaces;
|
||||||
@ -29,44 +29,22 @@ namespace Artemis.UI.ViewModels
|
|||||||
|
|
||||||
// Sync up with the plugin service
|
// Sync up with the plugin service
|
||||||
Modules = new BindableCollection<IModule>();
|
Modules = new BindableCollection<IModule>();
|
||||||
LoadingPlugins = _pluginService.LoadingPlugins;
|
Modules.AddRange(_pluginService.GetPluginsOfType<IModule>());
|
||||||
_pluginService.StartedLoadingPlugins += PluginServiceOnStartedLoadingPlugins;
|
|
||||||
_pluginService.FinishedLoadedPlugins += PluginServiceOnFinishedLoadedPlugins;
|
|
||||||
|
|
||||||
if (!LoadingPlugins)
|
|
||||||
Modules.AddRange(_pluginService.GetModules());
|
|
||||||
|
|
||||||
|
_pluginService.PluginEnabled += PluginServiceOnPluginEnabled;
|
||||||
|
_pluginService.PluginDisabled += PluginServiceOnPluginDisabled;
|
||||||
PropertyChanged += OnSelectedModuleChanged;
|
PropertyChanged += OnSelectedModuleChanged;
|
||||||
PropertyChanged += OnSelectedPageChanged;
|
PropertyChanged += OnSelectedPageChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IObservableCollection<IModule> Modules { get; set; }
|
public IObservableCollection<IModule> Modules { get; set; }
|
||||||
|
|
||||||
public bool MenuOpen { get; set; }
|
public bool MenuOpen { get; set; }
|
||||||
public bool LoadingPlugins { get; set; }
|
|
||||||
public ListBoxItem SelectedPage { get; set; }
|
public ListBoxItem SelectedPage { get; set; }
|
||||||
public IModule SelectedModule { get; set; }
|
public IModule SelectedModule { get; set; }
|
||||||
|
|
||||||
private void PluginServiceOnStartedLoadingPlugins(object sender, EventArgs eventArgs)
|
|
||||||
{
|
|
||||||
LoadingPlugins = true;
|
|
||||||
|
|
||||||
Modules.Clear();
|
|
||||||
SelectedModule = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PluginServiceOnFinishedLoadedPlugins(object sender, EventArgs eventArgs)
|
|
||||||
{
|
|
||||||
Modules.AddRange(_pluginService.GetModules());
|
|
||||||
SelectedModule = null;
|
|
||||||
|
|
||||||
LoadingPlugins = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task NavigateToSelectedModule()
|
public async Task NavigateToSelectedModule()
|
||||||
{
|
{
|
||||||
if (SelectedModule == null || LoadingPlugins)
|
if (SelectedModule == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create a view model for the given plugin info (which will be a module)
|
// Create a view model for the given plugin info (which will be a module)
|
||||||
@ -78,6 +56,31 @@ namespace Artemis.UI.ViewModels
|
|||||||
MenuOpen = false;
|
MenuOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
|
||||||
|
{
|
||||||
|
var existing = Modules.FirstOrDefault(m => _pluginService.GetPluginInfo(m)?.Guid == e.PluginInfo.Guid);
|
||||||
|
if (existing != null)
|
||||||
|
{
|
||||||
|
if (SelectedModule == existing && SelectedModule != null)
|
||||||
|
SelectedModule = null;
|
||||||
|
Modules.Remove(existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.PluginInfo.Instance is IModule module)
|
||||||
|
Modules.Add(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PluginServiceOnPluginDisabled(object sender, PluginEventArgs e)
|
||||||
|
{
|
||||||
|
var existing = Modules.FirstOrDefault(m => _pluginService.GetPluginInfo(m)?.Guid == e.PluginInfo.Guid);
|
||||||
|
if (existing != null)
|
||||||
|
{
|
||||||
|
if (SelectedModule == existing && SelectedModule != null)
|
||||||
|
SelectedModule = null;
|
||||||
|
Modules.Remove(existing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void OnSelectedModuleChanged(object sender, PropertyChangedEventArgs e)
|
private async void OnSelectedModuleChanged(object sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PropertyName == "SelectedModule")
|
if (e.PropertyName == "SelectedModule")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user