Core - Refactored effects

Profile editor - Added effect creation
This commit is contained in:
Robert committed 2022-04-23 17:07:04 +02:00
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()
{
@@ -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;
}
}
+3 -3
View File
@@ -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();
}