Merge branch 'feature/visual-scripting' into feature/avalonia

This commit is contained in:
Robert committed 2021-11-17 23:07:36 +01:00
commit 4ef7c83c74
366 files changed
+11986 -10866

No files matched your search

-2
View File
@@ -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
{
+125
View File
@@ -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();