mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Merge branch 'feature/visual-scripting' into feature/avalonia
This commit is contained in:
commit
4ef7c83c74
366 files changed
+11986
-10866
No files matched your search
@@ -216,8 +216,6 @@ namespace Artemis.Core.Services
|
||||
Version? hidSharpVersion = Assembly.GetAssembly(typeof(HidDevice))!.GetName().Version;
|
||||
_logger.Debug("Forcing plugins to use HidSharp {hidSharpVersion}", hidSharpVersion);
|
||||
|
||||
DeserializationLogger.Initialize(Kernel!);
|
||||
|
||||
// Initialize the services
|
||||
_pluginManagementService.CopyBuiltInPlugins();
|
||||
_pluginManagementService.LoadPlugins(StartupArguments, IsElevated);
|
||||
|
||||
@@ -4,7 +4,7 @@ using Artemis.Core.ScriptingProviders;
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// A service that allows you to manage various types of <see cref="Script" /> instances
|
||||
/// A service that allows you to manage various types of <see cref="NodeScript" /> instances
|
||||
/// </summary>
|
||||
public interface IScriptingService : IArtemisService
|
||||
{
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Artemis.Storage.Entities.Profile.Nodes;
|
||||
using Newtonsoft.Json;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
internal class NodeService : INodeService
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private static readonly Type TYPE_NODE = typeof(INode);
|
||||
|
||||
#endregion
|
||||
|
||||
private readonly IKernel _kernel;
|
||||
|
||||
#region Constructors
|
||||
|
||||
public NodeService(IKernel kernel)
|
||||
{
|
||||
_kernel = kernel;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
public IEnumerable<NodeData> AvailableNodes => NodeTypeStore.GetAll();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
public TypeColorRegistration? GetTypeColor(Type type)
|
||||
{
|
||||
return NodeTypeStore.GetColor(type);
|
||||
}
|
||||
|
||||
public NodeTypeRegistration RegisterNodeType(Plugin plugin, Type nodeType)
|
||||
{
|
||||
if (plugin == null) throw new ArgumentNullException(nameof(plugin));
|
||||
if (nodeType == null) throw new ArgumentNullException(nameof(nodeType));
|
||||
|
||||
if (!TYPE_NODE.IsAssignableFrom(nodeType)) throw new ArgumentException("Node has to be a base type of the Node-Type.", nameof(nodeType));
|
||||
|
||||
NodeAttribute? nodeAttribute = nodeType.GetCustomAttribute<NodeAttribute>();
|
||||
string name = nodeAttribute?.Name ?? nodeType.Name;
|
||||
string description = nodeAttribute?.Description ?? string.Empty;
|
||||
string category = nodeAttribute?.Category ?? string.Empty;
|
||||
|
||||
NodeData nodeData = new(plugin, nodeType, name, description, category, nodeAttribute?.InputType, nodeAttribute?.OutputType, (s, e) => CreateNode(s, e, nodeType));
|
||||
return NodeTypeStore.Add(nodeData);
|
||||
}
|
||||
|
||||
public TypeColorRegistration RegisterTypeColor(Plugin plugin, Type type, SKColor color)
|
||||
{
|
||||
if (plugin == null) throw new ArgumentNullException(nameof(plugin));
|
||||
if (type == null) throw new ArgumentNullException(nameof(type));
|
||||
|
||||
return NodeTypeStore.AddColor(type, color, plugin);
|
||||
}
|
||||
|
||||
private INode CreateNode(INodeScript script, NodeEntity? entity, Type nodeType)
|
||||
{
|
||||
INode node = _kernel.Get(nodeType) as INode ?? throw new InvalidOperationException($"Node {nodeType} is not an INode");
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
node.X = entity.X;
|
||||
node.Y = entity.Y;
|
||||
try
|
||||
{
|
||||
if (node is Node nodeImplementation)
|
||||
nodeImplementation.DeserializeStorage(entity.Storage);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
node.Initialize(script);
|
||||
return node;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A service that provides access to the node system
|
||||
/// </summary>
|
||||
public interface INodeService : IArtemisService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all available nodes
|
||||
/// </summary>
|
||||
IEnumerable<NodeData> AvailableNodes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the best matching registration for the provided type
|
||||
/// </summary>
|
||||
TypeColorRegistration? GetTypeColor(Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a node of the provided <paramref name="nodeType" />
|
||||
/// </summary>
|
||||
/// <param name="plugin">The plugin the node belongs to</param>
|
||||
/// <param name="nodeType">The type of node to initialize</param>
|
||||
NodeTypeRegistration RegisterNodeType(Plugin plugin, Type nodeType);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a type with a provided color for use in the node editor
|
||||
/// </summary>
|
||||
/// <param name="plugin">The plugin making the registration</param>
|
||||
/// <param name="type">The type to associate the color with</param>
|
||||
/// <param name="color">The color to display</param>
|
||||
TypeColorRegistration RegisterTypeColor(Plugin plugin, Type type, SKColor color);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
internal class ConditionOperatorService : IConditionOperatorService
|
||||
{
|
||||
public ConditionOperatorService()
|
||||
{
|
||||
RegisterBuiltInConditionOperators();
|
||||
}
|
||||
|
||||
public ConditionOperatorRegistration RegisterConditionOperator(Plugin plugin, BaseConditionOperator conditionOperator)
|
||||
{
|
||||
if (plugin == null)
|
||||
throw new ArgumentNullException(nameof(plugin));
|
||||
if (conditionOperator == null)
|
||||
throw new ArgumentNullException(nameof(conditionOperator));
|
||||
|
||||
conditionOperator.Plugin = plugin;
|
||||
return ConditionOperatorStore.Add(conditionOperator);
|
||||
}
|
||||
|
||||
public void RemoveConditionOperator(ConditionOperatorRegistration registration)
|
||||
{
|
||||
if (registration == null)
|
||||
throw new ArgumentNullException(nameof(registration));
|
||||
ConditionOperatorStore.Remove(registration);
|
||||
}
|
||||
|
||||
public List<BaseConditionOperator> GetConditionOperatorsForType(Type type, ConditionParameterSide side)
|
||||
{
|
||||
return ConditionOperatorStore.GetForType(type, side).Select(r => r.ConditionOperator).ToList();
|
||||
}
|
||||
|
||||
public BaseConditionOperator? GetConditionOperator(Guid operatorPluginGuid, string operatorType)
|
||||
{
|
||||
return ConditionOperatorStore.Get(operatorPluginGuid, operatorType)?.ConditionOperator;
|
||||
}
|
||||
|
||||
private void RegisterBuiltInConditionOperators()
|
||||
{
|
||||
// General usage for any type
|
||||
RegisterConditionOperator(Constants.CorePlugin, new EqualsConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new NotEqualConditionOperator());
|
||||
|
||||
// Numeric operators
|
||||
RegisterConditionOperator(Constants.CorePlugin, new NumberEqualsConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new NumberNotEqualConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new LessThanConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new GreaterThanConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new LessThanOrEqualConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new GreaterThanOrEqualConditionOperator());
|
||||
|
||||
// String operators
|
||||
RegisterConditionOperator(Constants.CorePlugin, new StringEqualsConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new StringNotEqualConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new StringContainsConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new StringNotContainsConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new StringStartsWithConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new StringEndsWithConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new StringMatchesRegexConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new StringNullConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new StringNotNullConditionOperator());
|
||||
|
||||
// Enum operators
|
||||
RegisterConditionOperator(Constants.CorePlugin, new EnumContainsConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new EnumNotContainsConditionOperator());
|
||||
|
||||
// Null checks, at the bottom
|
||||
// TODO: Implement a priority mechanism
|
||||
RegisterConditionOperator(Constants.CorePlugin, new NullConditionOperator());
|
||||
RegisterConditionOperator(Constants.CorePlugin, new NotNullConditionOperator());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
internal class DataBindingService : IDataBindingService
|
||||
{
|
||||
public DataBindingService()
|
||||
{
|
||||
RegisterBuiltInModifiers();
|
||||
}
|
||||
|
||||
public DataBindingModifierTypeRegistration RegisterModifierType(Plugin plugin, BaseDataBindingModifierType dataBindingModifierType)
|
||||
{
|
||||
if (plugin == null)
|
||||
throw new ArgumentNullException(nameof(plugin));
|
||||
if (dataBindingModifierType == null)
|
||||
throw new ArgumentNullException(nameof(dataBindingModifierType));
|
||||
|
||||
dataBindingModifierType.Plugin = plugin;
|
||||
return DataBindingModifierTypeStore.Add(dataBindingModifierType);
|
||||
}
|
||||
|
||||
public void RemoveModifierType(DataBindingModifierTypeRegistration registration)
|
||||
{
|
||||
if (registration == null)
|
||||
throw new ArgumentNullException(nameof(registration));
|
||||
DataBindingModifierTypeStore.Remove(registration);
|
||||
}
|
||||
|
||||
public List<BaseDataBindingModifierType> GetCompatibleModifierTypes(Type type, ModifierTypePart part)
|
||||
{
|
||||
return DataBindingModifierTypeStore.GetForType(type, part).Select(r => r.DataBindingModifierType).ToList();
|
||||
}
|
||||
|
||||
public BaseDataBindingModifierType? GetModifierType(Guid modifierTypePluginGuid, string modifierType)
|
||||
{
|
||||
return DataBindingModifierTypeStore.Get(modifierTypePluginGuid, modifierType)?.DataBindingModifierType;
|
||||
}
|
||||
|
||||
private void RegisterBuiltInModifiers()
|
||||
{
|
||||
// Numbers - General
|
||||
RegisterModifierType(Constants.CorePlugin, new SumModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new SubtractModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new MultiplicationModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new DivideModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new PercentageOfModifierType());
|
||||
|
||||
// Numbers - Advanced
|
||||
RegisterModifierType(Constants.CorePlugin, new MaxModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new MinModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new ModuloModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new AbsoluteModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new PowerModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new SquareRootModifierType());
|
||||
|
||||
// Numbers - Rounding
|
||||
RegisterModifierType(Constants.CorePlugin, new FloorModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new RoundModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new CeilingModifierType());
|
||||
|
||||
// Numbers - Trigonometric
|
||||
RegisterModifierType(Constants.CorePlugin, new SineModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new CosineModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new TangentModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new CotangentModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new SecantModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new CosecantModifierType());
|
||||
|
||||
// Colors
|
||||
RegisterModifierType(Constants.CorePlugin, new SKColorSumModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new SKColorSaturateModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new SKColorDesaturateModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new SKColorBrightenModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new SKColorDarkenModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new SKColorRotateHueModifierType());
|
||||
RegisterModifierType(Constants.CorePlugin, new SKColorInvertModifierType());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.Properties;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// A service that allows you to register and retrieve conditions operators used by display conditions
|
||||
/// </summary>
|
||||
public interface IConditionOperatorService : IArtemisService
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a new condition operator for use in layer conditions
|
||||
/// </summary>
|
||||
/// <param name="plugin">The plugin this condition operator belongs to</param>
|
||||
/// <param name="conditionOperator">The condition operator to register</param>
|
||||
ConditionOperatorRegistration RegisterConditionOperator([NotNull] Plugin plugin, [NotNull] BaseConditionOperator conditionOperator);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a condition operator so it is no longer available for use in layer conditions
|
||||
/// </summary>
|
||||
/// <param name="registration">The registration of the condition operator to remove</param>
|
||||
void RemoveConditionOperator([NotNull] ConditionOperatorRegistration registration);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the condition operators compatible with the provided type
|
||||
/// </summary>
|
||||
List<BaseConditionOperator> GetConditionOperatorsForType(Type type, ConditionParameterSide side);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a condition operator by its plugin GUID and type name
|
||||
/// </summary>
|
||||
/// <param name="operatorPluginGuid">The operator's plugin GUID</param>
|
||||
/// <param name="operatorType">The type name of the operator</param>
|
||||
BaseConditionOperator? GetConditionOperator(Guid operatorPluginGuid, string operatorType);
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.Properties;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// A service that allows you to register and retrieve data binding modifiers used by the data bindings system
|
||||
/// </summary>
|
||||
public interface IDataBindingService : IArtemisService
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a new modifier type for use in data bindings
|
||||
/// </summary>
|
||||
/// <param name="plugin">The plugin this modifier type belongs to</param>
|
||||
/// <param name="dataBindingModifierType">The modifier type to register</param>
|
||||
DataBindingModifierTypeRegistration RegisterModifierType([NotNull] Plugin plugin, [NotNull] BaseDataBindingModifierType dataBindingModifierType);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a modifier type so it is no longer available for use in data bindings
|
||||
/// </summary>
|
||||
/// <param name="dataBindingModifierType">The registration of the modifier type to remove</param>
|
||||
void RemoveModifierType([NotNull] DataBindingModifierTypeRegistration dataBindingModifierType);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the data binding modifier types compatible with the provided type
|
||||
/// </summary>
|
||||
List<BaseDataBindingModifierType> GetCompatibleModifierTypes(Type type, ModifierTypePart part);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a modifier type by its plugin GUID and type name
|
||||
/// </summary>
|
||||
/// <param name="modifierTypePluginGuid">The modifier type's plugin GUID</param>
|
||||
/// <param name="modifierType">The type name of the modifier type</param>
|
||||
/// <returns></returns>
|
||||
BaseDataBindingModifierType? GetModifierType(Guid modifierTypePluginGuid, string modifierType);
|
||||
}
|
||||
}
|
||||
@@ -30,9 +30,6 @@ namespace Artemis.Core.Services
|
||||
|
||||
public ProfileService(ILogger logger,
|
||||
IRgbService rgbService,
|
||||
// TODO: Move these two
|
||||
IConditionOperatorService conditionOperatorService,
|
||||
IDataBindingService dataBindingService,
|
||||
IProfileCategoryRepository profileCategoryRepository,
|
||||
IPluginManagementService pluginManagementService,
|
||||
IInputService inputService,
|
||||
@@ -224,8 +221,8 @@ namespace Artemis.Core.Services
|
||||
try
|
||||
{
|
||||
// Make sure the profile is active or inactive according to the parameters above
|
||||
if (shouldBeActive && profileConfiguration.Profile == null)
|
||||
ActivateProfile(profileConfiguration);
|
||||
if (shouldBeActive && profileConfiguration.Profile == null && profileConfiguration.BrokenState != "Failed to activate profile")
|
||||
profileConfiguration.TryOrBreak(() => ActivateProfile(profileConfiguration), "Failed to activate profile");
|
||||
else if (!shouldBeActive && profileConfiguration.Profile != null)
|
||||
DeactivateProfile(profileConfiguration);
|
||||
|
||||
@@ -330,7 +327,17 @@ namespace Artemis.Core.Services
|
||||
if (profileConfiguration.Profile != null)
|
||||
return profileConfiguration.Profile;
|
||||
|
||||
ProfileEntity profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
||||
ProfileEntity profileEntity;
|
||||
try
|
||||
{
|
||||
profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
profileConfiguration.SetBrokenState("Failed to activate profile", e);
|
||||
throw;
|
||||
}
|
||||
|
||||
if (profileEntity == null)
|
||||
throw new ArtemisCoreException($"Cannot find profile named: {profileConfiguration.Name} ID: {profileConfiguration.Entity.ProfileId}");
|
||||
|
||||
@@ -441,10 +448,8 @@ namespace Artemis.Core.Services
|
||||
profile.Save();
|
||||
if (includeChildren)
|
||||
{
|
||||
foreach (Folder folder in profile.GetAllFolders())
|
||||
folder.Save();
|
||||
foreach (Layer layer in profile.GetAllLayers())
|
||||
layer.Save();
|
||||
foreach (RenderProfileElement child in profile.GetAllRenderElements())
|
||||
child.Save();
|
||||
}
|
||||
|
||||
// If there are no changes, don't bother saving
|
||||
@@ -602,10 +607,8 @@ namespace Artemis.Core.Services
|
||||
|
||||
profile.Save();
|
||||
|
||||
foreach (Folder folder in profile.GetAllFolders())
|
||||
folder.Save();
|
||||
foreach (Layer layer in profile.GetAllLayers())
|
||||
layer.Save();
|
||||
foreach (RenderProfileElement renderProfileElement in profile.GetAllRenderElements())
|
||||
renderProfileElement.Save();
|
||||
|
||||
_logger.Debug("Adapt profile - Saving " + profile);
|
||||
profile.RedoStack.Clear();
|
||||
|
||||
Reference in new issue
Block a user