mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Core - Refactored effects
Profile editor - Added effect creation
This commit is contained in:
1 parent
e5ba48c7f4
commit
2bf36fbf20
61 files changed
+1005
-763
No files matched your search
@@ -6,7 +6,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
/// <summary>
|
||||
/// For internal use only, please use <see cref="LayerBrush{T}" /> or <see cref="PerLedLayerBrush{T}" /> or instead
|
||||
/// </summary>
|
||||
public abstract class PropertiesLayerBrush<T> : BaseLayerBrush where T : LayerPropertyGroup
|
||||
public abstract class PropertiesLayerBrush<T> : BaseLayerBrush where T : LayerPropertyGroup, new()
|
||||
{
|
||||
private T _properties = null!;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
|
||||
internal void InitializeProperties(PropertyGroupEntity? propertyGroupEntity)
|
||||
{
|
||||
Properties = Activator.CreateInstance<T>();
|
||||
Properties = new T();
|
||||
PropertyGroupDescriptionAttribute groupDescription = new() {Identifier = "Brush", Name = Descriptor.DisplayName, Description = Descriptor.Description};
|
||||
Properties.Initialize(Layer, null, groupDescription, propertyGroupEntity);
|
||||
PropertiesInitialized = true;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
/// Represents a brush that renders on a layer
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of brush properties</typeparam>
|
||||
public abstract class LayerBrush<T> : PropertiesLayerBrush<T> where T : LayerPropertyGroup
|
||||
public abstract class LayerBrush<T> : PropertiesLayerBrush<T> where T : LayerPropertyGroup, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="LayerBrush{T}" /> class
|
||||
|
||||
@@ -69,8 +69,6 @@ namespace Artemis.Core.LayerBrushes
|
||||
brush.LayerBrushEntity = entity ?? new LayerBrushEntity { ProviderId = Provider.Id, BrushType = LayerBrushType.FullName };
|
||||
|
||||
brush.Initialize();
|
||||
brush.Update(0);
|
||||
|
||||
return brush;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
/// Represents a brush that renders on a per-layer basis
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of brush properties</typeparam>
|
||||
public abstract class PerLedLayerBrush<T> : PropertiesLayerBrush<T> where T : LayerPropertyGroup
|
||||
public abstract class PerLedLayerBrush<T> : PropertiesLayerBrush<T> where T : LayerPropertyGroup, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="PerLedLayerBrush{T}" /> class
|
||||
|
||||
@@ -7,12 +7,11 @@ namespace Artemis.Core.LayerEffects
|
||||
/// <summary>
|
||||
/// For internal use only, please use <see cref="LayerEffect{T}" /> instead
|
||||
/// </summary>
|
||||
public abstract class BaseLayerEffect : BreakableModel, IDisposable
|
||||
public abstract class BaseLayerEffect : BreakableModel, IDisposable, IStorageModel
|
||||
{
|
||||
private ILayerEffectConfigurationDialog? _configurationDialog;
|
||||
private LayerEffectDescriptor _descriptor;
|
||||
private bool _suspended;
|
||||
private Guid _entityId;
|
||||
private bool _hasBeenRenamed;
|
||||
private string _name;
|
||||
private int _order;
|
||||
@@ -51,15 +50,6 @@ namespace Artemis.Core.LayerEffects
|
||||
set => SetAndNotify(ref _name, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the suspended state, if suspended the effect is skipped in render and update
|
||||
/// </summary>
|
||||
public bool Suspended
|
||||
{
|
||||
get => _suspended;
|
||||
set => SetAndNotify(ref _suspended, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the effect has been renamed by the user, if true consider refraining from changing the name
|
||||
/// programatically
|
||||
@@ -105,13 +95,18 @@ namespace Artemis.Core.LayerEffects
|
||||
/// <summary>
|
||||
/// Gets a reference to the layer property group without knowing it's type
|
||||
/// </summary>
|
||||
public virtual LayerPropertyGroup? BaseProperties => null;
|
||||
public virtual LayerEffectPropertyGroup? BaseProperties => null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the layer effect is enabled or not
|
||||
/// </summary>
|
||||
public bool Enabled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the layer effect is suspended or not
|
||||
/// </summary>
|
||||
public bool Suspended => BaseProperties is not {PropertiesInitialized: true} || !BaseProperties.IsEnabled;
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <summary>
|
||||
@@ -224,11 +219,20 @@ namespace Artemis.Core.LayerEffects
|
||||
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Load()
|
||||
{
|
||||
Name = LayerEffectEntity.Name;
|
||||
HasBeenRenamed = LayerEffectEntity.HasBeenRenamed;
|
||||
Order = LayerEffectEntity.Order;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Save()
|
||||
{
|
||||
// No need to update the ID, type and provider ID. They're set once by the LayerBrushDescriptors CreateInstance and can't change
|
||||
LayerEffectEntity.ProviderId = Descriptor.Provider.Id;
|
||||
LayerEffectEntity.EffectType = GetType().FullName;
|
||||
LayerEffectEntity.Name = Name;
|
||||
LayerEffectEntity.Suspended = Suspended;
|
||||
LayerEffectEntity.HasBeenRenamed = HasBeenRenamed;
|
||||
LayerEffectEntity.Order = Order;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Artemis.Core.LayerEffects
|
||||
/// Represents an effect that applies preprocessing and/or postprocessing to a layer
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class LayerEffect<T> : BaseLayerEffect where T : LayerPropertyGroup
|
||||
public abstract class LayerEffect<T> : BaseLayerEffect where T : LayerEffectPropertyGroup, new()
|
||||
{
|
||||
private T _properties = null!;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Artemis.Core.LayerEffects
|
||||
public bool PropertiesInitialized { get; internal set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override LayerPropertyGroup BaseProperties => Properties;
|
||||
public override LayerEffectPropertyGroup BaseProperties => Properties;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the properties of this effect.
|
||||
@@ -32,19 +32,22 @@ namespace Artemis.Core.LayerEffects
|
||||
}
|
||||
internal set => _properties = value;
|
||||
}
|
||||
|
||||
internal void InitializeProperties()
|
||||
{
|
||||
Properties = Activator.CreateInstance<T>();
|
||||
Properties.Initialize(ProfileElement, null, new PropertyGroupDescriptionAttribute(){Identifier = "LayerEffect"}, LayerEffectEntity.PropertyGroup);
|
||||
PropertiesInitialized = true;
|
||||
|
||||
EnableLayerEffect();
|
||||
}
|
||||
|
||||
|
||||
internal override void Initialize()
|
||||
{
|
||||
InitializeProperties();
|
||||
}
|
||||
|
||||
private void InitializeProperties()
|
||||
{
|
||||
Properties = new T();
|
||||
Properties.Initialize(ProfileElement, null, new PropertyGroupDescriptionAttribute {Identifier = "LayerEffect"}, LayerEffectEntity.PropertyGroup);
|
||||
|
||||
// Initialize will call PopulateDefaults but that is for plugin developers so can't rely on that to default IsEnabled to true
|
||||
Properties.InitializeIsEnabled();
|
||||
PropertiesInitialized = true;
|
||||
|
||||
EnableLayerEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,116 +1,111 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Artemis.Core.LayerEffects.Placeholder;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
using Ninject;
|
||||
|
||||
namespace Artemis.Core.LayerEffects
|
||||
namespace Artemis.Core.LayerEffects;
|
||||
|
||||
/// <summary>
|
||||
/// A class that describes a layer effect
|
||||
/// </summary>
|
||||
public class LayerEffectDescriptor
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that describes a layer effect
|
||||
/// </summary>
|
||||
public class LayerEffectDescriptor
|
||||
internal LayerEffectDescriptor(string displayName, string description, string icon, Type layerEffectType, LayerEffectProvider provider)
|
||||
{
|
||||
internal LayerEffectDescriptor(string displayName, string description, string icon, Type? layerEffectType, LayerEffectProvider provider)
|
||||
DisplayName = displayName;
|
||||
Description = description;
|
||||
Icon = icon;
|
||||
LayerEffectType = layerEffectType ?? throw new ArgumentNullException(nameof(layerEffectType));
|
||||
Provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
internal LayerEffectDescriptor(string placeholderFor, LayerEffectProvider provider)
|
||||
{
|
||||
PlaceholderFor = placeholderFor ?? throw new ArgumentNullException(nameof(placeholderFor));
|
||||
Provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
DisplayName = "Missing effect";
|
||||
Description = "This effect could not be loaded";
|
||||
Icon = "FileQuestion";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name that is displayed in the UI
|
||||
/// </summary>
|
||||
public string DisplayName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The description that is displayed in the UI
|
||||
/// </summary>
|
||||
public string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Material icon to display in the UI, a full reference can be found
|
||||
/// <see href="https://materialdesignicons.com">here</see>
|
||||
/// </summary>
|
||||
public string Icon { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of the layer effect
|
||||
/// </summary>
|
||||
public Type? LayerEffectType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The plugin that provided this <see cref="LayerEffectDescriptor" />
|
||||
/// </summary>
|
||||
public LayerEffectProvider Provider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GUID this descriptor is acting as a placeholder for. If null, this descriptor is not a placeholder
|
||||
/// </summary>
|
||||
public string? PlaceholderFor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the described effect and applies it to the render element
|
||||
/// </summary>
|
||||
public BaseLayerEffect CreateInstance(RenderProfileElement renderElement, LayerEffectEntity? entity)
|
||||
{
|
||||
if (PlaceholderFor != null)
|
||||
{
|
||||
DisplayName = displayName;
|
||||
Description = description;
|
||||
Icon = icon;
|
||||
LayerEffectType = layerEffectType;
|
||||
Provider = provider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name that is displayed in the UI
|
||||
/// </summary>
|
||||
public string DisplayName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The description that is displayed in the UI
|
||||
/// </summary>
|
||||
public string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Material icon to display in the UI, a full reference can be found
|
||||
/// <see href="https://materialdesignicons.com">here</see>
|
||||
/// </summary>
|
||||
public string Icon { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of the layer effect
|
||||
/// </summary>
|
||||
public Type? LayerEffectType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The plugin that provided this <see cref="LayerEffectDescriptor" />
|
||||
/// </summary>
|
||||
public LayerEffectProvider Provider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GUID this descriptor is acting as a placeholder for. If null, this descriptor is not a placeholder
|
||||
/// </summary>
|
||||
public string? PlaceholderFor { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the described effect and applies it to the render element
|
||||
/// </summary>
|
||||
internal void CreateInstance(RenderProfileElement renderElement, LayerEffectEntity? entity)
|
||||
{
|
||||
if (LayerEffectType == null)
|
||||
throw new ArtemisCoreException("Cannot create an instance of a layer effect because this descriptor is not a placeholder but is still missing its LayerEffectType");
|
||||
|
||||
if (entity == null)
|
||||
{
|
||||
entity = new LayerEffectEntity
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Suspended = false,
|
||||
Order = renderElement.LayerEffects.Count + 1,
|
||||
ProviderId = Provider.Id,
|
||||
EffectType = LayerEffectType.FullName
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip effects already on the element
|
||||
if (renderElement.LayerEffects.Any(e => e.LayerEffectEntity.Id == entity.Id))
|
||||
return;
|
||||
}
|
||||
throw new ArtemisCoreException("Cannot create a placeholder for a layer effect that wasn't loaded from an entity");
|
||||
|
||||
if (PlaceholderFor != null)
|
||||
{
|
||||
CreatePlaceHolderInstance(renderElement, entity);
|
||||
return;
|
||||
}
|
||||
|
||||
BaseLayerEffect effect = (BaseLayerEffect) Provider.Plugin.Kernel!.Get(LayerEffectType);
|
||||
effect.ProfileElement = renderElement;
|
||||
effect.LayerEffectEntity = entity;
|
||||
effect.Order = entity.Order;
|
||||
effect.Name = entity.Name;
|
||||
effect.Suspended = entity.Suspended;
|
||||
effect.Descriptor = this;
|
||||
|
||||
effect.Initialize();
|
||||
effect.Update(0);
|
||||
|
||||
renderElement.ActivateLayerEffect(effect);
|
||||
return CreatePlaceHolderInstance(renderElement, entity);
|
||||
}
|
||||
|
||||
private void CreatePlaceHolderInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
|
||||
if (LayerEffectType == null)
|
||||
throw new ArtemisCoreException("Cannot create an instance of a layer effect because this descriptor is not a placeholder but is still missing its LayerEffectType");
|
||||
|
||||
BaseLayerEffect effect = (BaseLayerEffect) Provider.Plugin.Kernel!.Get(LayerEffectType);
|
||||
effect.ProfileElement = renderElement;
|
||||
effect.Descriptor = this;
|
||||
if (entity != null)
|
||||
{
|
||||
if (PlaceholderFor == null)
|
||||
throw new ArtemisCoreException("Cannot create a placeholder instance using a layer effect descriptor that is not a placeholder for anything");
|
||||
PlaceholderLayerEffect effect = new(entity, PlaceholderFor)
|
||||
{
|
||||
ProfileElement = renderElement,
|
||||
Descriptor = this
|
||||
};
|
||||
effect.LayerEffectEntity = entity;
|
||||
effect.Load();
|
||||
effect.Initialize();
|
||||
renderElement.ActivateLayerEffect(effect);
|
||||
|
||||
if (renderElement.ShouldBeEnabled)
|
||||
effect.InternalEnable();
|
||||
}
|
||||
else
|
||||
{
|
||||
effect.LayerEffectEntity = new LayerEffectEntity();
|
||||
effect.Initialize();
|
||||
effect.Save();
|
||||
}
|
||||
|
||||
return effect;
|
||||
}
|
||||
|
||||
private BaseLayerEffect CreatePlaceHolderInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
|
||||
{
|
||||
if (PlaceholderFor == null)
|
||||
throw new ArtemisCoreException("Cannot create a placeholder instance using a layer effect descriptor that is not a placeholder for anything");
|
||||
|
||||
PlaceholderLayerEffect effect = new(entity, PlaceholderFor)
|
||||
{
|
||||
ProfileElement = renderElement,
|
||||
Descriptor = this
|
||||
};
|
||||
effect.Initialize();
|
||||
|
||||
return effect;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@ namespace Artemis.Core.LayerEffects.Placeholder
|
||||
LayerEffectEntity = originalEntity;
|
||||
Order = OriginalEntity.Order;
|
||||
Name = OriginalEntity.Name;
|
||||
Suspended = OriginalEntity.Suspended;
|
||||
HasBeenRenamed = OriginalEntity.HasBeenRenamed;
|
||||
}
|
||||
|
||||
@@ -58,7 +57,7 @@ namespace Artemis.Core.LayerEffects.Placeholder
|
||||
/// <summary>
|
||||
/// This is in place so that the UI has something to show
|
||||
/// </summary>
|
||||
internal class PlaceholderProperties : LayerPropertyGroup
|
||||
internal class PlaceholderProperties : LayerEffectPropertyGroup
|
||||
{
|
||||
protected override void PopulateDefaults()
|
||||
{
|
||||
|
||||
+1
-5
@@ -4,11 +4,7 @@
|
||||
{
|
||||
public static LayerEffectDescriptor Create(string missingProviderId)
|
||||
{
|
||||
LayerEffectDescriptor descriptor = new("Missing effect", "This effect could not be loaded", "FileQuestion", null, Constants.EffectPlaceholderPlugin)
|
||||
{
|
||||
PlaceholderFor = missingProviderId
|
||||
};
|
||||
|
||||
LayerEffectDescriptor descriptor = new(missingProviderId, Constants.EffectPlaceholderPlugin);
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Artemis.Core.Modules
|
||||
/// <summary>
|
||||
/// Allows you to add new data to the Artemis data model
|
||||
/// </summary>
|
||||
public abstract class Module<T> : Module where T : DataModel
|
||||
public abstract class Module<T> : Module where T : DataModel, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// The data model driving this module
|
||||
@@ -79,7 +79,7 @@ namespace Artemis.Core.Modules
|
||||
|
||||
internal override void InternalEnable()
|
||||
{
|
||||
DataModel = Activator.CreateInstance<T>();
|
||||
DataModel = new T();
|
||||
DataModel.Module = this;
|
||||
DataModel.DataModelDescription = GetDataModelDescription();
|
||||
base.InternalEnable();
|
||||
@@ -310,7 +310,7 @@ namespace Artemis.Core.Modules
|
||||
/// <inheritdoc />
|
||||
internal override void InternalEnable()
|
||||
{
|
||||
foreach ((DefaultCategoryName categoryName, var path) in _pendingDefaultProfilePaths)
|
||||
foreach ((DefaultCategoryName categoryName, string? path) in _pendingDefaultProfilePaths)
|
||||
AddDefaultProfile(categoryName, path);
|
||||
_pendingDefaultProfilePaths.Clear();
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public void SaveAllSettings()
|
||||
{
|
||||
foreach (var (_, pluginSetting) in _settingEntities)
|
||||
foreach ((string _, IPluginSetting? pluginSetting) in _settingEntities)
|
||||
pluginSetting.Save();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user