Core - Added stores for the different register-able types

Profiles - Refactored large parts of the profile structure to use these stores
This commit is contained in:
Robert committed 2020-09-09 17:28:55 +02:00
1 parent 1e52bc5b31
commit 86ff4497f3
75 files changed
+1526 -934

No files matched your search

@@ -60,7 +60,6 @@ namespace Artemis.Core
/// <returns></returns>
public abstract bool EvaluateObject(object target);
internal abstract void Initialize(IDataModelService dataModelService);
internal abstract void ApplyToEntity();
internal abstract DisplayConditionPartEntity GetEntity();
}
@@ -2,18 +2,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Artemis.Core.Services;
namespace Artemis.Core
{
/// <summary>
/// A display condition operator is used by the conditions system to perform a specific boolean check
/// A condition operator is used by the conditions system to perform a specific boolean check
/// </summary>
public abstract class DisplayConditionOperator
public abstract class ConditionOperator
{
private IDataModelService _dataModelService;
private bool _registered;
/// <summary>
/// Gets the plugin info this condition operator belongs to
/// <para>Note: Not set until after registering</para>
@@ -57,35 +53,5 @@ namespace Artemis.Core
/// <param name="rightSide">The parameter on the right side of the expression</param>
/// <returns></returns>
public abstract BinaryExpression CreateExpression(Expression leftSide, Expression rightSide);
internal void Register(PluginInfo pluginInfo, IDataModelService dataModelService)
{
if (_registered)
return;
PluginInfo = pluginInfo;
_dataModelService = dataModelService;
if (PluginInfo != Constants.CorePluginInfo)
PluginInfo.Instance.PluginDisabled += InstanceOnPluginDisabled;
_registered = true;
}
internal void Unsubscribe()
{
if (!_registered)
return;
if (PluginInfo != Constants.CorePluginInfo)
PluginInfo.Instance.PluginDisabled -= InstanceOnPluginDisabled;
_registered = false;
}
private void InstanceOnPluginDisabled(object sender, EventArgs e)
{
// The service will call Unsubscribe
_dataModelService.RemoveConditionOperator(this);
}
}
}
@@ -1,6 +1,5 @@
using System;
using System.Linq;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
@@ -108,12 +107,6 @@ namespace Artemis.Core
child.ApplyToEntity();
}
internal override void Initialize(IDataModelService dataModelService)
{
foreach (var child in Children)
child.Initialize(dataModelService);
}
internal override DisplayConditionPartEntity GetEntity()
{
return Entity;
@@ -3,7 +3,6 @@ using System.Collections;
using System.Linq;
using System.Linq.Expressions;
using Artemis.Core.DataModelExpansions;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
@@ -15,6 +14,8 @@ namespace Artemis.Core
{
Parent = parent;
Entity = new DisplayConditionListEntity();
Initialize();
}
public DisplayConditionList(DisplayConditionPart parent, DisplayConditionListEntity entity)
@@ -22,6 +23,8 @@ namespace Artemis.Core
Parent = parent;
Entity = entity;
ListOperator = (ListOperator) entity.ListOperator;
Initialize();
}
public DisplayConditionListEntity Entity { get; set; }
@@ -120,13 +123,13 @@ namespace Artemis.Core
return Entity;
}
internal override void Initialize(IDataModelService dataModelService)
internal void Initialize()
{
if (Entity.ListDataModelGuid == null)
return;
// Get the data model and ensure the path is valid
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.ListDataModelGuid.Value);
var dataModel = DataModelStore.Get(Entity.ListDataModelGuid.Value)?.DataModel;
if (dataModel == null || !dataModel.ContainsPath(Entity.ListPropertyPath))
return;
@@ -143,8 +146,6 @@ namespace Artemis.Core
Entity.Children.Clear();
AddChild(new DisplayConditionGroup(this));
}
Children[0].Initialize(dataModelService);
}
}
@@ -2,7 +2,6 @@
using System.Linq;
using System.Linq.Expressions;
using Artemis.Core.DataModelExpansions;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
using Newtonsoft.Json;
@@ -18,6 +17,7 @@ namespace Artemis.Core
Entity = new DisplayConditionListPredicateEntity();
ApplyParentList();
Initialize();
}
public DisplayConditionListPredicate(DisplayConditionPart parent, DisplayConditionListPredicateEntity entity)
@@ -27,12 +27,13 @@ namespace Artemis.Core
PredicateType = (ProfileRightSideType) entity.PredicateType;
ApplyParentList();
Initialize();
}
public DisplayConditionListPredicateEntity Entity { get; set; }
public ProfileRightSideType PredicateType { get; set; }
public DisplayConditionOperator Operator { get; private set; }
public ConditionOperator Operator { get; private set; }
public Type ListType { get; private set; }
public DataModel ListDataModel { get; private set; }
@@ -120,9 +121,9 @@ namespace Artemis.Core
CreateExpression();
}
public void UpdateOperator(DisplayConditionOperator displayConditionOperator)
public void UpdateOperator(ConditionOperator conditionOperator)
{
if (displayConditionOperator == null)
if (conditionOperator == null)
{
Operator = null;
return;
@@ -130,13 +131,13 @@ namespace Artemis.Core
if (LeftPropertyPath == null)
{
Operator = displayConditionOperator;
Operator = conditionOperator;
return;
}
var leftType = GetTypeAtInnerPath(LeftPropertyPath);
if (displayConditionOperator.SupportsType(leftType))
Operator = displayConditionOperator;
if (conditionOperator.SupportsType(leftType))
Operator = conditionOperator;
CreateExpression();
}
@@ -203,7 +204,7 @@ namespace Artemis.Core
Entity.OperatorType = Operator?.GetType().Name;
}
internal override void Initialize(IDataModelService dataModelService)
internal void Initialize()
{
// Left side
if (Entity.LeftPropertyPath != null && ListContainsInnerPath(Entity.LeftPropertyPath))
@@ -212,7 +213,7 @@ namespace Artemis.Core
// Operator
if (Entity.OperatorPluginGuid != null)
{
var conditionOperator = dataModelService.GetConditionOperator(Entity.OperatorPluginGuid.Value, Entity.OperatorType);
var conditionOperator = ConditionOperatorStore.Get(Entity.OperatorPluginGuid.Value, Entity.OperatorType)?.ConditionOperator;
if (conditionOperator != null)
UpdateOperator(conditionOperator);
}
@@ -241,7 +242,7 @@ namespace Artemis.Core
// If deserialization fails, use the type's default
catch (JsonSerializationException e)
{
dataModelService.LogListPredicateDeserializationFailure(this, e);
DeserializationLogger.LogListPredicateDeserializationFailure(this, e);
rightSideValue = Activator.CreateInstance(leftSideType);
}
@@ -255,7 +256,7 @@ namespace Artemis.Core
}
catch (JsonException e)
{
dataModelService.LogListPredicateDeserializationFailure(this, e);
DeserializationLogger.LogListPredicateDeserializationFailure(this, e);
}
}
}
@@ -2,7 +2,6 @@
using System.Linq;
using System.Linq.Expressions;
using Artemis.Core.DataModelExpansions;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
using Newtonsoft.Json;
@@ -25,6 +24,8 @@ namespace Artemis.Core
Parent = parent;
PredicateType = predicateType;
Entity = new DisplayConditionPredicateEntity();
Initialize();
}
/// <summary>
@@ -37,6 +38,8 @@ namespace Artemis.Core
Parent = parent;
Entity = entity;
PredicateType = (ProfileRightSideType) entity.PredicateType;
Initialize();
}
/// <summary>
@@ -47,7 +50,7 @@ namespace Artemis.Core
/// <summary>
/// Gets the operator
/// </summary>
public DisplayConditionOperator Operator { get; private set; }
public ConditionOperator Operator { get; private set; }
/// <summary>
/// Gets the currently used instance of the left data model
@@ -175,11 +178,11 @@ namespace Artemis.Core
/// <summary>
/// Updates the operator of the predicate and re-compiles the expression
/// </summary>
/// <param name="displayConditionOperator"></param>
public void UpdateOperator(DisplayConditionOperator displayConditionOperator)
/// <param name="conditionOperator"></param>
public void UpdateOperator(ConditionOperator conditionOperator)
{
// Calling CreateExpression will clear compiled expressions
if (displayConditionOperator == null)
if (conditionOperator == null)
{
Operator = null;
CreateExpression();
@@ -189,18 +192,18 @@ namespace Artemis.Core
// No need to clear compiled expressions, without a left data model they are already null
if (LeftDataModel == null)
{
Operator = displayConditionOperator;
Operator = conditionOperator;
return;
}
var leftType = LeftDataModel.GetTypeAtPath(LeftPropertyPath);
if (!displayConditionOperator.SupportsType(leftType))
if (!conditionOperator.SupportsType(leftType))
{
throw new ArtemisCoreException($"Cannot apply operator {displayConditionOperator.GetType().Name} to this predicate because " +
throw new ArtemisCoreException($"Cannot apply operator {conditionOperator.GetType().Name} to this predicate because " +
$"it does not support left side type {leftType.Name}");
}
Operator = displayConditionOperator;
Operator = conditionOperator;
CreateExpression();
}
@@ -243,12 +246,12 @@ namespace Artemis.Core
Entity.OperatorType = Operator?.GetType().Name;
}
internal override void Initialize(IDataModelService dataModelService)
internal void Initialize()
{
// Left side
if (Entity.LeftDataModelGuid != null)
{
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.LeftDataModelGuid.Value);
var dataModel = DataModelStore.Get(Entity.LeftDataModelGuid.Value)?.DataModel;
if (dataModel != null && dataModel.ContainsPath(Entity.LeftPropertyPath))
UpdateLeftSide(dataModel, Entity.LeftPropertyPath);
}
@@ -256,7 +259,7 @@ namespace Artemis.Core
// Operator
if (Entity.OperatorPluginGuid != null)
{
var conditionOperator = dataModelService.GetConditionOperator(Entity.OperatorPluginGuid.Value, Entity.OperatorType);
var conditionOperator = ConditionOperatorStore.Get(Entity.OperatorPluginGuid.Value, Entity.OperatorType)?.ConditionOperator;
if (conditionOperator != null)
UpdateOperator(conditionOperator);
}
@@ -264,7 +267,7 @@ namespace Artemis.Core
// Right side dynamic
if (PredicateType == ProfileRightSideType.Dynamic && Entity.RightDataModelGuid != null)
{
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.RightDataModelGuid.Value);
var dataModel = DataModelStore.Get(Entity.RightDataModelGuid.Value)?.DataModel;
if (dataModel != null && dataModel.ContainsPath(Entity.RightPropertyPath))
UpdateRightSide(dataModel, Entity.RightPropertyPath);
}
@@ -286,7 +289,7 @@ namespace Artemis.Core
// If deserialization fails, use the type's default
catch (JsonSerializationException e)
{
dataModelService.LogPredicateDeserializationFailure(this, e);
DeserializationLogger.LogPredicateDeserializationFailure(this, e);
rightSideValue = Activator.CreateInstance(leftSideType);
}
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
internal class EqualsConditionOperator : DisplayConditionOperator
internal class EqualsConditionOperator : ConditionOperator
{
public override IReadOnlyCollection<Type> CompatibleTypes => new List<Type> {typeof(object)};
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
internal class GreaterThanConditionOperator : DisplayConditionOperator
internal class GreaterThanConditionOperator : ConditionOperator
{
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
internal class GreaterThanOrEqualConditionOperator : DisplayConditionOperator
internal class GreaterThanOrEqualConditionOperator : ConditionOperator
{
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
internal class LessThanConditionOperator : DisplayConditionOperator
internal class LessThanConditionOperator : ConditionOperator
{
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
internal class LessThanOrEqualConditionOperator : DisplayConditionOperator
internal class LessThanOrEqualConditionOperator : ConditionOperator
{
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
internal class NotEqualConditionOperator : DisplayConditionOperator
internal class NotEqualConditionOperator : ConditionOperator
{
public override IReadOnlyCollection<Type> CompatibleTypes => new List<Type> {typeof(object)};
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
internal class StringContainsConditionOperator : DisplayConditionOperator
internal class StringContainsConditionOperator : ConditionOperator
{
private readonly MethodInfo _contains;
private readonly MethodInfo _toLower;
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
internal class StringEndsWithConditionOperator : DisplayConditionOperator
internal class StringEndsWithConditionOperator : ConditionOperator
{
private readonly MethodInfo _endsWith;
private readonly MethodInfo _toLower;
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
internal class StringEqualsConditionOperator : DisplayConditionOperator
internal class StringEqualsConditionOperator : ConditionOperator
{
private readonly MethodInfo _toLower;
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
internal class StringNotContainsConditionOperator : DisplayConditionOperator
internal class StringNotContainsConditionOperator : ConditionOperator
{
private readonly MethodInfo _contains;
private readonly MethodInfo _toLower;
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
internal class StringNotEqualConditionOperator : DisplayConditionOperator
internal class StringNotEqualConditionOperator : ConditionOperator
{
private readonly MethodInfo _toLower;
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
internal class StringNullConditionOperator : DisplayConditionOperator
internal class StringNullConditionOperator : ConditionOperator
{
public StringNullConditionOperator()
{
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
internal class StringStartsWithConditionOperator : DisplayConditionOperator
internal class StringStartsWithConditionOperator : ConditionOperator
{
private readonly MethodInfo _startsWith;
private readonly MethodInfo _toLower;
+24 -25
View File
@@ -42,21 +42,7 @@ namespace Artemis.Core
_layerEffects = new List<BaseLayerEffect>();
_expandedPropertyGroups = new List<string>();
_expandedPropertyGroups.AddRange(folderEntity.ExpandedPropertyGroups);
// Load child folders
foreach (var childFolder in Profile.ProfileEntity.Folders.Where(f => f.ParentId == EntityId))
ChildrenList.Add(new Folder(profile, this, childFolder));
// Load child layers
foreach (var childLayer in Profile.ProfileEntity.Layers.Where(f => f.ParentId == EntityId))
ChildrenList.Add(new Layer(profile, this, childLayer));
// Ensure order integrity, should be unnecessary but no one is perfect specially me
ChildrenList = ChildrenList.OrderBy(c => c.Order).ToList();
for (var index = 0; index < ChildrenList.Count; index++)
ChildrenList[index].Order = index + 1;
ApplyRenderElementEntity();
Load();
}
internal FolderEntity FolderEntity { get; set; }
@@ -263,23 +249,36 @@ namespace Artemis.Core
if (!disposing)
return;
_disposed = true;
foreach (var baseLayerEffect in LayerEffects)
baseLayerEffect.Dispose();
_layerEffects.Clear();
foreach (var profileElement in Children)
profileElement.Dispose();
ChildrenList.Clear();
_folderBitmap?.Dispose();
_folderBitmap = null;
Profile = null;
_disposed = true;
}
internal override void Load()
{
_expandedPropertyGroups.AddRange(FolderEntity.ExpandedPropertyGroups);
internal override void ApplyToEntity()
// Load child folders
foreach (var childFolder in Profile.ProfileEntity.Folders.Where(f => f.ParentId == EntityId))
ChildrenList.Add(new Folder(Profile, this, childFolder));
// Load child layers
foreach (var childLayer in Profile.ProfileEntity.Layers.Where(f => f.ParentId == EntityId))
ChildrenList.Add(new Layer(Profile, this, childLayer));
// Ensure order integrity, should be unnecessary but no one is perfect specially me
ChildrenList = ChildrenList.OrderBy(c => c.Order).ToList();
for (var index = 0; index < ChildrenList.Count; index++)
ChildrenList[index].Order = index + 1;
LoadRenderElement();
}
internal override void Save()
{
if (_disposed)
throw new ObjectDisposedException("Folder");
@@ -295,11 +294,11 @@ namespace Artemis.Core
FolderEntity.ExpandedPropertyGroups.Clear();
FolderEntity.ExpandedPropertyGroups.AddRange(_expandedPropertyGroups);
ApplyRenderElementToEntity();
// Conditions
RenderElementEntity.RootDisplayCondition = DisplayConditionGroup?.Entity;
DisplayConditionGroup?.ApplyToEntity();
SaveRenderElement();
}
#region Events
+77 -36
View File
@@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
using System.Linq;
using Artemis.Core.LayerBrushes;
using Artemis.Core.LayerEffects;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Entities.Profile.Abstract;
using SkiaSharp;
@@ -41,30 +40,27 @@ namespace Artemis.Core
_leds = new List<ArtemisLed>();
_expandedPropertyGroups = new List<string>();
General.PropertyGroupInitialized += GeneralOnPropertyGroupInitialized;
InitializeDefaultGroups();
parent.AddChild(this);
ApplyRenderElementDefaults();
}
internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity)
{
LayerEntity = layerEntity;
EntityId = layerEntity.Id;
Profile = profile;
Parent = parent;
Name = layerEntity.Name;
Enabled = layerEntity.Enabled;
Order = layerEntity.Order;
General = new LayerGeneralProperties();
Transform = new LayerTransformProperties();
_layerEffects = new List<BaseLayerEffect>();
_leds = new List<ArtemisLed>();
_expandedPropertyGroups = new List<string>();
_expandedPropertyGroups.AddRange(layerEntity.ExpandedPropertyGroups);
General.PropertyGroupInitialized += GeneralOnPropertyGroupInitialized;
ApplyRenderElementEntity();
InitializeDefaultGroups();
Load();
}
internal LayerEntity LayerEntity { get; set; }
@@ -128,25 +124,41 @@ namespace Artemis.Core
// Brush first in case it depends on any of the other disposables during it's own disposal
_layerBrush?.Dispose();
_layerBrush = null;
foreach (var baseLayerEffect in LayerEffects)
baseLayerEffect.Dispose();
_layerEffects.Clear();
_general?.Dispose();
_general = null;
_layerBitmap?.Dispose();
_layerBitmap = null;
_transform?.Dispose();
_transform = null;
}
Profile = null;
private void InitializeDefaultGroups()
{
// Layers have two hardcoded property groups, instantiate them
General.Initialize(this, "General.", Constants.CorePluginInfo);
Transform.Initialize(this, "Transform.", Constants.CorePluginInfo);
General.ShapeType.BaseValueChanged += ShapeTypeOnBaseValueChanged;
ApplyShapeType();
}
#region Storage
internal override void ApplyToEntity()
internal override void Load()
{
EntityId = LayerEntity.Id;
Name = LayerEntity.Name;
Enabled = LayerEntity.Enabled;
Order = LayerEntity.Order;
_expandedPropertyGroups.AddRange(LayerEntity.ExpandedPropertyGroups);
ActivateLayerBrush();
LoadRenderElement();
}
internal override void Save()
{
if (_disposed)
throw new ObjectDisposedException("Layer");
@@ -181,20 +193,13 @@ namespace Artemis.Core
RenderElementEntity.RootDisplayCondition = DisplayConditionGroup?.Entity;
DisplayConditionGroup?.ApplyToEntity();
ApplyRenderElementToEntity();
SaveRenderElement();
}
#endregion
#region Shape management
private void GeneralOnPropertyGroupInitialized(object sender, EventArgs e)
{
ApplyShapeType();
General.ShapeType.BaseValueChanged -= ShapeTypeOnBaseValueChanged;
General.ShapeType.BaseValueChanged += ShapeTypeOnBaseValueChanged;
}
private void ShapeTypeOnBaseValueChanged(object sender, EventArgs e)
{
ApplyShapeType();
@@ -290,7 +295,7 @@ namespace Artemis.Core
baseLayerEffect.Update(delta);
}
}
/// <inheritdoc />
public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo)
{
@@ -646,7 +651,51 @@ namespace Artemis.Core
#endregion
#region Activation
#region Brush management
/// <summary>
/// Changes the current layer brush to the brush described in the provided <paramref name="descriptor" />
/// </summary>
public void ChangeLayerBrush(LayerBrushDescriptor descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
// Ensure the brush reference matches the brush
var current = General.BrushReference.CurrentValue;
if (current.BrushPluginGuid != descriptor.LayerBrushProvider.PluginInfo.Guid || current.BrushType != descriptor.LayerBrushType.Name)
{
General.BrushReference.CurrentValue = new LayerBrushReference
{
BrushPluginGuid = descriptor.LayerBrushProvider.PluginInfo.Guid,
BrushType = descriptor.LayerBrushType.Name
};
}
ActivateLayerBrush();
}
/// <summary>
/// Removes the current layer brush from the layer
/// </summary>
public void RemoveLayerBrush()
{
if (LayerBrush == null)
return;
var brush = LayerBrush;
DeactivateLayerBrush();
LayerEntity.PropertyEntities.RemoveAll(p => p.PluginGuid == brush.PluginInfo.Guid && p.Path.StartsWith("LayerBrush."));
}
internal void ActivateLayerBrush()
{
var current = General.BrushReference.CurrentValue;
var descriptor = LayerBrushStore.Get(current.BrushPluginGuid, current.BrushType)?.LayerBrushDescriptor;
descriptor?.CreateInstance(this);
OnLayerBrushUpdated();
}
internal void DeactivateLayerBrush()
{
@@ -656,16 +705,8 @@ namespace Artemis.Core
var brush = LayerBrush;
LayerBrush = null;
brush.Dispose();
}
internal void RemoveLayerBrush()
{
if (LayerBrush == null)
return;
var brush = LayerBrush;
DeactivateLayerBrush();
LayerEntity.PropertyEntities.RemoveAll(p => p.PluginGuid == brush.PluginInfo.Guid && p.Path.StartsWith("LayerBrush."));
OnLayerBrushUpdated();
}
#endregion
@@ -171,14 +171,6 @@ namespace Artemis.Core
OnPropertyGroupInitialized();
}
internal void InitializeDataBindings(IDataModelService dataModelService, IDataModelService dataModelService1)
{
foreach (var layerProperty in LayerProperties)
{
layerProperty.InitializeDataBindings(dataModelService);
}
}
internal void ApplyToEntity()
{
if (!PropertiesInitialized)
+3 -3
View File
@@ -22,7 +22,7 @@ namespace Artemis.Core
RedoStack = new Stack<string>();
AddChild(new Folder(this, this, "Root folder"));
ApplyToEntity();
Save();
}
internal Profile(ProfileModule module, ProfileEntity profileEntity)
@@ -129,7 +129,7 @@ namespace Artemis.Core
_disposed = true;
}
internal override void ApplyToEntity()
internal override void Save()
{
if (_disposed)
throw new ObjectDisposedException("Profile");
@@ -140,7 +140,7 @@ namespace Artemis.Core
ProfileEntity.IsActive = IsActivated;
foreach (var profileElement in Children)
profileElement.ApplyToEntity();
profileElement.Save();
ProfileEntity.Folders.Clear();
ProfileEntity.Folders.AddRange(GetAllFolders().Select(f => f.FolderEntity));
@@ -23,18 +23,27 @@ namespace Artemis.Core
ChildrenList = new List<ProfileElement>();
}
/// <summary>
/// Gets the unique ID of this profile element
/// </summary>
public Guid EntityId
{
get => _entityId;
internal set => SetAndNotify(ref _entityId, value);
}
/// <summary>
/// Gets the profile this element belongs to
/// </summary>
public Profile Profile
{
get => _profile;
internal set => SetAndNotify(ref _profile, value);
}
/// <summary>
/// Gets the parent of this element
/// </summary>
public ProfileElement Parent
{
get => _parent;
@@ -73,12 +82,6 @@ namespace Artemis.Core
set => SetAndNotify(ref _enabled, value);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Updates the element
/// </summary>
@@ -90,39 +93,13 @@ namespace Artemis.Core
/// </summary>
public abstract void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo);
public List<Folder> GetAllFolders()
/// <inheritdoc />
public override string ToString()
{
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
var folders = new List<Folder>();
foreach (var childFolder in Children.Where(c => c is Folder).Cast<Folder>())
{
// Add all folders in this element
folders.Add(childFolder);
// Add all folders in folders inside this element
folders.AddRange(childFolder.GetAllFolders());
}
return folders;
return $"{nameof(EntityId)}: {EntityId}, {nameof(Order)}: {Order}, {nameof(Name)}: {Name}";
}
public List<Layer> GetAllLayers()
{
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
var layers = new List<Layer>();
// Add all layers in this element
layers.AddRange(Children.Where(c => c is Layer).Cast<Layer>());
// Add all layers in folders inside this element
foreach (var childFolder in Children.Where(c => c is Folder).Cast<Folder>())
layers.AddRange(childFolder.GetAllLayers());
return layers;
}
#region Hierarchy
/// <summary>
/// Adds a profile element to the <see cref="Children" /> collection, optionally at the given position (1-based)
@@ -189,9 +166,64 @@ namespace Artemis.Core
OnChildRemoved();
}
public override string ToString()
/// <summary>
/// Returns a flattened list of all child folders
/// </summary>
/// <returns></returns>
public List<Folder> GetAllFolders()
{
return $"{nameof(EntityId)}: {EntityId}, {nameof(Order)}: {Order}, {nameof(Name)}: {Name}";
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
var folders = new List<Folder>();
foreach (var childFolder in Children.Where(c => c is Folder).Cast<Folder>())
{
// Add all folders in this element
folders.Add(childFolder);
// Add all folders in folders inside this element
folders.AddRange(childFolder.GetAllFolders());
}
return folders;
}
/// <summary>
/// Returns a flattened list of all child layers
/// </summary>
/// <returns></returns>
public List<Layer> GetAllLayers()
{
if (_disposed)
throw new ObjectDisposedException(GetType().Name);
var layers = new List<Layer>();
// Add all layers in this element
layers.AddRange(Children.Where(c => c is Layer).Cast<Layer>());
// Add all layers in folders inside this element
foreach (var childFolder in Children.Where(c => c is Folder).Cast<Folder>())
layers.AddRange(childFolder.GetAllLayers());
return layers;
}
#endregion
#region Storage
internal abstract void Load();
internal abstract void Save();
#endregion
#region IDisposable
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
@@ -201,10 +233,7 @@ namespace Artemis.Core
}
}
/// <summary>
/// Applies the profile element's properties to the underlying storage entity
/// </summary>
internal abstract void ApplyToEntity();
#endregion
#region Events
@@ -12,21 +12,23 @@ namespace Artemis.Core
{
public abstract class RenderProfileElement : ProfileElement
{
protected void ApplyRenderElementDefaults()
internal void ApplyRenderElementDefaults()
{
MainSegmentLength = TimeSpan.FromSeconds(5);
}
protected void ApplyRenderElementEntity()
internal void LoadRenderElement()
{
StartSegmentLength = RenderElementEntity.StartSegmentLength;
MainSegmentLength = RenderElementEntity.MainSegmentLength;
EndSegmentLength = RenderElementEntity.EndSegmentLength;
DisplayContinuously = RenderElementEntity.DisplayContinuously;
AlwaysFinishTimeline = RenderElementEntity.AlwaysFinishTimeline;
ActivateEffects();
}
protected void ApplyRenderElementToEntity()
internal void SaveRenderElement()
{
RenderElementEntity.StartSegmentLength = StartSegmentLength;
RenderElementEntity.MainSegmentLength = MainSegmentLength;
@@ -206,7 +208,7 @@ namespace Artemis.Core
#endregion
#region Effects
#region Effect management
protected List<BaseLayerEffect> _layerEffects;
@@ -215,11 +217,35 @@ namespace Artemis.Core
/// </summary>
public ReadOnlyCollection<BaseLayerEffect> LayerEffects => _layerEffects.AsReadOnly();
internal void RemoveLayerEffect([NotNull] BaseLayerEffect effect)
/// <summary>
/// Adds a the layer effect described inthe provided <paramref name="descriptor" />
/// </summary>
public void AddLayerEffect(LayerEffectDescriptor descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var entity = new LayerEffectEntity
{
Id = Guid.NewGuid(),
Enabled = true,
Order = LayerEffects.Count + 1
};
descriptor.CreateInstance(this, entity);
OnLayerEffectsUpdated();
}
/// <summary>
/// Removes the provided layer
/// </summary>
/// <param name="effect"></param>
public void RemoveLayerEffect([NotNull] BaseLayerEffect effect)
{
if (effect == null) throw new ArgumentNullException(nameof(effect));
DeactivateLayerEffect(effect);
// Remove the effect from the layer and dispose it
_layerEffects.Remove(effect);
effect.Dispose();
// Update the order on the remaining effects
var index = 0;
@@ -232,20 +258,31 @@ namespace Artemis.Core
OnLayerEffectsUpdated();
}
internal void AddLayerEffect([NotNull] BaseLayerEffect effect)
internal void ActivateEffects()
{
if (effect == null) throw new ArgumentNullException(nameof(effect));
_layerEffects.Add(effect);
OnLayerEffectsUpdated();
foreach (var layerEffectEntity in RenderElementEntity.LayerEffects)
{
if (_layerEffects.Any(e => e.EntityId == layerEffectEntity.Id))
continue;
var descriptor = LayerEffectStore.Get(layerEffectEntity.PluginGuid, layerEffectEntity.EffectType)?.LayerEffectDescriptor;
descriptor?.CreateInstance(this, layerEffectEntity);
}
}
internal void DeactivateLayerEffect([NotNull] BaseLayerEffect effect)
internal void ActivateLayerEffect(BaseLayerEffect layerEffect)
{
if (effect == null) throw new ArgumentNullException(nameof(effect));
_layerEffects.Add(layerEffect);
// Remove the effect from the layer and dispose it
_layerEffects.Remove(effect);
effect.Dispose();
// Update the order on the effects
var index = 0;
foreach (var baseLayerEffect in LayerEffects.OrderBy(e => e.Order))
{
baseLayerEffect.Order = Order = index + 1;
index++;
}
OnLayerEffectsUpdated();
}
#endregion
@@ -296,6 +333,5 @@ namespace Artemis.Core
}
#endregion
}
}