mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Nodes - Added type color registration system
Nodes - Generate (stable) type colors for undefined types
This commit is contained in:
1 parent
5675d1895b
commit
b8077ca589
12 files changed
+297
-147
No files matched your search
@@ -16,7 +16,7 @@ namespace Artemis.Core
|
||||
/// <returns>The RGB.NET color</returns>
|
||||
public static Color ToRgbColor(this SKColor color)
|
||||
{
|
||||
return new(color.Alpha, color.Red, color.Green, color.Blue);
|
||||
return new Color(color.Alpha, color.Red, color.Green, color.Blue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -49,7 +49,7 @@ namespace Artemis.Core
|
||||
/// <returns>The sum of the two colors</returns>
|
||||
public static SKColor Sum(this SKColor a, SKColor b)
|
||||
{
|
||||
return new(
|
||||
return new SKColor(
|
||||
ClampToByte(a.Red + b.Red),
|
||||
ClampToByte(a.Green + b.Green),
|
||||
ClampToByte(a.Blue + b.Blue),
|
||||
@@ -57,6 +57,19 @@ namespace Artemis.Core
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Darkens the color by the specified amount
|
||||
/// </summary>
|
||||
/// <param name="c">The color to darken</param>
|
||||
/// <param name="amount">The brightness of the new color</param>
|
||||
/// <returns>The darkened color</returns>
|
||||
public static SKColor Darken(this SKColor c, float amount)
|
||||
{
|
||||
c.ToHsl(out float h, out float s, out float l);
|
||||
l *= 1f - amount;
|
||||
return SKColor.FromHsl(h, s, l);
|
||||
}
|
||||
|
||||
private static byte ClampToByte(float value)
|
||||
{
|
||||
return (byte) Math.Clamp(value, 0, 255);
|
||||
|
||||
@@ -4,24 +4,19 @@ using System.Reflection;
|
||||
using Artemis.Storage.Entities.Profile.Nodes;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
internal class NodeService : INodeService
|
||||
{
|
||||
private readonly IKernel _kernel;
|
||||
|
||||
#region Constants
|
||||
|
||||
private static readonly Type TYPE_NODE = typeof(INode);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
public IEnumerable<NodeData> AvailableNodes => NodeTypeStore.GetAll();
|
||||
|
||||
#endregion
|
||||
private readonly IKernel _kernel;
|
||||
|
||||
#region Constructors
|
||||
|
||||
@@ -32,8 +27,20 @@ namespace Artemis.Core.Services
|
||||
|
||||
#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));
|
||||
@@ -46,10 +53,18 @@ namespace Artemis.Core.Services
|
||||
string description = nodeAttribute?.Description ?? string.Empty;
|
||||
string category = nodeAttribute?.Category ?? string.Empty;
|
||||
|
||||
NodeData nodeData = new(plugin, nodeType, name, description, category, (e) => CreateNode(e, nodeType));
|
||||
NodeData nodeData = new(plugin, nodeType, name, description, category, e => CreateNode(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(NodeEntity? entity, Type nodeType)
|
||||
{
|
||||
INode node = _kernel.Get(nodeType) as INode ?? throw new InvalidOperationException($"Node {nodeType} is not an INode");
|
||||
@@ -72,20 +87,33 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A service that provides access to the node system
|
||||
/// A service that provides access to the node system
|
||||
/// </summary>
|
||||
public interface INodeService : IArtemisService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all available nodes
|
||||
/// Gets all available nodes
|
||||
/// </summary>
|
||||
IEnumerable<NodeData> AvailableNodes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a node of the provided <paramref name="nodeType"/>
|
||||
/// 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,12 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
internal class NodeTypeStore
|
||||
{
|
||||
private static readonly List<NodeTypeRegistration> Registrations = new();
|
||||
private static readonly List<TypeColorRegistration> ColorRegistrations = new();
|
||||
|
||||
public static NodeTypeRegistration Add(NodeData nodeData)
|
||||
{
|
||||
@@ -19,7 +21,7 @@ namespace Artemis.Core
|
||||
if (Registrations.Any(r => r.NodeData == nodeData))
|
||||
throw new ArtemisCoreException($"Data binding modifier type store already contains modifier '{nodeData.Name}'");
|
||||
|
||||
typeRegistration = new NodeTypeRegistration(nodeData, nodeData.Plugin) { IsInStore = true };
|
||||
typeRegistration = new NodeTypeRegistration(nodeData, nodeData.Plugin) {IsInStore = true};
|
||||
Registrations.Add(typeRegistration);
|
||||
}
|
||||
|
||||
@@ -32,7 +34,7 @@ namespace Artemis.Core
|
||||
lock (Registrations)
|
||||
{
|
||||
if (!Registrations.Contains(typeRegistration))
|
||||
throw new ArtemisCoreException($"Data binding modifier type store does not contain modifier type '{typeRegistration.NodeData.Name}'");
|
||||
throw new ArtemisCoreException($"Node type store does not contain modifier type '{typeRegistration.NodeData.Name}'");
|
||||
|
||||
Registrations.Remove(typeRegistration);
|
||||
typeRegistration.IsInStore = false;
|
||||
@@ -57,6 +59,51 @@ namespace Artemis.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static Plugin? GetPlugin(INode node)
|
||||
{
|
||||
lock (Registrations)
|
||||
{
|
||||
return Registrations.FirstOrDefault(r => r.Plugin.GetType().Assembly == node.GetType().Assembly)?.Plugin;
|
||||
}
|
||||
}
|
||||
|
||||
public static TypeColorRegistration AddColor(Type type, SKColor color, Plugin plugin)
|
||||
{
|
||||
TypeColorRegistration typeColorRegistration;
|
||||
lock (ColorRegistrations)
|
||||
{
|
||||
if (ColorRegistrations.Any(r => r.Type == type))
|
||||
throw new ArtemisCoreException($"Node color store already contains a color for '{type.Name}'");
|
||||
|
||||
typeColorRegistration = new TypeColorRegistration(type, color, plugin) {IsInStore = true};
|
||||
ColorRegistrations.Add(typeColorRegistration);
|
||||
}
|
||||
|
||||
return typeColorRegistration;
|
||||
}
|
||||
|
||||
public static void RemoveColor(TypeColorRegistration typeColorRegistration)
|
||||
{
|
||||
lock (ColorRegistrations)
|
||||
{
|
||||
if (!ColorRegistrations.Contains(typeColorRegistration))
|
||||
throw new ArtemisCoreException($"Node color store does not contain modifier type '{typeColorRegistration.Type.Name}'");
|
||||
|
||||
ColorRegistrations.Remove(typeColorRegistration);
|
||||
typeColorRegistration.IsInStore = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static TypeColorRegistration? GetColor(Type type)
|
||||
{
|
||||
lock (ColorRegistrations)
|
||||
{
|
||||
return ColorRegistrations
|
||||
.OrderByDescending(r => r.Type.ScoreCastability(type))
|
||||
.FirstOrDefault(r => r.Type.ScoreCastability(type) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
public static event EventHandler<NodeTypeStoreEvent>? NodeTypeAdded;
|
||||
@@ -73,13 +120,5 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static Plugin? GetPlugin(INode node)
|
||||
{
|
||||
lock (Registrations)
|
||||
{
|
||||
return Registrations.FirstOrDefault(r => r.Plugin.GetType().Assembly == node.GetType().Assembly)?.Plugin;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
using System;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a registration for a type of <see cref="INode"/>
|
||||
/// Represents a registration for a type of <see cref="INode" />
|
||||
/// </summary>
|
||||
public class NodeTypeRegistration
|
||||
{
|
||||
@@ -15,13 +16,16 @@ namespace Artemis.Core
|
||||
Plugin.Disabled += OnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the node data that was registered
|
||||
/// </summary>
|
||||
public NodeData NodeData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin the node is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||
/// </summary>
|
||||
@@ -34,4 +38,51 @@ namespace Artemis.Core
|
||||
NodeTypeStore.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a registration for a <see cref="SKColor" /> to associate with a certain <see cref="System.Type" />
|
||||
/// </summary>
|
||||
public class TypeColorRegistration
|
||||
{
|
||||
internal TypeColorRegistration(Type type, SKColor color, Plugin plugin)
|
||||
{
|
||||
Type = type;
|
||||
Color = color;
|
||||
Plugin = plugin;
|
||||
|
||||
Plugin.Disabled += OnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type
|
||||
/// </summary>
|
||||
public Type Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color
|
||||
/// </summary>
|
||||
public SKColor Color { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a darkened tone of the <see cref="Color" />
|
||||
/// </summary>
|
||||
public SKColor DarkenedColor => Color.Darken(0.35f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin type color is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||
/// </summary>
|
||||
public bool IsInStore { get; internal set; }
|
||||
|
||||
private void OnDisabled(object? sender, EventArgs e)
|
||||
{
|
||||
Plugin.Disabled -= OnDisabled;
|
||||
if (IsInStore)
|
||||
NodeTypeStore.RemoveColor(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user