mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Scripting - Core implementation (#629)
Scripting - Added plugin classes Layers - Fix certain blend modes not working as intended UI - Add customizable header per page Profile editor - Hide the regular header Profile editor - Added a new toolbar
This commit is contained in:
1 parent
d749ab5bbd
commit
048864fe78
47 files changed
+1599
-237
No files matched your search
@@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.LayerEffects;
|
||||
using Artemis.Core.ScriptingProviders;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
using Artemis.Storage.Entities.Profile.Abstract;
|
||||
using RGB.NET.Core;
|
||||
@@ -37,6 +38,9 @@ namespace Artemis.Core
|
||||
Profile = Parent.Profile;
|
||||
Name = name;
|
||||
Suspended = false;
|
||||
Scripts = new List<LayerScript>();
|
||||
ScriptConfigurations = new List<ScriptConfiguration>();
|
||||
|
||||
_general = new LayerGeneralProperties();
|
||||
_transform = new LayerTransformProperties();
|
||||
|
||||
@@ -60,6 +64,9 @@ namespace Artemis.Core
|
||||
|
||||
Profile = profile;
|
||||
Parent = parent;
|
||||
Scripts = new List<LayerScript>();
|
||||
ScriptConfigurations = new List<ScriptConfiguration>();
|
||||
|
||||
_general = new LayerGeneralProperties();
|
||||
_transform = new LayerTransformProperties();
|
||||
|
||||
@@ -75,6 +82,16 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<ArtemisLed> Leds => _leds.AsReadOnly();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all active scripts assigned to this layer
|
||||
/// </summary>
|
||||
public List<LayerScript> Scripts { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all script configurations assigned to this layer
|
||||
/// </summary>
|
||||
public List<ScriptConfiguration> ScriptConfigurations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the shape that is rendered by the <see cref="LayerBrush" />.
|
||||
/// </summary>
|
||||
@@ -142,8 +159,10 @@ namespace Artemis.Core
|
||||
if (LayerBrush?.BaseProperties != null)
|
||||
result.AddRange(LayerBrush.BaseProperties.GetAllLayerProperties());
|
||||
foreach (BaseLayerEffect layerEffect in LayerEffects)
|
||||
{
|
||||
if (layerEffect.BaseProperties != null)
|
||||
result.AddRange(layerEffect.BaseProperties.GetAllLayerProperties());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -171,6 +190,9 @@ namespace Artemis.Core
|
||||
|
||||
Disposed = true;
|
||||
|
||||
while (Scripts.Count > 1)
|
||||
Scripts[0].Dispose();
|
||||
|
||||
LayerBrushStore.LayerBrushAdded -= LayerBrushStoreOnLayerBrushAdded;
|
||||
LayerBrushStore.LayerBrushRemoved -= LayerBrushStoreOnLayerBrushRemoved;
|
||||
|
||||
@@ -247,6 +269,11 @@ namespace Artemis.Core
|
||||
ExpandedPropertyGroups.AddRange(LayerEntity.ExpandedPropertyGroups);
|
||||
LoadRenderElement();
|
||||
Adapter.Load();
|
||||
|
||||
foreach (ScriptConfiguration scriptConfiguration in ScriptConfigurations)
|
||||
scriptConfiguration.Script?.Dispose();
|
||||
ScriptConfigurations.Clear();
|
||||
ScriptConfigurations.AddRange(LayerEntity.ScriptConfigurations.Select(e => new ScriptConfiguration(e)));
|
||||
}
|
||||
|
||||
internal override void Save()
|
||||
@@ -284,6 +311,13 @@ namespace Artemis.Core
|
||||
// Adaption hints
|
||||
Adapter.Save();
|
||||
|
||||
LayerEntity.ScriptConfigurations.Clear();
|
||||
foreach (ScriptConfiguration scriptConfiguration in ScriptConfigurations)
|
||||
{
|
||||
scriptConfiguration.Save();
|
||||
LayerEntity.ScriptConfigurations.Add(scriptConfiguration.Entity);
|
||||
}
|
||||
|
||||
SaveRenderElement();
|
||||
}
|
||||
|
||||
@@ -316,6 +350,9 @@ namespace Artemis.Core
|
||||
if (Disposed)
|
||||
throw new ObjectDisposedException("Layer");
|
||||
|
||||
foreach (LayerScript layerScript in Scripts)
|
||||
layerScript.OnLayerUpdating(deltaTime);
|
||||
|
||||
UpdateDisplayCondition();
|
||||
UpdateTimeline(deltaTime);
|
||||
|
||||
@@ -323,6 +360,9 @@ namespace Artemis.Core
|
||||
Enable();
|
||||
else if (Timeline.IsFinished)
|
||||
Disable();
|
||||
|
||||
foreach (LayerScript layerScript in Scripts)
|
||||
layerScript.OnLayerUpdated(deltaTime);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -473,19 +513,27 @@ namespace Artemis.Core
|
||||
if (LayerBrush == null)
|
||||
throw new ArtemisCoreException("The layer is not yet ready for rendering");
|
||||
|
||||
foreach (LayerScript layerScript in Scripts)
|
||||
layerScript.OnLayerRendering(canvas, bounds, layerPaint);
|
||||
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => !e.Suspended))
|
||||
baseLayerEffect.PreProcess(canvas, bounds, layerPaint);
|
||||
|
||||
try
|
||||
{
|
||||
canvas.SaveLayer(layerPaint);
|
||||
|
||||
// If a brush is a bad boy and tries to color outside the lines, ensure that its clipped off
|
||||
canvas.ClipPath(renderPath);
|
||||
|
||||
// Restore the blend mode before doing the actual render
|
||||
layerPaint.BlendMode = SKBlendMode.SrcOver;
|
||||
|
||||
LayerBrush.InternalRender(canvas, bounds, layerPaint);
|
||||
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => !e.Suspended))
|
||||
baseLayerEffect.PostProcess(canvas, bounds, layerPaint);
|
||||
|
||||
foreach (LayerScript layerScript in Scripts)
|
||||
layerScript.OnLayerRendered(canvas, bounds, layerPaint);
|
||||
}
|
||||
|
||||
finally
|
||||
@@ -500,9 +548,7 @@ namespace Artemis.Core
|
||||
throw new ObjectDisposedException("Layer");
|
||||
|
||||
if (!Leds.Any())
|
||||
{
|
||||
Path = new SKPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
SKPath path = new() {FillType = SKPathFillType.Winding};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.ScriptingProviders;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
|
||||
namespace Artemis.Core
|
||||
@@ -23,6 +24,16 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
LayerPropertyGroup LayerPropertyGroup { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all active scripts assigned to this layer property
|
||||
/// </summary>
|
||||
List<PropertyScript> Scripts { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all script configurations assigned to this layer property
|
||||
/// </summary>
|
||||
public List<ScriptConfiguration> ScriptConfigurations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique path of the property on the layer
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Artemis.Core.ScriptingProviders;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@@ -30,6 +31,8 @@ namespace Artemis.Core
|
||||
Path = null!;
|
||||
Entity = null!;
|
||||
PropertyDescription = null!;
|
||||
Scripts = new List<PropertyScript>();
|
||||
ScriptConfigurations = new List<ScriptConfiguration>();
|
||||
|
||||
CurrentValue = default!;
|
||||
DefaultValue = default!;
|
||||
@@ -55,15 +58,15 @@ namespace Artemis.Core
|
||||
/// </param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_disposed = true;
|
||||
_disposed = true;
|
||||
|
||||
foreach (IDataBinding dataBinding in _dataBindings)
|
||||
dataBinding.Dispose();
|
||||
while (Scripts.Count > 1)
|
||||
Scripts[0].Dispose();
|
||||
|
||||
Disposed?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
foreach (IDataBinding dataBinding in _dataBindings)
|
||||
dataBinding.Dispose();
|
||||
|
||||
Disposed?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -150,6 +153,12 @@ namespace Artemis.Core
|
||||
/// <inheritdoc />
|
||||
public PropertyDescriptionAttribute PropertyDescription { get; internal set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public List<PropertyScript> Scripts { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public List<ScriptConfiguration> ScriptConfigurations { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Path { get; private set; }
|
||||
|
||||
@@ -162,12 +171,18 @@ namespace Artemis.Core
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
|
||||
foreach (PropertyScript propertyScript in Scripts)
|
||||
propertyScript.OnPropertyUpdating(timeline.Delta.TotalSeconds);
|
||||
|
||||
CurrentValue = BaseValue;
|
||||
|
||||
UpdateKeyframes(timeline);
|
||||
UpdateDataBindings(timeline);
|
||||
|
||||
OnUpdated();
|
||||
|
||||
foreach (PropertyScript propertyScript in Scripts)
|
||||
propertyScript.OnPropertyUpdated(timeline.Delta.TotalSeconds);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -747,6 +762,11 @@ namespace Artemis.Core
|
||||
if (dataBinding != null)
|
||||
_dataBindings.Add(dataBinding);
|
||||
}
|
||||
|
||||
foreach (ScriptConfiguration scriptConfiguration in ScriptConfigurations)
|
||||
scriptConfiguration.Script?.Dispose();
|
||||
ScriptConfigurations.Clear();
|
||||
ScriptConfigurations.AddRange(Entity.ScriptConfigurations.Select(e => new ScriptConfiguration(e)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -768,6 +788,13 @@ namespace Artemis.Core
|
||||
Entity.DataBindingEntities.Clear();
|
||||
foreach (IDataBinding dataBinding in _dataBindings)
|
||||
dataBinding.Save();
|
||||
|
||||
Entity.ScriptConfigurations.Clear();
|
||||
foreach (ScriptConfiguration scriptConfiguration in ScriptConfigurations)
|
||||
{
|
||||
scriptConfiguration.Save();
|
||||
Entity.ScriptConfigurations.Add(scriptConfiguration.Entity);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core.ScriptingProviders;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
using SkiaSharp;
|
||||
|
||||
@@ -13,13 +14,15 @@ namespace Artemis.Core
|
||||
{
|
||||
private readonly object _lock = new();
|
||||
private bool _isFreshImport;
|
||||
|
||||
|
||||
internal Profile(ProfileConfiguration configuration, ProfileEntity profileEntity) : base(null!)
|
||||
{
|
||||
Configuration = configuration;
|
||||
Profile = this;
|
||||
ProfileEntity = profileEntity;
|
||||
EntityId = profileEntity.Id;
|
||||
Scripts = new List<ProfileScript>();
|
||||
ScriptConfigurations = new List<ScriptConfiguration>();
|
||||
|
||||
UndoStack = new Stack<string>();
|
||||
RedoStack = new Stack<string>();
|
||||
@@ -32,6 +35,17 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public ProfileConfiguration Configuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all active scripts assigned to this profile
|
||||
/// </summary>
|
||||
public List<ProfileScript> Scripts { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all script configurations assigned to this profile
|
||||
/// </summary>
|
||||
public List<ScriptConfiguration> ScriptConfigurations { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether this profile is freshly imported i.e. no changes have been made to it
|
||||
/// since import
|
||||
@@ -62,8 +76,14 @@ namespace Artemis.Core
|
||||
if (Disposed)
|
||||
throw new ObjectDisposedException("Profile");
|
||||
|
||||
foreach (ProfileScript profileScript in Scripts)
|
||||
profileScript.OnProfileUpdating(deltaTime);
|
||||
|
||||
foreach (ProfileElement profileElement in Children)
|
||||
profileElement.Update(deltaTime);
|
||||
|
||||
foreach (ProfileScript profileScript in Scripts)
|
||||
profileScript.OnProfileUpdated(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +95,14 @@ namespace Artemis.Core
|
||||
if (Disposed)
|
||||
throw new ObjectDisposedException("Profile");
|
||||
|
||||
foreach (ProfileScript profileScript in Scripts)
|
||||
profileScript.OnProfileRendering(canvas, canvas.LocalClipBounds);
|
||||
|
||||
foreach (ProfileElement profileElement in Children)
|
||||
profileElement.Render(canvas, basePosition);
|
||||
|
||||
foreach (ProfileScript profileScript in Scripts)
|
||||
profileScript.OnProfileRendered(canvas, canvas.LocalClipBounds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +151,9 @@ namespace Artemis.Core
|
||||
if (!disposing)
|
||||
return;
|
||||
|
||||
while (Scripts.Count > 1)
|
||||
Scripts[0].Dispose();
|
||||
|
||||
foreach (ProfileElement profileElement in Children)
|
||||
profileElement.Dispose();
|
||||
ChildrenList.Clear();
|
||||
@@ -157,6 +186,11 @@ namespace Artemis.Core
|
||||
AddChild(new Folder(this, this, rootFolder));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ScriptConfiguration scriptConfiguration in ScriptConfigurations)
|
||||
scriptConfiguration.Script?.Dispose();
|
||||
ScriptConfigurations.Clear();
|
||||
ScriptConfigurations.AddRange(ProfileEntity.ScriptConfigurations.Select(e => new ScriptConfiguration(e)));
|
||||
}
|
||||
|
||||
internal override void Save()
|
||||
@@ -176,6 +210,13 @@ namespace Artemis.Core
|
||||
|
||||
ProfileEntity.Layers.Clear();
|
||||
ProfileEntity.Layers.AddRange(GetAllLayers().Select(f => f.LayerEntity));
|
||||
|
||||
ProfileEntity.ScriptConfigurations.Clear();
|
||||
foreach (ScriptConfiguration scriptConfiguration in ScriptConfigurations)
|
||||
{
|
||||
scriptConfiguration.Save();
|
||||
ProfileEntity.ScriptConfigurations.Add(scriptConfiguration.Entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user