mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Core - Nullable refactoring
Core - Nullable refactoring Core - Nullable refactoring (finish)
This commit is contained in:
parent
b185b28645
commit
fb3466e102
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Artemis.Storage.Entities.Plugins;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
@ -34,13 +35,13 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly PluginInfo CorePluginInfo = new PluginInfo
|
public static readonly PluginInfo CorePluginInfo = new PluginInfo
|
||||||
{
|
{
|
||||||
Guid = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"), Name = "Artemis Core"
|
Guid = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"), Name = "Artemis Core", Version = new Version(2,0)
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The plugin used by core components of Artemis
|
/// The plugin used by core components of Artemis
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Plugin CorePlugin = new Plugin(CorePluginInfo, new DirectoryInfo(ApplicationFolder));
|
public static readonly Plugin CorePlugin = new Plugin(CorePluginInfo, new DirectoryInfo(ApplicationFolder), null);
|
||||||
|
|
||||||
internal static readonly CorePluginFeature CorePluginFeature = new CorePluginFeature {Plugin = CorePlugin};
|
internal static readonly CorePluginFeature CorePluginFeature = new CorePluginFeature {Plugin = CorePlugin};
|
||||||
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new EffectPlaceholderPlugin {Plugin = CorePlugin};
|
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new EffectPlaceholderPlugin {Plugin = CorePlugin};
|
||||||
|
|||||||
@ -8,6 +8,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A static class providing <see cref="Process" /> extensions
|
/// A static class providing <see cref="Process" /> extensions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1060:Move pinvokes to native methods class", Justification = "I don't care, piss off")]
|
||||||
public static class ProcessExtensions
|
public static class ProcessExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -20,7 +20,7 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="parent">The parent of the folder</param>
|
/// <param name="parent">The parent of the folder</param>
|
||||||
/// <param name="name">The name of the folder</param>
|
/// <param name="name">The name of the folder</param>
|
||||||
public Folder(ProfileElement parent, string name)
|
public Folder(ProfileElement parent, string name) : base(parent.Profile)
|
||||||
{
|
{
|
||||||
FolderEntity = new FolderEntity();
|
FolderEntity = new FolderEntity();
|
||||||
EntityId = Guid.NewGuid();
|
EntityId = Guid.NewGuid();
|
||||||
@ -29,14 +29,11 @@ namespace Artemis.Core
|
|||||||
Profile = Parent.Profile;
|
Profile = Parent.Profile;
|
||||||
Name = name;
|
Name = name;
|
||||||
Enabled = true;
|
Enabled = true;
|
||||||
|
|
||||||
LayerEffectsList = new List<BaseLayerEffect>();
|
|
||||||
ExpandedPropertyGroups = new List<string>();
|
|
||||||
|
|
||||||
Parent.AddChild(this);
|
Parent.AddChild(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity)
|
internal Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity) : base(parent.Profile)
|
||||||
{
|
{
|
||||||
FolderEntity = folderEntity;
|
FolderEntity = folderEntity;
|
||||||
EntityId = folderEntity.Id;
|
EntityId = folderEntity.Id;
|
||||||
@ -46,10 +43,7 @@ namespace Artemis.Core
|
|||||||
Name = folderEntity.Name;
|
Name = folderEntity.Name;
|
||||||
Enabled = folderEntity.Enabled;
|
Enabled = folderEntity.Enabled;
|
||||||
Order = folderEntity.Order;
|
Order = folderEntity.Order;
|
||||||
|
|
||||||
LayerEffectsList = new List<BaseLayerEffect>();
|
|
||||||
ExpandedPropertyGroups = new List<string>();
|
|
||||||
|
|
||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="parent">The parent of the layer</param>
|
/// <param name="parent">The parent of the layer</param>
|
||||||
/// <param name="name">The name of the layer</param>
|
/// <param name="name">The name of the layer</param>
|
||||||
public Layer(ProfileElement parent, string name)
|
public Layer(ProfileElement parent, string name) : base(parent.Profile)
|
||||||
{
|
{
|
||||||
LayerEntity = new LayerEntity();
|
LayerEntity = new LayerEntity();
|
||||||
EntityId = Guid.NewGuid();
|
EntityId = Guid.NewGuid();
|
||||||
@ -39,16 +39,14 @@ namespace Artemis.Core
|
|||||||
Enabled = true;
|
Enabled = true;
|
||||||
_general = new LayerGeneralProperties();
|
_general = new LayerGeneralProperties();
|
||||||
_transform = new LayerTransformProperties();
|
_transform = new LayerTransformProperties();
|
||||||
|
|
||||||
LayerEffectsList = new List<BaseLayerEffect>();
|
|
||||||
_leds = new List<ArtemisLed>();
|
_leds = new List<ArtemisLed>();
|
||||||
ExpandedPropertyGroups = new List<string>();
|
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
Parent.AddChild(this);
|
Parent.AddChild(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity)
|
internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity) : base(parent.Profile)
|
||||||
{
|
{
|
||||||
LayerEntity = layerEntity;
|
LayerEntity = layerEntity;
|
||||||
EntityId = layerEntity.Id;
|
EntityId = layerEntity.Id;
|
||||||
@ -57,10 +55,8 @@ namespace Artemis.Core
|
|||||||
Parent = parent;
|
Parent = parent;
|
||||||
_general = new LayerGeneralProperties();
|
_general = new LayerGeneralProperties();
|
||||||
_transform = new LayerTransformProperties();
|
_transform = new LayerTransformProperties();
|
||||||
|
|
||||||
LayerEffectsList = new List<BaseLayerEffect>();
|
|
||||||
_leds = new List<ArtemisLed>();
|
_leds = new List<ArtemisLed>();
|
||||||
ExpandedPropertyGroups = new List<string>();
|
|
||||||
|
|
||||||
Load();
|
Load();
|
||||||
Initialize();
|
Initialize();
|
||||||
@ -263,17 +259,12 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void ApplyShapeType()
|
private void ApplyShapeType()
|
||||||
{
|
{
|
||||||
switch (General.ShapeType.CurrentValue)
|
LayerShape = General.ShapeType.CurrentValue switch
|
||||||
{
|
{
|
||||||
case LayerShapeType.Ellipse:
|
LayerShapeType.Ellipse => new EllipseShape(this),
|
||||||
LayerShape = new EllipseShape(this);
|
LayerShapeType.Rectangle => new RectangleShape(this),
|
||||||
break;
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
case LayerShapeType.Rectangle:
|
};
|
||||||
LayerShape = new RectangleShape(this);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -25,7 +25,13 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected LayerProperty()
|
protected LayerProperty()
|
||||||
{
|
{
|
||||||
// Cant define generic types as nullable ¯\_(ツ)_/¯
|
// These are set right after construction to keep the constructor (and inherited constructs) clean
|
||||||
|
ProfileElement = null!;
|
||||||
|
LayerPropertyGroup = null!;
|
||||||
|
Path = null!;
|
||||||
|
Entity = null!;
|
||||||
|
PropertyDescription = null!;
|
||||||
|
|
||||||
CurrentValue = default!;
|
CurrentValue = default!;
|
||||||
DefaultValue = default!;
|
DefaultValue = default!;
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Artemis.Core.LayerBrushes;
|
using Artemis.Core.LayerBrushes;
|
||||||
using Artemis.Core.LayerEffects;
|
using Artemis.Core.LayerEffects;
|
||||||
using Artemis.Core.Properties;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
|
|
||||||
@ -30,6 +29,12 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected LayerPropertyGroup()
|
protected LayerPropertyGroup()
|
||||||
{
|
{
|
||||||
|
// These are set right after construction to keep the constructor (and inherited constructs) clean
|
||||||
|
GroupDescription = null!;
|
||||||
|
Feature = null!;
|
||||||
|
ProfileElement = null!;
|
||||||
|
Path = null!;
|
||||||
|
|
||||||
_layerProperties = new List<ILayerProperty>();
|
_layerProperties = new List<ILayerProperty>();
|
||||||
_layerPropertyGroups = new List<LayerPropertyGroup>();
|
_layerPropertyGroups = new List<LayerPropertyGroup>();
|
||||||
}
|
}
|
||||||
@ -52,7 +57,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The parent group of this group
|
/// The parent group of this group
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerPropertyGroup Parent { get; internal set; }
|
public LayerPropertyGroup? Parent { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of this property group
|
/// The path of this property group
|
||||||
@ -67,12 +72,12 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The layer brush this property group belongs to
|
/// The layer brush this property group belongs to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BaseLayerBrush LayerBrush { get; internal set; }
|
public BaseLayerBrush? LayerBrush { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The layer effect this property group belongs to
|
/// The layer effect this property group belongs to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BaseLayerEffect LayerEffect { get; internal set; }
|
public BaseLayerEffect? LayerEffect { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets whether the property is hidden in the UI
|
/// Gets or sets whether the property is hidden in the UI
|
||||||
@ -139,19 +144,16 @@ namespace Artemis.Core
|
|||||||
PropertyGroupInitialized?.Invoke(this, EventArgs.Empty);
|
PropertyGroupInitialized?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Initialize(RenderProfileElement profileElement, [NotNull] string path, PluginFeature feature)
|
internal void Initialize(RenderProfileElement profileElement, string path, PluginFeature feature)
|
||||||
{
|
{
|
||||||
if (path == null)
|
if (path == null) throw new ArgumentNullException(nameof(path));
|
||||||
throw new ArgumentNullException(nameof(path));
|
|
||||||
if (feature == null)
|
|
||||||
throw new ArgumentNullException(nameof(feature));
|
|
||||||
|
|
||||||
// Doubt this will happen but let's make sure
|
// Doubt this will happen but let's make sure
|
||||||
if (PropertiesInitialized)
|
if (PropertiesInitialized)
|
||||||
throw new ArtemisCoreException("Layer property group already initialized, wut");
|
throw new ArtemisCoreException("Layer property group already initialized, wut");
|
||||||
|
|
||||||
Feature = feature;
|
Feature = feature ?? throw new ArgumentNullException(nameof(feature));
|
||||||
ProfileElement = profileElement;
|
ProfileElement = profileElement ?? throw new ArgumentNullException(nameof(profileElement));
|
||||||
Path = path.TrimEnd('.');
|
Path = path.TrimEnd('.');
|
||||||
|
|
||||||
// Get all properties with a PropertyDescriptionAttribute
|
// Get all properties with a PropertyDescriptionAttribute
|
||||||
@ -209,8 +211,7 @@ namespace Artemis.Core
|
|||||||
if (!typeof(ILayerProperty).IsAssignableFrom(propertyInfo.PropertyType))
|
if (!typeof(ILayerProperty).IsAssignableFrom(propertyInfo.PropertyType))
|
||||||
throw new ArtemisPluginException($"Layer property with PropertyDescription attribute must be of type LayerProperty at {path}");
|
throw new ArtemisPluginException($"Layer property with PropertyDescription attribute must be of type LayerProperty at {path}");
|
||||||
|
|
||||||
ILayerProperty instance = (ILayerProperty) Activator.CreateInstance(propertyInfo.PropertyType, true);
|
if (!(Activator.CreateInstance(propertyInfo.PropertyType, true) is ILayerProperty instance))
|
||||||
if (instance == null)
|
|
||||||
throw new ArtemisPluginException($"Failed to create instance of layer property at {path}");
|
throw new ArtemisPluginException($"Failed to create instance of layer property at {path}");
|
||||||
|
|
||||||
// Ensure the description has a name, if not this is a good point to set it based on the property info
|
// Ensure the description has a name, if not this is a good point to set it based on the property info
|
||||||
@ -230,8 +231,7 @@ namespace Artemis.Core
|
|||||||
if (!typeof(LayerPropertyGroup).IsAssignableFrom(propertyInfo.PropertyType))
|
if (!typeof(LayerPropertyGroup).IsAssignableFrom(propertyInfo.PropertyType))
|
||||||
throw new ArtemisPluginException("Layer property with PropertyGroupDescription attribute must be of type LayerPropertyGroup");
|
throw new ArtemisPluginException("Layer property with PropertyGroupDescription attribute must be of type LayerPropertyGroup");
|
||||||
|
|
||||||
LayerPropertyGroup instance = (LayerPropertyGroup) Activator.CreateInstance(propertyInfo.PropertyType);
|
if (!(Activator.CreateInstance(propertyInfo.PropertyType) is LayerPropertyGroup instance))
|
||||||
if (instance == null)
|
|
||||||
throw new ArtemisPluginException($"Failed to create instance of layer property group at {path + propertyInfo.Name}");
|
throw new ArtemisPluginException($"Failed to create instance of layer property group at {path + propertyInfo.Name}");
|
||||||
|
|
||||||
// Ensure the description has a name, if not this is a good point to set it based on the property info
|
// Ensure the description has a name, if not this is a good point to set it based on the property info
|
||||||
@ -250,7 +250,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private PropertyEntity GetPropertyEntity(RenderProfileElement profileElement, string path, out bool fromStorage)
|
private PropertyEntity GetPropertyEntity(RenderProfileElement profileElement, string path, out bool fromStorage)
|
||||||
{
|
{
|
||||||
PropertyEntity entity = profileElement.RenderElementEntity.PropertyEntities.FirstOrDefault(p => p.FeatureId == Feature.Id && p.Path == path);
|
PropertyEntity? entity = profileElement.RenderElementEntity.PropertyEntities.FirstOrDefault(p => p.FeatureId == Feature.Id && p.Path == path);
|
||||||
fromStorage = entity != null;
|
fromStorage = entity != null;
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
{
|
{
|
||||||
@ -298,18 +298,18 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the property group has initialized all its children
|
/// Occurs when the property group has initialized all its children
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler PropertyGroupInitialized;
|
public event EventHandler? PropertyGroupInitialized;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when one of the current value of one of the layer properties in this group changes by some form of input
|
/// Occurs when one of the current value of one of the layer properties in this group changes by some form of input
|
||||||
/// <para>Note: Will not trigger on properties in child groups</para>
|
/// <para>Note: Will not trigger on properties in child groups</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<LayerPropertyEventArgs> LayerPropertyOnCurrentValueSet;
|
public event EventHandler<LayerPropertyEventArgs>? LayerPropertyOnCurrentValueSet;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the <see cref="IsHidden" /> value of the layer property was updated
|
/// Occurs when the <see cref="IsHidden" /> value of the layer property was updated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler VisibilityChanged;
|
public event EventHandler? VisibilityChanged;
|
||||||
|
|
||||||
internal virtual void OnVisibilityChanged()
|
internal virtual void OnVisibilityChanged()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -20,7 +20,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a the path outlining the shape
|
/// Gets a the path outlining the shape
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SKPath Path { get; protected set; }
|
public SKPath? Path { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates the <see cref="Path" />
|
/// Calculates the <see cref="Path" />
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace Artemis.Core
|
|||||||
private bool _isActivated;
|
private bool _isActivated;
|
||||||
private readonly object _lock = new object();
|
private readonly object _lock = new object();
|
||||||
|
|
||||||
internal Profile(ProfileModule module, string name)
|
internal Profile(ProfileModule module, string name) : base(null!)
|
||||||
{
|
{
|
||||||
ProfileEntity = new ProfileEntity();
|
ProfileEntity = new ProfileEntity();
|
||||||
EntityId = Guid.NewGuid();
|
EntityId = Guid.NewGuid();
|
||||||
@ -30,7 +30,7 @@ namespace Artemis.Core
|
|||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Profile(ProfileModule module, ProfileEntity profileEntity)
|
internal Profile(ProfileModule module, ProfileEntity profileEntity) : base(null!)
|
||||||
{
|
{
|
||||||
Profile = this;
|
Profile = this;
|
||||||
ProfileEntity = profileEntity;
|
ProfileEntity = profileEntity;
|
||||||
@ -149,7 +149,7 @@ namespace Artemis.Core
|
|||||||
ChildrenList.Clear();
|
ChildrenList.Clear();
|
||||||
|
|
||||||
// Populate the profile starting at the root, the rest is populated recursively
|
// Populate the profile starting at the root, the rest is populated recursively
|
||||||
FolderEntity rootFolder = ProfileEntity.Folders.FirstOrDefault(f => f.ParentId == EntityId);
|
FolderEntity? rootFolder = ProfileEntity.Folders.FirstOrDefault(f => f.ParentId == EntityId);
|
||||||
if (rootFolder == null)
|
if (rootFolder == null)
|
||||||
{
|
{
|
||||||
Folder _ = new Folder(this, "Root folder");
|
Folder _ = new Folder(this, "Root folder");
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
private bool _enabled;
|
private bool _enabled;
|
||||||
private Guid _entityId;
|
private Guid _entityId;
|
||||||
private string _name;
|
private string? _name;
|
||||||
private int _order;
|
private int _order;
|
||||||
private ProfileElement? _parent;
|
private ProfileElement? _parent;
|
||||||
private Profile _profile;
|
private Profile _profile;
|
||||||
@ -21,8 +21,9 @@ namespace Artemis.Core
|
|||||||
internal List<ProfileElement> ChildrenList;
|
internal List<ProfileElement> ChildrenList;
|
||||||
internal bool Disposed;
|
internal bool Disposed;
|
||||||
|
|
||||||
internal ProfileElement()
|
internal ProfileElement(Profile profile)
|
||||||
{
|
{
|
||||||
|
_profile = profile;
|
||||||
ChildrenList = new List<ProfileElement>();
|
ChildrenList = new List<ProfileElement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +57,16 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The element's children
|
/// The element's children
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<ProfileElement> Children => ChildrenList.AsReadOnly();
|
public ReadOnlyCollection<ProfileElement> Children
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (ChildrenList)
|
||||||
|
{
|
||||||
|
return ChildrenList.AsReadOnly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The order in which this element appears in the update loop and editor
|
/// The order in which this element appears in the update loop and editor
|
||||||
@ -70,7 +80,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name which appears in the editor
|
/// The name which appears in the editor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name
|
public string? Name
|
||||||
{
|
{
|
||||||
get => _name;
|
get => _name;
|
||||||
set => SetAndNotify(ref _name, value);
|
set => SetAndNotify(ref _name, value);
|
||||||
|
|||||||
@ -16,10 +16,12 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class RenderProfileElement : ProfileElement
|
public abstract class RenderProfileElement : ProfileElement
|
||||||
{
|
{
|
||||||
internal RenderProfileElement()
|
internal RenderProfileElement(Profile profile) : base(profile)
|
||||||
{
|
{
|
||||||
Timeline = new Timeline();
|
Timeline = new Timeline();
|
||||||
Renderer = new Renderer();
|
Renderer = new Renderer();
|
||||||
|
ExpandedPropertyGroups = new List<string>();
|
||||||
|
LayerEffectsList = new List<BaseLayerEffect>();
|
||||||
|
|
||||||
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
||||||
LayerEffectStore.LayerEffectRemoved += LayerEffectStoreOnLayerEffectRemoved;
|
LayerEffectStore.LayerEffectRemoved += LayerEffectStoreOnLayerEffectRemoved;
|
||||||
@ -68,7 +70,7 @@ namespace Artemis.Core
|
|||||||
LayerEffectEntity layerEffectEntity = new LayerEffectEntity
|
LayerEffectEntity layerEffectEntity = new LayerEffectEntity
|
||||||
{
|
{
|
||||||
Id = layerEffect.EntityId,
|
Id = layerEffect.EntityId,
|
||||||
ProviderId = layerEffect.Descriptor.PlaceholderFor ?? layerEffect.ProviderId,
|
ProviderId = layerEffect.Descriptor?.PlaceholderFor ?? layerEffect.ProviderId,
|
||||||
EffectType = layerEffect.GetEffectTypeName(),
|
EffectType = layerEffect.GetEffectTypeName(),
|
||||||
Name = layerEffect.Name,
|
Name = layerEffect.Name,
|
||||||
Enabled = layerEffect.Enabled,
|
Enabled = layerEffect.Enabled,
|
||||||
@ -76,7 +78,7 @@ namespace Artemis.Core
|
|||||||
Order = layerEffect.Order
|
Order = layerEffect.Order
|
||||||
};
|
};
|
||||||
RenderElementEntity.LayerEffects.Add(layerEffectEntity);
|
RenderElementEntity.LayerEffects.Add(layerEffectEntity);
|
||||||
layerEffect.BaseProperties.ApplyToEntity();
|
layerEffect.BaseProperties?.ApplyToEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conditions
|
// Conditions
|
||||||
@ -290,8 +292,7 @@ namespace Artemis.Core
|
|||||||
private void LayerEffectStoreOnLayerEffectRemoved(object? sender, LayerEffectStoreEvent e)
|
private void LayerEffectStoreOnLayerEffectRemoved(object? sender, LayerEffectStoreEvent e)
|
||||||
{
|
{
|
||||||
// If effects provided by the plugin are on the element, replace them with placeholders
|
// If effects provided by the plugin are on the element, replace them with placeholders
|
||||||
List<BaseLayerEffect> pluginEffects = LayerEffectsList.Where(ef => ef.Descriptor.Provider != null &&
|
List<BaseLayerEffect> pluginEffects = LayerEffectsList.Where(ef => ef.ProviderId == e.Registration.PluginFeature.Id).ToList();
|
||||||
ef.ProviderId == e.Registration.PluginFeature.Id).ToList();
|
|
||||||
foreach (BaseLayerEffect pluginEffect in pluginEffects)
|
foreach (BaseLayerEffect pluginEffect in pluginEffects)
|
||||||
{
|
{
|
||||||
LayerEffectEntity entity = RenderElementEntity.LayerEffects.First(en => en.Id == pluginEffect.EntityId);
|
LayerEffectEntity entity = RenderElementEntity.LayerEffects.First(en => en.Id == pluginEffect.EntityId);
|
||||||
@ -323,13 +324,13 @@ namespace Artemis.Core
|
|||||||
protected set => SetAndNotify(ref _displayConditionMet, value);
|
protected set => SetAndNotify(ref _displayConditionMet, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataModelConditionGroup _displayCondition;
|
private DataModelConditionGroup? _displayCondition;
|
||||||
private bool _displayConditionMet;
|
private bool _displayConditionMet;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the root display condition group
|
/// Gets or sets the root display condition group
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModelConditionGroup DisplayCondition
|
public DataModelConditionGroup? DisplayCondition
|
||||||
{
|
{
|
||||||
get => _displayCondition;
|
get => _displayCondition;
|
||||||
set => SetAndNotify(ref _displayCondition, value);
|
set => SetAndNotify(ref _displayCondition, value);
|
||||||
|
|||||||
@ -26,7 +26,7 @@ namespace Artemis.Core
|
|||||||
if (IsOpen)
|
if (IsOpen)
|
||||||
throw new ArtemisCoreException("Cannot open render context because it is already open");
|
throw new ArtemisCoreException("Cannot open render context because it is already open");
|
||||||
|
|
||||||
if (!_valid)
|
if (!_valid || Canvas == null)
|
||||||
{
|
{
|
||||||
SKRect pathBounds = path.Bounds;
|
SKRect pathBounds = path.Bounds;
|
||||||
int width = (int) pathBounds.Width;
|
int width = (int) pathBounds.Width;
|
||||||
@ -59,7 +59,7 @@ namespace Artemis.Core
|
|||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException("Renderer");
|
throw new ObjectDisposedException("Renderer");
|
||||||
|
|
||||||
Canvas.Restore();
|
Canvas?.Restore();
|
||||||
Paint?.Dispose();
|
Paint?.Dispose();
|
||||||
Paint = null;
|
Paint = null;
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ namespace Artemis.Core
|
|||||||
public class ArtemisDevice : CorePropertyChanged
|
public class ArtemisDevice : CorePropertyChanged
|
||||||
{
|
{
|
||||||
private ReadOnlyCollection<ArtemisLed> _leds;
|
private ReadOnlyCollection<ArtemisLed> _leds;
|
||||||
private SKPath _renderPath;
|
private SKPath? _renderPath;
|
||||||
private SKRect _renderRectangle;
|
private SKRect _renderRectangle;
|
||||||
|
|
||||||
internal ArtemisDevice(IRGBDevice rgbDevice, DeviceProvider deviceProvider, ArtemisSurface surface)
|
internal ArtemisDevice(IRGBDevice rgbDevice, DeviceProvider deviceProvider, ArtemisSurface surface)
|
||||||
@ -23,7 +23,7 @@ namespace Artemis.Core
|
|||||||
DeviceProvider = deviceProvider;
|
DeviceProvider = deviceProvider;
|
||||||
Surface = surface;
|
Surface = surface;
|
||||||
DeviceEntity = new DeviceEntity();
|
DeviceEntity = new DeviceEntity();
|
||||||
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
_leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||||
|
|
||||||
Rotation = 0;
|
Rotation = 0;
|
||||||
Scale = 1;
|
Scale = 1;
|
||||||
@ -39,7 +39,7 @@ namespace Artemis.Core
|
|||||||
DeviceProvider = deviceProvider;
|
DeviceProvider = deviceProvider;
|
||||||
Surface = surface;
|
Surface = surface;
|
||||||
DeviceEntity = deviceEntity;
|
DeviceEntity = deviceEntity;
|
||||||
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
_leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -54,7 +54,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path surrounding the device, sized to match the render scale
|
/// Gets the path surrounding the device, sized to match the render scale
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SKPath RenderPath
|
public SKPath? RenderPath
|
||||||
{
|
{
|
||||||
get => _renderPath;
|
get => _renderPath;
|
||||||
private set => SetAndNotify(ref _renderPath, value);
|
private set => SetAndNotify(ref _renderPath, value);
|
||||||
|
|||||||
@ -22,7 +22,7 @@ namespace Artemis.Core.Ninject
|
|||||||
|
|
||||||
protected override ILogger CreateInstance(IContext context)
|
protected override ILogger CreateInstance(IContext context)
|
||||||
{
|
{
|
||||||
Type requestingType = context.Request.ParentContext?.Plan?.Type;
|
Type? requestingType = context.Request.ParentContext?.Plan?.Type;
|
||||||
if (requestingType != null)
|
if (requestingType != null)
|
||||||
return Logger.ForContext(requestingType);
|
return Logger.ForContext(requestingType);
|
||||||
return Logger;
|
return Logger;
|
||||||
|
|||||||
@ -11,32 +11,32 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the user-friendly name for this property, shown in the UI.
|
/// Gets or sets the user-friendly name for this property, shown in the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string? Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the user-friendly description for this property, shown in the UI.
|
/// Gets or sets the user-friendly description for this property, shown in the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Description { get; set; }
|
public string? Description { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the an optional prefix to show before displaying elements in the UI.
|
/// Gets or sets the an optional prefix to show before displaying elements in the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Prefix { get; set; }
|
public string? Prefix { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets an optional affix to show behind displaying elements in the UI.
|
/// Gets or sets an optional affix to show behind displaying elements in the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Affix { get; set; }
|
public string? Affix { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets an optional maximum value, this value is not enforced but used for percentage calculations.
|
/// Gets or sets an optional maximum value, this value is not enforced but used for percentage calculations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object MaxValue { get; set; }
|
public object? MaxValue { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets an optional minimum value, this value is not enforced but used for percentage calculations.
|
/// Gets or sets an optional minimum value, this value is not enforced but used for percentage calculations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object MinValue { get; set; }
|
public object? MinValue { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets whether this property resets the max depth of the data model, defaults to true
|
/// Gets or sets whether this property resets the max depth of the data model, defaults to true
|
||||||
|
|||||||
@ -15,6 +15,16 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
{
|
{
|
||||||
private readonly Dictionary<string, DataModel> _dynamicDataModels = new Dictionary<string, DataModel>();
|
private readonly Dictionary<string, DataModel> _dynamicDataModels = new Dictionary<string, DataModel>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DataModel" /> class
|
||||||
|
/// </summary>
|
||||||
|
protected DataModel()
|
||||||
|
{
|
||||||
|
// These are both set right after construction to keep the constructor of inherited classes clean
|
||||||
|
Feature = null!;
|
||||||
|
DataModelDescription = null!;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin feature this data model belongs to
|
/// Gets the plugin feature this data model belongs to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -60,7 +70,7 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
/// <param name="key">The key of the child, must be unique to this data model</param>
|
/// <param name="key">The key of the child, must be unique to this data model</param>
|
||||||
/// <param name="name">An optional name, if not provided the key will be used in a humanized form</param>
|
/// <param name="name">An optional name, if not provided the key will be used in a humanized form</param>
|
||||||
/// <param name="description">An optional description</param>
|
/// <param name="description">An optional description</param>
|
||||||
public T AddDynamicChild<T>(T dynamicDataModel, string key, string name = null, string description = null) where T : DataModel
|
public T AddDynamicChild<T>(T dynamicDataModel, string key, string? name = null, string? description = null) where T : DataModel
|
||||||
{
|
{
|
||||||
if (dynamicDataModel == null)
|
if (dynamicDataModel == null)
|
||||||
throw new ArgumentNullException(nameof(dynamicDataModel));
|
throw new ArgumentNullException(nameof(dynamicDataModel));
|
||||||
@ -140,7 +150,7 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
/// <returns>If found, the dynamic data model otherwise <c>null</c></returns>
|
/// <returns>If found, the dynamic data model otherwise <c>null</c></returns>
|
||||||
public T? DynamicChild<T>(string key) where T : DataModel
|
public T? DynamicChild<T>(string key) where T : DataModel
|
||||||
{
|
{
|
||||||
_dynamicDataModels.TryGetValue(key, out DataModel value);
|
_dynamicDataModels.TryGetValue(key, out DataModel? value);
|
||||||
return value as T;
|
return value as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public T DataModel
|
public T DataModel
|
||||||
{
|
{
|
||||||
get => (T) InternalDataModel;
|
get => InternalDataModel as T ?? throw new InvalidOperationException("Internal datamodel does not match the type of the data model");
|
||||||
internal set => InternalDataModel = value;
|
internal set => InternalDataModel = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,11 +49,5 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
DataModel.DataModelDescription = GetDataModelDescription();
|
DataModel.DataModelDescription = GetDataModelDescription();
|
||||||
base.InternalEnable();
|
base.InternalEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override void InternalDisable()
|
|
||||||
{
|
|
||||||
DataModel = null;
|
|
||||||
base.InternalDisable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ namespace Artemis.Core.DeviceProviders
|
|||||||
/// A logger used by the device provider internally, ignore this
|
/// A logger used by the device provider internally, ignore this
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Inject]
|
[Inject]
|
||||||
public ILogger Logger { get; set; }
|
public ILogger? Logger { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Disable()
|
public override void Disable()
|
||||||
|
|||||||
@ -10,10 +10,20 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
{
|
{
|
||||||
private LayerBrushType _brushType;
|
private LayerBrushType _brushType;
|
||||||
private ILayerBrushConfigurationDialog? _configurationDialog;
|
private ILayerBrushConfigurationDialog? _configurationDialog;
|
||||||
private LayerBrushDescriptor? _descriptor;
|
private LayerBrushDescriptor _descriptor;
|
||||||
private Layer _layer;
|
private Layer _layer;
|
||||||
private bool _supportsTransformation = true;
|
private bool _supportsTransformation = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="BaseLayerBrush" /> class
|
||||||
|
/// </summary>
|
||||||
|
protected BaseLayerBrush()
|
||||||
|
{
|
||||||
|
// Both are set right after construction to keep the constructor of inherited classes clean
|
||||||
|
_layer = null!;
|
||||||
|
_descriptor = null!;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the layer this brush is applied to
|
/// Gets the layer this brush is applied to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -26,7 +36,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the descriptor of this brush
|
/// Gets the descriptor of this brush
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerBrushDescriptor? Descriptor
|
public LayerBrushDescriptor Descriptor
|
||||||
{
|
{
|
||||||
get => _descriptor;
|
get => _descriptor;
|
||||||
internal set => SetAndNotify(ref _descriptor, value);
|
internal set => SetAndNotify(ref _descriptor, value);
|
||||||
|
|||||||
@ -7,7 +7,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class PropertiesLayerBrush<T> : BaseLayerBrush where T : LayerPropertyGroup
|
public abstract class PropertiesLayerBrush<T> : BaseLayerBrush where T : LayerPropertyGroup
|
||||||
{
|
{
|
||||||
private T _properties;
|
private T _properties = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether all properties on this brush are initialized
|
/// Gets whether all properties on this brush are initialized
|
||||||
@ -35,7 +35,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
internal void InitializeProperties()
|
internal void InitializeProperties()
|
||||||
{
|
{
|
||||||
Properties = Activator.CreateInstance<T>();
|
Properties = Activator.CreateInstance<T>();
|
||||||
Properties.GroupDescription ??= new PropertyGroupDescriptionAttribute {Name = Descriptor.DisplayName, Description = Descriptor.Description};
|
Properties.GroupDescription = new PropertyGroupDescriptionAttribute {Name = Descriptor.DisplayName, Description = Descriptor.Description};
|
||||||
Properties.LayerBrush = this;
|
Properties.LayerBrush = this;
|
||||||
Properties.Initialize(Layer, "LayerBrush.", Descriptor.Provider);
|
Properties.Initialize(Layer, "LayerBrush.", Descriptor.Provider);
|
||||||
PropertiesInitialized = true;
|
PropertiesInitialized = true;
|
||||||
|
|||||||
@ -59,6 +59,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal void CreateInstance(Layer layer)
|
internal void CreateInstance(Layer layer)
|
||||||
{
|
{
|
||||||
|
if (layer == null) throw new ArgumentNullException(nameof(layer));
|
||||||
if (layer.LayerBrush != null)
|
if (layer.LayerBrush != null)
|
||||||
throw new ArtemisCoreException("Layer already has an instantiated layer brush");
|
throw new ArtemisCoreException("Layer already has an instantiated layer brush");
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected RgbNetLayerBrush()
|
protected RgbNetLayerBrush()
|
||||||
{
|
{
|
||||||
|
LedGroup = new ListLedGroup();
|
||||||
BrushType = LayerBrushType.RgbNet;
|
BrushType = LayerBrushType.RgbNet;
|
||||||
SupportsTransformation = false;
|
SupportsTransformation = false;
|
||||||
}
|
}
|
||||||
@ -75,7 +76,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
// Not used in this effect type
|
// Not used in this effect type
|
||||||
internal override void InternalRender(SKCanvas canvas, SKRect bounds, SKPaint paint)
|
internal override void InternalRender(SKCanvas canvas, SKRect bounds, SKPaint paint)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("RGB.NET layer effectes do not implement InternalRender");
|
throw new NotImplementedException("RGB.NET layer effects do not implement InternalRender");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerOnRenderPropertiesUpdated(object? sender, EventArgs e)
|
private void LayerOnRenderPropertiesUpdated(object? sender, EventArgs e)
|
||||||
|
|||||||
@ -9,7 +9,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BaseLayerEffect : CorePropertyChanged, IDisposable
|
public abstract class BaseLayerEffect : CorePropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
private ILayerEffectConfigurationDialog _configurationDialog;
|
private ILayerEffectConfigurationDialog? _configurationDialog;
|
||||||
private LayerEffectDescriptor _descriptor;
|
private LayerEffectDescriptor _descriptor;
|
||||||
private bool _enabled;
|
private bool _enabled;
|
||||||
private Guid _entityId;
|
private Guid _entityId;
|
||||||
@ -18,6 +18,15 @@ namespace Artemis.Core.LayerEffects
|
|||||||
private int _order;
|
private int _order;
|
||||||
private RenderProfileElement _profileElement;
|
private RenderProfileElement _profileElement;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected BaseLayerEffect()
|
||||||
|
{
|
||||||
|
// These are set right after construction to keep the constructor of inherited classes clean
|
||||||
|
_profileElement = null!;
|
||||||
|
_descriptor = null!;
|
||||||
|
_name = null!;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the unique ID of this effect
|
/// Gets the unique ID of this effect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -76,7 +85,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="LayerEffectDescriptor" /> that registered this effect
|
/// Gets the <see cref="LayerEffectDescriptor" /> that registered this effect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerEffectDescriptor? Descriptor
|
public LayerEffectDescriptor Descriptor
|
||||||
{
|
{
|
||||||
get => _descriptor;
|
get => _descriptor;
|
||||||
internal set => SetAndNotify(ref _descriptor, value);
|
internal set => SetAndNotify(ref _descriptor, value);
|
||||||
@ -85,7 +94,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a configuration dialog complementing the regular properties
|
/// Gets or sets a configuration dialog complementing the regular properties
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ILayerEffectConfigurationDialog ConfigurationDialog
|
public ILayerEffectConfigurationDialog? ConfigurationDialog
|
||||||
{
|
{
|
||||||
get => _configurationDialog;
|
get => _configurationDialog;
|
||||||
protected set => SetAndNotify(ref _configurationDialog, value);
|
protected set => SetAndNotify(ref _configurationDialog, value);
|
||||||
@ -94,12 +103,12 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ID of the <see cref="LayerEffectProvider"/> that provided this effect
|
/// Gets the ID of the <see cref="LayerEffectProvider"/> that provided this effect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ProviderId => Descriptor?.Provider?.Id;
|
public string ProviderId => Descriptor.Provider.Id;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a reference to the layer property group without knowing it's type
|
/// Gets a reference to the layer property group without knowing it's type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual LayerPropertyGroup BaseProperties => null;
|
public virtual LayerPropertyGroup? BaseProperties => null;
|
||||||
|
|
||||||
internal string PropertyRootPath => $"LayerEffect.{EntityId}.{GetType().Name}.";
|
internal string PropertyRootPath => $"LayerEffect.{EntityId}.{GetType().Name}.";
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public abstract class LayerEffect<T> : BaseLayerEffect where T : LayerPropertyGroup
|
public abstract class LayerEffect<T> : BaseLayerEffect where T : LayerPropertyGroup
|
||||||
{
|
{
|
||||||
private T _properties;
|
private T _properties = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether all properties on this effect are initialized
|
/// Gets whether all properties on this effect are initialized
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LayerEffectDescriptor
|
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;
|
DisplayName = displayName;
|
||||||
Description = description;
|
Description = description;
|
||||||
@ -39,12 +39,12 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of the layer effect
|
/// The type of the layer effect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Type LayerEffectType { get; }
|
public Type? LayerEffectType { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The plugin that provided this <see cref="LayerEffectDescriptor" />
|
/// The plugin that provided this <see cref="LayerEffectDescriptor" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerEffectProvider? Provider { get; }
|
public LayerEffectProvider Provider { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the GUID this descriptor is acting as a placeholder for. If null, this descriptor is not a placeholder
|
/// Gets the GUID this descriptor is acting as a placeholder for. If null, this descriptor is not a placeholder
|
||||||
@ -66,8 +66,8 @@ namespace Artemis.Core.LayerEffects
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Provider == null)
|
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 provider");
|
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);
|
BaseLayerEffect effect = (BaseLayerEffect) Provider.Plugin.Kernel!.Get(LayerEffectType);
|
||||||
effect.ProfileElement = renderElement;
|
effect.ProfileElement = renderElement;
|
||||||
@ -85,7 +85,13 @@ namespace Artemis.Core.LayerEffects
|
|||||||
|
|
||||||
private void CreatePlaceHolderInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
|
private void CreatePlaceHolderInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
|
||||||
{
|
{
|
||||||
PlaceholderLayerEffect effect = new PlaceholderLayerEffect(entity, PlaceholderFor) {ProfileElement = renderElement, Descriptor = this};
|
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 PlaceholderLayerEffect(entity, PlaceholderFor)
|
||||||
|
{
|
||||||
|
ProfileElement = renderElement,
|
||||||
|
Descriptor = this
|
||||||
|
};
|
||||||
effect.Initialize();
|
effect.Initialize();
|
||||||
renderElement.ActivateLayerEffect(effect);
|
renderElement.ActivateLayerEffect(effect);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="processName">The name of the process that must run</param>
|
/// <param name="processName">The name of the process that must run</param>
|
||||||
/// <param name="location">The location of where the process must be running from (optional)</param>
|
/// <param name="location">The location of where the process must be running from (optional)</param>
|
||||||
public ProcessActivationRequirement(string processName, string location = null)
|
public ProcessActivationRequirement(string? processName, string? location = null)
|
||||||
{
|
{
|
||||||
ProcessName = processName;
|
ProcessName = processName;
|
||||||
Location = location;
|
Location = location;
|
||||||
@ -25,12 +25,12 @@ namespace Artemis.Core.Modules
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the process that must run
|
/// The name of the process that must run
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ProcessName { get; set; }
|
public string? ProcessName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The location of where the process must be running from
|
/// The location of where the process must be running from
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Location { get; set; }
|
public string? Location { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Evaluate()
|
public bool Evaluate()
|
||||||
|
|||||||
@ -18,7 +18,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public T DataModel
|
public T DataModel
|
||||||
{
|
{
|
||||||
get => (T) InternalDataModel;
|
get => InternalDataModel as T ?? throw new InvalidOperationException("Internal datamodel does not match the type of the data model");
|
||||||
internal set => InternalDataModel = value;
|
internal set => InternalDataModel = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,12 +52,6 @@ namespace Artemis.Core.Modules
|
|||||||
DataModel.DataModelDescription = GetDataModelDescription();
|
DataModel.DataModelDescription = GetDataModelDescription();
|
||||||
base.InternalEnable();
|
base.InternalEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override void InternalDisable()
|
|
||||||
{
|
|
||||||
DataModel = null;
|
|
||||||
base.InternalDisable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,12 +6,11 @@ namespace Artemis.Core.Modules
|
|||||||
public class ModuleTab<T> : ModuleTab where T : IModuleViewModel
|
public class ModuleTab<T> : ModuleTab where T : IModuleViewModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ModuleTab{T}" /> class
|
/// Creates a new instance of the <see cref="ModuleTab{T}" /> class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="title">The title of the tab</param>
|
/// <param name="title">The title of the tab</param>
|
||||||
public ModuleTab(string title)
|
public ModuleTab(string title) : base(title)
|
||||||
{
|
{
|
||||||
Title = title;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -24,9 +23,13 @@ namespace Artemis.Core.Modules
|
|||||||
public abstract class ModuleTab
|
public abstract class ModuleTab
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The module this tab belongs to
|
/// Creates a new instance of the <see cref="ModuleTab" /> class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal Module Module { get; set; }
|
/// <param name="title">The title of the tab</param>
|
||||||
|
protected ModuleTab(string title)
|
||||||
|
{
|
||||||
|
Title = title;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The title of the tab
|
/// The title of the tab
|
||||||
|
|||||||
@ -22,7 +22,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public T DataModel
|
public T DataModel
|
||||||
{
|
{
|
||||||
get => (T) InternalDataModel;
|
get => InternalDataModel as T ?? throw new InvalidOperationException("Internal datamodel does not match the type of the data model");
|
||||||
internal set => InternalDataModel = value;
|
internal set => InternalDataModel = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,6 @@ namespace Artemis.Core.Modules
|
|||||||
{
|
{
|
||||||
Deactivate(true);
|
Deactivate(true);
|
||||||
base.InternalDisable();
|
base.InternalDisable();
|
||||||
DataModel = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +181,7 @@ namespace Artemis.Core.Modules
|
|||||||
ProfileRendered(deltaTime, surface, canvas, canvasInfo);
|
ProfileRendered(deltaTime, surface, canvas, canvasInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task ChangeActiveProfileAnimated(Profile profile, ArtemisSurface surface)
|
internal async Task ChangeActiveProfileAnimated(Profile? profile, ArtemisSurface? surface)
|
||||||
{
|
{
|
||||||
if (profile != null && profile.Module != this)
|
if (profile != null && profile.Module != this)
|
||||||
throw new ArtemisCoreException($"Cannot activate a profile of module {profile.Module} on a module of plugin {this}.");
|
throw new ArtemisCoreException($"Cannot activate a profile of module {profile.Module} on a module of plugin {this}.");
|
||||||
@ -204,12 +203,14 @@ namespace Artemis.Core.Modules
|
|||||||
await Task.Delay(50);
|
await Task.Delay(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ChangeActiveProfile(Profile profile, ArtemisSurface surface)
|
internal void ChangeActiveProfile(Profile? profile, ArtemisSurface? surface)
|
||||||
{
|
{
|
||||||
if (profile != null && profile.Module != this)
|
if (profile != null && profile.Module != this)
|
||||||
throw new ArtemisCoreException($"Cannot activate a profile of module {profile.Module} on a module of plugin {this}.");
|
throw new ArtemisCoreException($"Cannot activate a profile of module {profile.Module} on a module of plugin {this}.");
|
||||||
if (!IsActivated)
|
if (!IsActivated)
|
||||||
throw new ArtemisCoreException("Cannot activate a profile on a deactivated module");
|
throw new ArtemisCoreException("Cannot activate a profile on a deactivated module");
|
||||||
|
if (profile != null && surface == null)
|
||||||
|
throw new ArtemisCoreException("If changing the active profile to a non-null profile, a surface is required");
|
||||||
|
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
@ -219,7 +220,7 @@ namespace Artemis.Core.Modules
|
|||||||
ActiveProfile?.Dispose();
|
ActiveProfile?.Dispose();
|
||||||
|
|
||||||
ActiveProfile = profile;
|
ActiveProfile = profile;
|
||||||
ActiveProfile?.Activate(surface);
|
ActiveProfile?.Activate(surface!);
|
||||||
}
|
}
|
||||||
|
|
||||||
OnActiveProfileChanged();
|
OnActiveProfileChanged();
|
||||||
@ -229,7 +230,7 @@ namespace Artemis.Core.Modules
|
|||||||
{
|
{
|
||||||
base.Deactivate(isOverride);
|
base.Deactivate(isOverride);
|
||||||
|
|
||||||
Profile profile = ActiveProfile;
|
Profile? profile = ActiveProfile;
|
||||||
ActiveProfile = null;
|
ActiveProfile = null;
|
||||||
profile?.Dispose();
|
profile?.Dispose();
|
||||||
}
|
}
|
||||||
@ -249,7 +250,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the <see cref="ActiveProfile" /> has changed
|
/// Occurs when the <see cref="ActiveProfile" /> has changed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler ActiveProfileChanged;
|
public event EventHandler? ActiveProfileChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invokes the <see cref="ActiveProfileChanged" /> event
|
/// Invokes the <see cref="ActiveProfileChanged" /> event
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@ -19,10 +20,11 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private bool _isEnabled;
|
private bool _isEnabled;
|
||||||
|
|
||||||
internal Plugin(PluginInfo info, DirectoryInfo directory)
|
internal Plugin(PluginInfo info, DirectoryInfo directory, PluginEntity? pluginEntity)
|
||||||
{
|
{
|
||||||
Info = info;
|
Info = info;
|
||||||
Directory = directory;
|
Directory = directory;
|
||||||
|
Entity = pluginEntity ?? new PluginEntity {Id = Guid, IsEnabled = true};
|
||||||
|
|
||||||
_features = new List<PluginFeature>();
|
_features = new List<PluginFeature>();
|
||||||
}
|
}
|
||||||
@ -42,6 +44,7 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DirectoryInfo Directory { get; }
|
public DirectoryInfo Directory { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a configuration dialog for this plugin that is accessible in the UI under Settings > Plugins
|
/// Gets or sets a configuration dialog for this plugin that is accessible in the UI under Settings > Plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -91,7 +94,8 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The path to resolve</param>
|
/// <param name="path">The path to resolve</param>
|
||||||
/// <returns>An absolute path pointing to the provided relative path</returns>
|
/// <returns>An absolute path pointing to the provided relative path</returns>
|
||||||
public string? ResolveRelativePath(string path)
|
[return: NotNullIfNotNull("path")]
|
||||||
|
public string? ResolveRelativePath(string? path)
|
||||||
{
|
{
|
||||||
return path == null ? null : Path.Combine(Directory.FullName, path);
|
return path == null ? null : Path.Combine(Directory.FullName, path);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin that provides this feature
|
/// Gets the plugin that provides this feature
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Plugin Plugin { get; internal set; }
|
public Plugin Plugin { get; internal set; } = null!; // Will be set right after construction
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether the plugin is enabled
|
/// Gets whether the plugin is enabled
|
||||||
@ -41,7 +41,7 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Id => $"{GetType().FullName}-{Plugin.Guid.ToString().Substring(0, 8)}"; // Not as unique as a GUID but good enough and stays readable
|
public string Id => $"{GetType().FullName}-{Plugin.Guid.ToString().Substring(0, 8)}"; // Not as unique as a GUID but good enough and stays readable
|
||||||
|
|
||||||
internal PluginFeatureEntity Entity { get; set; }
|
internal PluginFeatureEntity Entity { get; set; } = null!; // Will be set right after construction
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the feature is activated
|
/// Called when the feature is activated
|
||||||
|
|||||||
@ -9,13 +9,13 @@ namespace Artemis.Core
|
|||||||
[JsonObject(MemberSerialization.OptIn)]
|
[JsonObject(MemberSerialization.OptIn)]
|
||||||
public class PluginInfo : CorePropertyChanged
|
public class PluginInfo : CorePropertyChanged
|
||||||
{
|
{
|
||||||
private string _description;
|
private string? _description;
|
||||||
private Guid _guid;
|
private Guid _guid;
|
||||||
private string _icon;
|
private string? _icon;
|
||||||
private string _main;
|
private string _main = null!;
|
||||||
private string _name;
|
private string _name = null!;
|
||||||
private Plugin _plugin;
|
private Plugin _plugin = null!;
|
||||||
private Version _version;
|
private Version _version = null!;
|
||||||
|
|
||||||
internal PluginInfo()
|
internal PluginInfo()
|
||||||
{
|
{
|
||||||
@ -45,7 +45,7 @@ namespace Artemis.Core
|
|||||||
/// A short description of the plugin
|
/// A short description of the plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public string Description
|
public string? Description
|
||||||
{
|
{
|
||||||
get => _description;
|
get => _description;
|
||||||
set => SetAndNotify(ref _description, value);
|
set => SetAndNotify(ref _description, value);
|
||||||
@ -57,7 +57,7 @@ namespace Artemis.Core
|
|||||||
/// icons
|
/// icons
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public string Icon
|
public string? Icon
|
||||||
{
|
{
|
||||||
get => _icon;
|
get => _icon;
|
||||||
set => SetAndNotify(ref _icon, value);
|
set => SetAndNotify(ref _icon, value);
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Artemis.Core.Properties;
|
||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -27,11 +29,11 @@ namespace Artemis.Core
|
|||||||
Name = pluginSettingEntity.Name;
|
Name = pluginSettingEntity.Name;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Value = JsonConvert.DeserializeObject<T>(pluginSettingEntity.Value);
|
_value = JsonConvert.DeserializeObject<T>(pluginSettingEntity.Value);
|
||||||
}
|
}
|
||||||
catch (JsonReaderException)
|
catch (JsonReaderException)
|
||||||
{
|
{
|
||||||
Value = default;
|
_value = default!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +45,8 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The value of the setting
|
/// The value of the setting
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[AllowNull]
|
||||||
|
[CanBeNull]
|
||||||
public T Value
|
public T Value
|
||||||
{
|
{
|
||||||
get => _value;
|
get => _value;
|
||||||
@ -50,7 +54,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
if (Equals(_value, value)) return;
|
if (Equals(_value, value)) return;
|
||||||
|
|
||||||
_value = value;
|
_value = value!;
|
||||||
OnSettingChanged();
|
OnSettingChanged();
|
||||||
OnPropertyChanged(nameof(Value));
|
OnPropertyChanged(nameof(Value));
|
||||||
|
|
||||||
@ -94,12 +98,12 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the value of the setting has been changed
|
/// Occurs when the value of the setting has been changed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler SettingChanged;
|
public event EventHandler? SettingChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the value of the setting has been saved
|
/// Occurs when the value of the setting has been saved
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler SettingSaved;
|
public event EventHandler? SettingSaved;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Artemis.Core
|
|||||||
public class TimedUpdateRegistration : IDisposable
|
public class TimedUpdateRegistration : IDisposable
|
||||||
{
|
{
|
||||||
private DateTime _lastEvent;
|
private DateTime _lastEvent;
|
||||||
private Timer _timer;
|
private Timer? _timer;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly object _lock = new object();
|
private readonly object _lock = new object();
|
||||||
|
|
||||||
@ -53,12 +53,12 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the action that gets called each time the update event fires
|
/// Gets the action that gets called each time the update event fires
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<double> Action { get; }
|
public Action<double>? Action { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the task that gets called each time the update event fires
|
/// Gets the task that gets called each time the update event fires
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<double, Task> AsyncAction { get; }
|
public Func<double, Task>? AsyncAction { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts calling the <see cref="Action" /> or <see cref="AsyncAction"/> at the configured <see cref="Interval" />
|
/// Starts calling the <see cref="Action" /> or <see cref="AsyncAction"/> at the configured <see cref="Interval" />
|
||||||
|
|||||||
@ -22,9 +22,10 @@ SOFTWARE. */
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
// ReSharper disable InheritdocConsiderUsage
|
|
||||||
|
|
||||||
#pragma warning disable 1591
|
#pragma warning disable 1591
|
||||||
|
#pragma warning disable 8618
|
||||||
|
|
||||||
|
// ReSharper disable InheritdocConsiderUsage
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable MemberCanBePrivate.Global
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
|||||||
@ -60,7 +60,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the bitmap used to sample the brush
|
/// Gets the bitmap used to sample the brush
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SKBitmap Bitmap { get; private set; }
|
public SKBitmap? Bitmap { get; private set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -94,6 +94,9 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void TakeCenter(IEnumerable<BrushRenderTarget> renderTargets)
|
private void TakeCenter(IEnumerable<BrushRenderTarget> renderTargets)
|
||||||
{
|
{
|
||||||
|
if (Bitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
foreach (BrushRenderTarget renderTarget in renderTargets)
|
foreach (BrushRenderTarget renderTarget in renderTargets)
|
||||||
{
|
{
|
||||||
Point scaledLocation = renderTarget.Point * Scale;
|
Point scaledLocation = renderTarget.Point * Scale;
|
||||||
@ -104,6 +107,9 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void TakeSamples(IEnumerable<BrushRenderTarget> renderTargets)
|
private void TakeSamples(IEnumerable<BrushRenderTarget> renderTargets)
|
||||||
{
|
{
|
||||||
|
if (Bitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
int sampleSize = _sampleSizeSetting.Value;
|
int sampleSize = _sampleSizeSetting.Value;
|
||||||
int sampleDepth = Math.Sqrt(sampleSize).RoundToInt();
|
int sampleDepth = Math.Sqrt(sampleSize).RoundToInt();
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@ namespace Artemis.Core.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class CoreService : ICoreService
|
internal class CoreService : ICoreService
|
||||||
{
|
{
|
||||||
internal static IKernel Kernel;
|
internal static IKernel Kernel = null!;
|
||||||
|
|
||||||
private readonly Stopwatch _frameStopWatch;
|
private readonly Stopwatch _frameStopWatch;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
@ -32,10 +32,10 @@ namespace Artemis.Core.Services
|
|||||||
private readonly IProfileService _profileService;
|
private readonly IProfileService _profileService;
|
||||||
private readonly IRgbService _rgbService;
|
private readonly IRgbService _rgbService;
|
||||||
private readonly ISurfaceService _surfaceService;
|
private readonly ISurfaceService _surfaceService;
|
||||||
private List<BaseDataModelExpansion> _dataModelExpansions;
|
private List<BaseDataModelExpansion> _dataModelExpansions = new List<BaseDataModelExpansion>();
|
||||||
private List<Module> _modules;
|
private List<Module> _modules = new List<Module>();
|
||||||
|
|
||||||
// ReSharper disable once UnusedParameter.Local - Storage migration service is injected early to ensure it runs before anything else
|
// ReSharper disable UnusedParameter.Local - Storage migration and module service are injected early to ensure it runs before anything else
|
||||||
public CoreService(IKernel kernel, ILogger logger, StorageMigrationService _, ISettingsService settingsService, IPluginManagementService pluginManagementService,
|
public CoreService(IKernel kernel, ILogger logger, StorageMigrationService _, ISettingsService settingsService, IPluginManagementService pluginManagementService,
|
||||||
IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService, IModuleService moduleService)
|
IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService, IModuleService moduleService)
|
||||||
{
|
{
|
||||||
@ -60,10 +60,11 @@ namespace Artemis.Core.Services
|
|||||||
_pluginManagementService.PluginEnabled += (sender, args) => UpdatePluginCache();
|
_pluginManagementService.PluginEnabled += (sender, args) => UpdatePluginCache();
|
||||||
_pluginManagementService.PluginDisabled += (sender, args) => UpdatePluginCache();
|
_pluginManagementService.PluginDisabled += (sender, args) => UpdatePluginCache();
|
||||||
}
|
}
|
||||||
|
// ReSharper restore UnusedParameter.Local
|
||||||
|
|
||||||
public TimeSpan FrameTime { get; private set; }
|
public TimeSpan FrameTime { get; private set; }
|
||||||
public bool ModuleRenderingDisabled { get; set; }
|
public bool ModuleRenderingDisabled { get; set; }
|
||||||
public List<string> StartupArguments { get; set; }
|
public List<string>? StartupArguments { get; set; }
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
@ -86,13 +87,10 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
// Initialize the services
|
// Initialize the services
|
||||||
_pluginManagementService.CopyBuiltInPlugins();
|
_pluginManagementService.CopyBuiltInPlugins();
|
||||||
_pluginManagementService.LoadPlugins(StartupArguments.Contains("--ignore-plugin-lock"));
|
_pluginManagementService.LoadPlugins(StartupArguments != null && StartupArguments.Contains("--ignore-plugin-lock"));
|
||||||
|
|
||||||
ArtemisSurface surfaceConfig = _surfaceService.ActiveSurface;
|
ArtemisSurface surfaceConfig = _surfaceService.ActiveSurface;
|
||||||
if (surfaceConfig != null)
|
_logger.Information("Initialized with active surface entity {surfaceConfig}-{guid}", surfaceConfig.Name, surfaceConfig.EntityId);
|
||||||
_logger.Information("Initialized with active surface entity {surfaceConfig}-{guid}", surfaceConfig.Name, surfaceConfig.EntityId);
|
|
||||||
else
|
|
||||||
_logger.Information("Initialized without an active surface entity");
|
|
||||||
|
|
||||||
PlayIntroAnimation();
|
PlayIntroAnimation();
|
||||||
OnInitialized();
|
OnInitialized();
|
||||||
@ -121,7 +119,7 @@ namespace Artemis.Core.Services
|
|||||||
FrameRendering += DrawOverlay;
|
FrameRendering += DrawOverlay;
|
||||||
|
|
||||||
// Stop rendering after the profile finishes (take 1 second extra in case of slow updates)
|
// Stop rendering after the profile finishes (take 1 second extra in case of slow updates)
|
||||||
TimeSpan introLength = intro.AnimationProfile.GetAllLayers().Max(l => l.Timeline.Length);
|
TimeSpan introLength = intro.AnimationProfile.GetAllLayers().Max(l => l.Timeline.Length)!;
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await Task.Delay(introLength.Add(TimeSpan.FromSeconds(1)));
|
await Task.Delay(introLength.Add(TimeSpan.FromSeconds(1)));
|
||||||
@ -217,14 +215,14 @@ namespace Artemis.Core.Services
|
|||||||
if (_rgbService.IsRenderPaused)
|
if (_rgbService.IsRenderPaused)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OnFrameRendered(new FrameRenderedEventArgs(_rgbService.BitmapBrush, _rgbService.Surface));
|
OnFrameRendered(new FrameRenderedEventArgs(_rgbService.BitmapBrush!, _rgbService.Surface));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public event EventHandler Initialized;
|
public event EventHandler? Initialized;
|
||||||
public event EventHandler<FrameRenderingEventArgs> FrameRendering;
|
public event EventHandler<FrameRenderingEventArgs>? FrameRendering;
|
||||||
public event EventHandler<FrameRenderedEventArgs> FrameRendered;
|
public event EventHandler<FrameRenderedEventArgs>? FrameRendered;
|
||||||
|
|
||||||
private void OnInitialized()
|
private void OnInitialized()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -26,7 +26,7 @@ namespace Artemis.Core.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a list of startup arguments
|
/// Gets or sets a list of startup arguments
|
||||||
/// </summary>
|
/// </summary>
|
||||||
List<string> StartupArguments { get; set; }
|
List<string>? StartupArguments { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the core, only call once
|
/// Initializes the core, only call once
|
||||||
|
|||||||
@ -12,13 +12,13 @@ namespace Artemis.Core.Services
|
|||||||
/// Gets the current active module override. If set, all other modules are deactivated and only the
|
/// Gets the current active module override. If set, all other modules are deactivated and only the
|
||||||
/// <see cref="ActiveModuleOverride" /> is active.
|
/// <see cref="ActiveModuleOverride" /> is active.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Module ActiveModuleOverride { get; }
|
Module? ActiveModuleOverride { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Changes the current <see cref="ActiveModuleOverride" /> and deactivates all other modules
|
/// Changes the current <see cref="ActiveModuleOverride" /> and deactivates all other modules
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="overrideModule"></param>
|
/// <param name="overrideModule"></param>
|
||||||
Task SetActiveModuleOverride(Module overrideModule);
|
Task SetActiveModuleOverride(Module? overrideModule);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Evaluates every enabled module's activation requirements and activates/deactivates modules accordingly
|
/// Evaluates every enabled module's activation requirements and activates/deactivates modules accordingly
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace Artemis.Core.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the bitmap brush used to convert the rendered frame to LED-colors
|
/// Gets the bitmap brush used to convert the rendered frame to LED-colors
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BitmapBrush BitmapBrush { get; }
|
BitmapBrush? BitmapBrush { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the scale the frames are rendered on, a scale of 1.0 means 1 pixel = 1mm
|
/// Gets the scale the frames are rendered on, a scale of 1.0 means 1 pixel = 1mm
|
||||||
|
|||||||
@ -149,9 +149,9 @@ namespace Artemis.Core.Services
|
|||||||
UpdateModulePriority(module, category, priority);
|
UpdateModulePriority(module, category, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Module ActiveModuleOverride { get; private set; }
|
public Module? ActiveModuleOverride { get; private set; }
|
||||||
|
|
||||||
public async Task SetActiveModuleOverride(Module overrideModule)
|
public async Task SetActiveModuleOverride(Module? overrideModule)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@ -242,12 +242,10 @@ namespace Artemis.Core.Services
|
|||||||
throw new ArtemisCoreException("Cannot load a plugin that is already loaded");
|
throw new ArtemisCoreException("Cannot load a plugin that is already loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin plugin = new Plugin(pluginInfo, directory);
|
|
||||||
OnPluginLoading(new PluginEventArgs(plugin));
|
|
||||||
|
|
||||||
// Load the entity and fall back on creating a new one
|
// Load the entity and fall back on creating a new one
|
||||||
plugin.Entity = _pluginRepository.GetPluginByGuid(pluginInfo.Guid) ?? new PluginEntity {Id = plugin.Guid, IsEnabled = true};
|
Plugin plugin = new Plugin(pluginInfo, directory, _pluginRepository.GetPluginByGuid(pluginInfo.Guid));
|
||||||
|
OnPluginLoading(new PluginEventArgs(plugin));
|
||||||
|
|
||||||
// Locate the main assembly entry
|
// Locate the main assembly entry
|
||||||
string? mainFile = plugin.ResolveRelativePath(plugin.Info.Main);
|
string? mainFile = plugin.ResolveRelativePath(plugin.Info.Main);
|
||||||
if (!File.Exists(mainFile))
|
if (!File.Exists(mainFile))
|
||||||
|
|||||||
@ -34,7 +34,7 @@ namespace Artemis.Core.Services
|
|||||||
return ConditionOperatorStore.GetForType(type, side).Select(r => r.ConditionOperator).ToList();
|
return ConditionOperatorStore.GetForType(type, side).Select(r => r.ConditionOperator).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseConditionOperator GetConditionOperator(Guid operatorPluginGuid, string operatorType)
|
public BaseConditionOperator? GetConditionOperator(Guid operatorPluginGuid, string operatorType)
|
||||||
{
|
{
|
||||||
return ConditionOperatorStore.Get(operatorPluginGuid, operatorType)?.ConditionOperator;
|
return ConditionOperatorStore.Get(operatorPluginGuid, operatorType)?.ConditionOperator;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ namespace Artemis.Core.Services
|
|||||||
return DataBindingModifierTypeStore.GetForType(type, part).Select(r => r.DataBindingModifierType).ToList();
|
return DataBindingModifierTypeStore.GetForType(type, part).Select(r => r.DataBindingModifierType).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseDataBindingModifierType GetModifierType(Guid modifierTypePluginGuid, string modifierType)
|
public BaseDataBindingModifierType? GetModifierType(Guid modifierTypePluginGuid, string modifierType)
|
||||||
{
|
{
|
||||||
return DataBindingModifierTypeStore.Get(modifierTypePluginGuid, modifierType)?.DataBindingModifierType;
|
return DataBindingModifierTypeStore.Get(modifierTypePluginGuid, modifierType)?.DataBindingModifierType;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace Artemis.Core.Services
|
|||||||
public DataModelService(IPluginManagementService pluginManagementService)
|
public DataModelService(IPluginManagementService pluginManagementService)
|
||||||
{
|
{
|
||||||
// Add data models of already loaded plugins
|
// Add data models of already loaded plugins
|
||||||
foreach (Module module in pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled))
|
foreach (Module module in pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled && p.InternalDataModel != null))
|
||||||
AddModuleDataModel(module);
|
AddModuleDataModel(module);
|
||||||
foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetFeaturesOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetFeaturesOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
||||||
AddDataModelExpansionDataModel(dataModelExpansion);
|
AddDataModelExpansionDataModel(dataModelExpansion);
|
||||||
@ -40,9 +40,9 @@ namespace Artemis.Core.Services
|
|||||||
return DataModelStore.GetAll().Select(d => d.DataModel).ToList();
|
return DataModelStore.GetAll().Select(d => d.DataModel).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetDataModel<T>() where T : DataModel
|
public T? GetDataModel<T>() where T : DataModel
|
||||||
{
|
{
|
||||||
return (T) DataModelStore.GetAll().FirstOrDefault(d => d.DataModel is T)?.DataModel;
|
return (T?) DataModelStore.GetAll().FirstOrDefault(d => d.DataModel is T)?.DataModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModel? GetPluginDataModel(PluginFeature pluginFeature)
|
public DataModel? GetPluginDataModel(PluginFeature pluginFeature)
|
||||||
@ -61,8 +61,7 @@ namespace Artemis.Core.Services
|
|||||||
private void AddModuleDataModel(Module module)
|
private void AddModuleDataModel(Module module)
|
||||||
{
|
{
|
||||||
if (module.InternalDataModel == null)
|
if (module.InternalDataModel == null)
|
||||||
return;
|
throw new ArtemisCoreException("Cannot add module data model that is not enabled");
|
||||||
|
|
||||||
if (module.InternalDataModel.DataModelDescription == null)
|
if (module.InternalDataModel.DataModelDescription == null)
|
||||||
throw new ArtemisPluginFeatureException(module, "Module overrides GetDataModelDescription but returned null");
|
throw new ArtemisPluginFeatureException(module, "Module overrides GetDataModelDescription but returned null");
|
||||||
|
|
||||||
@ -72,6 +71,8 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
private void AddDataModelExpansionDataModel(BaseDataModelExpansion dataModelExpansion)
|
private void AddDataModelExpansionDataModel(BaseDataModelExpansion dataModelExpansion)
|
||||||
{
|
{
|
||||||
|
if (dataModelExpansion.InternalDataModel == null)
|
||||||
|
throw new ArtemisCoreException("Cannot add data model expansion that is not enabled");
|
||||||
if (dataModelExpansion.InternalDataModel.DataModelDescription == null)
|
if (dataModelExpansion.InternalDataModel.DataModelDescription == null)
|
||||||
throw new ArtemisPluginFeatureException(dataModelExpansion, "Data model expansion overrides GetDataModelDescription but returned null");
|
throw new ArtemisPluginFeatureException(dataModelExpansion, "Data model expansion overrides GetDataModelDescription but returned null");
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,6 @@ namespace Artemis.Core.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="operatorPluginGuid">The operator's plugin GUID</param>
|
/// <param name="operatorPluginGuid">The operator's plugin GUID</param>
|
||||||
/// <param name="operatorType">The type name of the operator</param>
|
/// <param name="operatorType">The type name of the operator</param>
|
||||||
BaseConditionOperator GetConditionOperator(Guid operatorPluginGuid, string operatorType);
|
BaseConditionOperator? GetConditionOperator(Guid operatorPluginGuid, string operatorType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -33,6 +33,6 @@ namespace Artemis.Core.Services
|
|||||||
/// <param name="modifierTypePluginGuid">The modifier type's plugin GUID</param>
|
/// <param name="modifierTypePluginGuid">The modifier type's plugin GUID</param>
|
||||||
/// <param name="modifierType">The type name of the modifier type</param>
|
/// <param name="modifierType">The type name of the modifier type</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
BaseDataBindingModifierType GetModifierType(Guid modifierTypePluginGuid, string modifierType);
|
BaseDataBindingModifierType? GetModifierType(Guid modifierTypePluginGuid, string modifierType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ namespace Artemis.Core.Services
|
|||||||
/// If found, returns the registered data model of type <typeparamref name="T" />
|
/// If found, returns the registered data model of type <typeparamref name="T" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the data model to find</typeparam>
|
/// <typeparam name="T">The type of the data model to find</typeparam>
|
||||||
T GetDataModel<T>() where T : DataModel;
|
T? GetDataModel<T>() where T : DataModel;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If found, returns the data model of the provided plugin
|
/// If found, returns the data model of the provided plugin
|
||||||
|
|||||||
@ -34,7 +34,7 @@ namespace Artemis.Core.Services
|
|||||||
return LayerBrushStore.GetAll().Select(r => r.LayerBrushDescriptor).ToList();
|
return LayerBrushStore.GetAll().Select(r => r.LayerBrushDescriptor).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LayerBrushDescriptor GetDefaultLayerBrush()
|
public LayerBrushDescriptor? GetDefaultLayerBrush()
|
||||||
{
|
{
|
||||||
PluginSetting<LayerBrushReference> defaultReference = _settingsService.GetSetting("ProfileEditor.DefaultLayerBrushDescriptor", new LayerBrushReference
|
PluginSetting<LayerBrushReference> defaultReference = _settingsService.GetSetting("ProfileEditor.DefaultLayerBrushDescriptor", new LayerBrushReference
|
||||||
{
|
{
|
||||||
@ -42,6 +42,8 @@ namespace Artemis.Core.Services
|
|||||||
BrushType = "ColorBrush"
|
BrushType = "ColorBrush"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
defaultReference.Value.LayerBrushProviderId ??= "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba";
|
||||||
|
defaultReference.Value.BrushType ??= "ColorBrush";
|
||||||
return LayerBrushStore.Get(defaultReference.Value.LayerBrushProviderId, defaultReference.Value.BrushType)?.LayerBrushDescriptor;
|
return LayerBrushStore.Get(defaultReference.Value.LayerBrushProviderId, defaultReference.Value.BrushType)?.LayerBrushDescriptor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace Artemis.Core.Services
|
|||||||
private readonly PluginSetting<double> _renderScaleSetting;
|
private readonly PluginSetting<double> _renderScaleSetting;
|
||||||
private readonly PluginSetting<int> _sampleSizeSetting;
|
private readonly PluginSetting<int> _sampleSizeSetting;
|
||||||
private readonly PluginSetting<int> _targetFrameRateSetting;
|
private readonly PluginSetting<int> _targetFrameRateSetting;
|
||||||
private ListLedGroup _surfaceLedGroup;
|
private ListLedGroup? _surfaceLedGroup;
|
||||||
|
|
||||||
public RgbService(ILogger logger, ISettingsService settingsService)
|
public RgbService(ILogger logger, ISettingsService settingsService)
|
||||||
{
|
{
|
||||||
@ -41,7 +41,7 @@ namespace Artemis.Core.Services
|
|||||||
public RGBSurface Surface { get; set; }
|
public RGBSurface Surface { get; set; }
|
||||||
|
|
||||||
public TimerUpdateTrigger UpdateTrigger { get; }
|
public TimerUpdateTrigger UpdateTrigger { get; }
|
||||||
public BitmapBrush BitmapBrush { get; private set; }
|
public BitmapBrush? BitmapBrush { get; private set; }
|
||||||
public IReadOnlyCollection<IRGBDevice> LoadedDevices => _loadedDevices.AsReadOnly();
|
public IReadOnlyCollection<IRGBDevice> LoadedDevices => _loadedDevices.AsReadOnly();
|
||||||
public double RenderScale => _renderScaleSetting.Value;
|
public double RenderScale => _renderScaleSetting.Value;
|
||||||
public bool IsRenderPaused { get; set; }
|
public bool IsRenderPaused { get; set; }
|
||||||
@ -109,7 +109,7 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
public void UpdateSurfaceLedGroup()
|
public void UpdateSurfaceLedGroup()
|
||||||
{
|
{
|
||||||
if (_surfaceLedGroup == null)
|
if (_surfaceLedGroup == null || BitmapBrush == null)
|
||||||
{
|
{
|
||||||
// Apply the application wide brush and decorator
|
// Apply the application wide brush and decorator
|
||||||
BitmapBrush = new BitmapBrush(new Scale(_renderScaleSetting.Value), _sampleSizeSetting);
|
BitmapBrush = new BitmapBrush(new Scale(_renderScaleSetting.Value), _sampleSizeSetting);
|
||||||
@ -126,10 +126,6 @@ namespace Artemis.Core.Services
|
|||||||
BitmapBrush.Scale = new Scale(_renderScaleSetting.Value);
|
BitmapBrush.Scale = new Scale(_renderScaleSetting.Value);
|
||||||
_surfaceLedGroup = new ListLedGroup(Surface.Leds) {Brush = BitmapBrush};
|
_surfaceLedGroup = new ListLedGroup(Surface.Leds) {Brush = BitmapBrush};
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (BitmapBrush)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDeviceLoaded(DeviceEventArgs e)
|
private void OnDeviceLoaded(DeviceEventArgs e)
|
||||||
|
|||||||
@ -14,7 +14,7 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
public PluginSetting<T> GetSetting<T>(string name, T defaultValue = default)
|
public PluginSetting<T> GetSetting<T>(string name, T defaultValue = default)
|
||||||
{
|
{
|
||||||
return _pluginSettings.GetSetting(name, defaultValue);
|
return _pluginSettings.GetSetting(name, defaultValue!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,40 @@ namespace Artemis.Core.Services
|
|||||||
public JsonSerializerSettings MementoSettings { get; set; } = new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All};
|
public JsonSerializerSettings MementoSettings { get; set; } = new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All};
|
||||||
public JsonSerializerSettings ExportSettings { get; set; } = new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All, Formatting = Formatting.Indented};
|
public JsonSerializerSettings ExportSettings { get; set; } = new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All, Formatting = Formatting.Indented};
|
||||||
|
|
||||||
|
public ProfileDescriptor? GetLastActiveProfile(ProfileModule module)
|
||||||
|
{
|
||||||
|
List<ProfileEntity> moduleProfiles = _profileRepository.GetByModuleId(module.Id);
|
||||||
|
if (!moduleProfiles.Any())
|
||||||
|
return CreateProfileDescriptor(module, "Default");
|
||||||
|
|
||||||
|
ProfileEntity? profileEntity = moduleProfiles.FirstOrDefault(p => p.IsActive) ?? moduleProfiles.FirstOrDefault();
|
||||||
|
return profileEntity == null ? null : new ProfileDescriptor(module, profileEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveActiveProfile(ProfileModule module)
|
||||||
|
{
|
||||||
|
if (module.ActiveProfile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
List<ProfileEntity> profileEntities = _profileRepository.GetByModuleId(module.Id);
|
||||||
|
foreach (ProfileEntity profileEntity in profileEntities)
|
||||||
|
{
|
||||||
|
profileEntity.IsActive = module.ActiveProfile.EntityId == profileEntity.Id;
|
||||||
|
_profileRepository.Save(profileEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Populates all missing LEDs on all currently active profiles
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="surface"></param>
|
||||||
|
private void ActiveProfilesPopulateLeds(ArtemisSurface surface)
|
||||||
|
{
|
||||||
|
List<ProfileModule> profileModules = _pluginManagementService.GetFeaturesOfType<ProfileModule>();
|
||||||
|
foreach (ProfileModule profileModule in profileModules.Where(p => p.ActiveProfile != null).ToList())
|
||||||
|
profileModule.ActiveProfile?.PopulateLeds(surface); // Avoid race condition
|
||||||
|
}
|
||||||
|
|
||||||
public List<ProfileDescriptor> GetProfileDescriptors(ProfileModule module)
|
public List<ProfileDescriptor> GetProfileDescriptors(ProfileModule module)
|
||||||
{
|
{
|
||||||
List<ProfileEntity> profileEntities = _profileRepository.GetByModuleId(module.Id);
|
List<ProfileEntity> profileEntities = _profileRepository.GetByModuleId(module.Id);
|
||||||
@ -52,14 +86,14 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
public void ActivateLastProfile(ProfileModule profileModule)
|
public void ActivateLastProfile(ProfileModule profileModule)
|
||||||
{
|
{
|
||||||
ProfileDescriptor activeProfile = GetLastActiveProfile(profileModule);
|
ProfileDescriptor? activeProfile = GetLastActiveProfile(profileModule);
|
||||||
if (activeProfile != null)
|
if (activeProfile != null)
|
||||||
ActivateProfile(activeProfile);
|
ActivateProfile(activeProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ActivateLastProfileAnimated(ProfileModule profileModule)
|
public async Task ActivateLastProfileAnimated(ProfileModule profileModule)
|
||||||
{
|
{
|
||||||
ProfileDescriptor activeProfile = GetLastActiveProfile(profileModule);
|
ProfileDescriptor? activeProfile = GetLastActiveProfile(profileModule);
|
||||||
if (activeProfile != null)
|
if (activeProfile != null)
|
||||||
await ActivateProfileAnimated(activeProfile);
|
await ActivateProfileAnimated(activeProfile);
|
||||||
}
|
}
|
||||||
@ -196,7 +230,8 @@ namespace Artemis.Core.Services
|
|||||||
string top = profile.UndoStack.Pop();
|
string top = profile.UndoStack.Pop();
|
||||||
string memento = JsonConvert.SerializeObject(profile.ProfileEntity, MementoSettings);
|
string memento = JsonConvert.SerializeObject(profile.ProfileEntity, MementoSettings);
|
||||||
profile.RedoStack.Push(memento);
|
profile.RedoStack.Push(memento);
|
||||||
profile.ProfileEntity = JsonConvert.DeserializeObject<ProfileEntity>(top, MementoSettings);
|
profile.ProfileEntity = JsonConvert.DeserializeObject<ProfileEntity>(top, MementoSettings)
|
||||||
|
?? throw new InvalidOperationException("Failed to deserialize memento");
|
||||||
|
|
||||||
profile.Load();
|
profile.Load();
|
||||||
InstantiateProfile(profile);
|
InstantiateProfile(profile);
|
||||||
@ -220,7 +255,8 @@ namespace Artemis.Core.Services
|
|||||||
string top = profile.RedoStack.Pop();
|
string top = profile.RedoStack.Pop();
|
||||||
string memento = JsonConvert.SerializeObject(profile.ProfileEntity, MementoSettings);
|
string memento = JsonConvert.SerializeObject(profile.ProfileEntity, MementoSettings);
|
||||||
profile.UndoStack.Push(memento);
|
profile.UndoStack.Push(memento);
|
||||||
profile.ProfileEntity = JsonConvert.DeserializeObject<ProfileEntity>(top, MementoSettings);
|
profile.ProfileEntity = JsonConvert.DeserializeObject<ProfileEntity>(top, MementoSettings)
|
||||||
|
?? throw new InvalidOperationException("Failed to deserialize memento");
|
||||||
|
|
||||||
profile.Load();
|
profile.Load();
|
||||||
InstantiateProfile(profile);
|
InstantiateProfile(profile);
|
||||||
@ -246,7 +282,9 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
public ProfileDescriptor ImportProfile(string json, ProfileModule profileModule)
|
public ProfileDescriptor ImportProfile(string json, ProfileModule profileModule)
|
||||||
{
|
{
|
||||||
ProfileEntity profileEntity = JsonConvert.DeserializeObject<ProfileEntity>(json, ExportSettings);
|
ProfileEntity? profileEntity = JsonConvert.DeserializeObject<ProfileEntity>(json, ExportSettings);
|
||||||
|
if (profileEntity == null)
|
||||||
|
throw new ArtemisCoreException("Failed to import profile but JSON.NET threw no error :(");
|
||||||
|
|
||||||
// Assign a new GUID to make sure it is unique in case of a previous import of the same content
|
// Assign a new GUID to make sure it is unique in case of a previous import of the same content
|
||||||
profileEntity.UpdateGuid(Guid.NewGuid());
|
profileEntity.UpdateGuid(Guid.NewGuid());
|
||||||
@ -256,40 +294,6 @@ namespace Artemis.Core.Services
|
|||||||
return new ProfileDescriptor(profileModule, profileEntity);
|
return new ProfileDescriptor(profileModule, profileEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileDescriptor GetLastActiveProfile(ProfileModule module)
|
|
||||||
{
|
|
||||||
List<ProfileEntity> moduleProfiles = _profileRepository.GetByModuleId(module.Id);
|
|
||||||
if (!moduleProfiles.Any())
|
|
||||||
return CreateProfileDescriptor(module, "Default");
|
|
||||||
|
|
||||||
ProfileEntity profileEntity = moduleProfiles.FirstOrDefault(p => p.IsActive) ?? moduleProfiles.FirstOrDefault();
|
|
||||||
return profileEntity == null ? null : new ProfileDescriptor(module, profileEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveActiveProfile(ProfileModule module)
|
|
||||||
{
|
|
||||||
if (module.ActiveProfile == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
List<ProfileEntity> profileEntities = _profileRepository.GetByModuleId(module.Id);
|
|
||||||
foreach (ProfileEntity profileEntity in profileEntities)
|
|
||||||
{
|
|
||||||
profileEntity.IsActive = module.ActiveProfile.EntityId == profileEntity.Id;
|
|
||||||
_profileRepository.Save(profileEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Populates all missing LEDs on all currently active profiles
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="surface"></param>
|
|
||||||
private void ActiveProfilesPopulateLeds(ArtemisSurface surface)
|
|
||||||
{
|
|
||||||
List<ProfileModule> profileModules = _pluginManagementService.GetFeaturesOfType<ProfileModule>();
|
|
||||||
foreach (ProfileModule profileModule in profileModules.Where(p => p.ActiveProfile != null).ToList())
|
|
||||||
profileModule.ActiveProfile.PopulateLeds(surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void OnActiveSurfaceConfigurationSelected(object? sender, SurfaceConfigurationEventArgs e)
|
private void OnActiveSurfaceConfigurationSelected(object? sender, SurfaceConfigurationEventArgs e)
|
||||||
|
|||||||
@ -28,6 +28,8 @@ namespace Artemis.Core.Services
|
|||||||
_surfaceConfigurations = new List<ArtemisSurface>();
|
_surfaceConfigurations = new List<ArtemisSurface>();
|
||||||
_renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.5);
|
_renderScaleSetting = settingsService.GetSetting("Core.RenderScale", 0.5);
|
||||||
|
|
||||||
|
// LoadFromRepository is guaranteed to set the ActiveSurface
|
||||||
|
ActiveSurface = null!;
|
||||||
LoadFromRepository();
|
LoadFromRepository();
|
||||||
|
|
||||||
_rgbService.DeviceLoaded += RgbServiceOnDeviceLoaded;
|
_rgbService.DeviceLoaded += RgbServiceOnDeviceLoaded;
|
||||||
@ -61,6 +63,7 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
public void SetActiveSurfaceConfiguration(ArtemisSurface surface)
|
public void SetActiveSurfaceConfiguration(ArtemisSurface surface)
|
||||||
{
|
{
|
||||||
|
if (surface == null) throw new ArgumentNullException(nameof(surface));
|
||||||
if (ActiveSurface == surface)
|
if (ActiveSurface == surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -81,11 +84,8 @@ namespace Artemis.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply the active surface entity to the devices
|
// Apply the active surface entity to the devices
|
||||||
if (ActiveSurface != null)
|
foreach (ArtemisDevice device in ActiveSurface.Devices)
|
||||||
{
|
device.ApplyToRgbDevice();
|
||||||
foreach (ArtemisDevice device in ActiveSurface.Devices)
|
|
||||||
device.ApplyToRgbDevice();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the RGB service's graphics decorator to work with the new surface entity
|
// Update the RGB service's graphics decorator to work with the new surface entity
|
||||||
_rgbService.UpdateSurfaceLedGroup();
|
_rgbService.UpdateSurfaceLedGroup();
|
||||||
@ -134,7 +134,7 @@ namespace Artemis.Core.Services
|
|||||||
ArtemisSurface surfaceConfiguration = new ArtemisSurface(_rgbService.Surface, surfaceEntity, _renderScaleSetting.Value);
|
ArtemisSurface surfaceConfiguration = new ArtemisSurface(_rgbService.Surface, surfaceEntity, _renderScaleSetting.Value);
|
||||||
foreach (DeviceEntity position in surfaceEntity.DeviceEntities)
|
foreach (DeviceEntity position in surfaceEntity.DeviceEntities)
|
||||||
{
|
{
|
||||||
IRGBDevice device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceIdentifier() == position.DeviceIdentifier);
|
IRGBDevice? device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceIdentifier() == position.DeviceIdentifier);
|
||||||
if (device != null)
|
if (device != null)
|
||||||
{
|
{
|
||||||
DeviceProvider deviceProvider = _pluginManagementService.GetDeviceProviderByDevice(device);
|
DeviceProvider deviceProvider = _pluginManagementService.GetDeviceProviderByDevice(device);
|
||||||
@ -150,7 +150,7 @@ namespace Artemis.Core.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When all surface configs are loaded, apply the active surface config
|
// When all surface configs are loaded, apply the active surface config
|
||||||
ArtemisSurface active = SurfaceConfigurations.FirstOrDefault(c => c.IsActive);
|
ArtemisSurface? active = SurfaceConfigurations.FirstOrDefault(c => c.IsActive);
|
||||||
if (active != null)
|
if (active != null)
|
||||||
SetActiveSurfaceConfiguration(active);
|
SetActiveSurfaceConfiguration(active);
|
||||||
else
|
else
|
||||||
@ -170,13 +170,13 @@ namespace Artemis.Core.Services
|
|||||||
private void AddDeviceIfMissing(IRGBDevice rgbDevice, ArtemisSurface surface)
|
private void AddDeviceIfMissing(IRGBDevice rgbDevice, ArtemisSurface surface)
|
||||||
{
|
{
|
||||||
string deviceIdentifier = rgbDevice.GetDeviceIdentifier();
|
string deviceIdentifier = rgbDevice.GetDeviceIdentifier();
|
||||||
ArtemisDevice device = surface.Devices.FirstOrDefault(d => d.DeviceEntity.DeviceIdentifier == deviceIdentifier);
|
ArtemisDevice? device = surface.Devices.FirstOrDefault(d => d.DeviceEntity.DeviceIdentifier == deviceIdentifier);
|
||||||
|
|
||||||
if (device != null)
|
if (device != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Find an existing device config and use that
|
// Find an existing device config and use that
|
||||||
DeviceEntity existingDeviceConfig = surface.SurfaceEntity.DeviceEntities.FirstOrDefault(d => d.DeviceIdentifier == deviceIdentifier);
|
DeviceEntity? existingDeviceConfig = surface.SurfaceEntity.DeviceEntities.FirstOrDefault(d => d.DeviceIdentifier == deviceIdentifier);
|
||||||
if (existingDeviceConfig != null)
|
if (existingDeviceConfig != null)
|
||||||
{
|
{
|
||||||
DeviceProvider deviceProvider = _pluginManagementService.GetDeviceProviderByDevice(rgbDevice);
|
DeviceProvider deviceProvider = _pluginManagementService.GetDeviceProviderByDevice(rgbDevice);
|
||||||
@ -225,8 +225,8 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public event EventHandler<SurfaceConfigurationEventArgs> ActiveSurfaceConfigurationSelected;
|
public event EventHandler<SurfaceConfigurationEventArgs>? ActiveSurfaceConfigurationSelected;
|
||||||
public event EventHandler<SurfaceConfigurationEventArgs> SurfaceConfigurationUpdated;
|
public event EventHandler<SurfaceConfigurationEventArgs>? SurfaceConfigurationUpdated;
|
||||||
|
|
||||||
protected virtual void OnActiveSurfaceConfigurationChanged(SurfaceConfigurationEventArgs e)
|
protected virtual void OnActiveSurfaceConfigurationChanged(SurfaceConfigurationEventArgs e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,6 +10,9 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
public static ConditionOperatorRegistration Add(BaseConditionOperator conditionOperator)
|
public static ConditionOperatorRegistration Add(BaseConditionOperator conditionOperator)
|
||||||
{
|
{
|
||||||
|
if (conditionOperator.Plugin == null)
|
||||||
|
throw new ArtemisCoreException("Cannot add a condition operator to the store that is not related to a plugin");
|
||||||
|
|
||||||
ConditionOperatorRegistration registration;
|
ConditionOperatorRegistration registration;
|
||||||
lock (Registrations)
|
lock (Registrations)
|
||||||
{
|
{
|
||||||
@ -74,8 +77,8 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public static event EventHandler<ConditionOperatorStoreEvent> ConditionOperatorAdded;
|
public static event EventHandler<ConditionOperatorStoreEvent>? ConditionOperatorAdded;
|
||||||
public static event EventHandler<ConditionOperatorStoreEvent> ConditionOperatorRemoved;
|
public static event EventHandler<ConditionOperatorStoreEvent>? ConditionOperatorRemoved;
|
||||||
|
|
||||||
private static void OnConditionOperatorAdded(ConditionOperatorStoreEvent e)
|
private static void OnConditionOperatorAdded(ConditionOperatorStoreEvent e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -57,8 +57,8 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public static event EventHandler<DataModelStoreEvent> DataModelAdded;
|
public static event EventHandler<DataModelStoreEvent>? DataModelAdded;
|
||||||
public static event EventHandler<DataModelStoreEvent> DataModelRemoved;
|
public static event EventHandler<DataModelStoreEvent>? DataModelRemoved;
|
||||||
|
|
||||||
private static void OnDataModelAdded(DataModelStoreEvent e)
|
private static void OnDataModelAdded(DataModelStoreEvent e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -58,8 +58,8 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public static event EventHandler<LayerBrushStoreEvent> LayerBrushAdded;
|
public static event EventHandler<LayerBrushStoreEvent>? LayerBrushAdded;
|
||||||
public static event EventHandler<LayerBrushStoreEvent> LayerBrushRemoved;
|
public static event EventHandler<LayerBrushStoreEvent>? LayerBrushRemoved;
|
||||||
|
|
||||||
private static void OnLayerBrushAdded(LayerBrushStoreEvent e)
|
private static void OnLayerBrushAdded(LayerBrushStoreEvent e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -51,14 +51,14 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
lock (Registrations)
|
lock (Registrations)
|
||||||
{
|
{
|
||||||
return Registrations.FirstOrDefault(d => d.PluginFeature.Id == providerId && d.LayerEffectDescriptor.LayerEffectType.Name == typeName);
|
return Registrations.FirstOrDefault(d => d.PluginFeature.Id == providerId && d.LayerEffectDescriptor.LayerEffectType?.Name == typeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public static event EventHandler<LayerEffectStoreEvent> LayerEffectAdded;
|
public static event EventHandler<LayerEffectStoreEvent>? LayerEffectAdded;
|
||||||
public static event EventHandler<LayerEffectStoreEvent> LayerEffectRemoved;
|
public static event EventHandler<LayerEffectStoreEvent>? LayerEffectRemoved;
|
||||||
|
|
||||||
private static void OnLayerEffectAdded(LayerEffectStoreEvent e)
|
private static void OnLayerEffectAdded(LayerEffectStoreEvent e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -23,7 +23,7 @@ namespace Artemis.Core
|
|||||||
string arguments = "-Command \"& {Start-Sleep -s " + delay + "; (Get-Process 'Artemis.UI').kill()}";
|
string arguments = "-Command \"& {Start-Sleep -s " + delay + "; (Get-Process 'Artemis.UI').kill()}";
|
||||||
// If restart is required, start the executable again after the process was killed
|
// If restart is required, start the executable again after the process was killed
|
||||||
if (restart)
|
if (restart)
|
||||||
arguments = "-Command \"& {Start-Sleep -s " + delay + "; (Get-Process 'Artemis.UI').kill(); Start-Process -FilePath '" + Process.GetCurrentProcess().MainModule.FileName + "'}\"";
|
arguments = "-Command \"& {Start-Sleep -s " + delay + "; (Get-Process 'Artemis.UI').kill(); Start-Process -FilePath '" + Process.GetCurrentProcess().MainModule!.FileName + "'}\"";
|
||||||
|
|
||||||
ProcessStartInfo info = new ProcessStartInfo
|
ProcessStartInfo info = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
@ -45,7 +45,7 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="url">The URL to open</param>
|
/// <param name="url">The URL to open</param>
|
||||||
/// <returns>The process created to open the URL</returns>
|
/// <returns>The process created to open the URL</returns>
|
||||||
public static Process OpenUrl(string url)
|
public static Process? OpenUrl(string url)
|
||||||
{
|
{
|
||||||
ProcessStartInfo processInfo = new ProcessStartInfo
|
ProcessStartInfo processInfo = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
@ -61,7 +61,7 @@ namespace Artemis.Core
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal static string GetCurrentLocation()
|
internal static string GetCurrentLocation()
|
||||||
{
|
{
|
||||||
return Process.GetCurrentProcess().MainModule.FileName;
|
return Process.GetCurrentProcess().MainModule!.FileName!;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
internal static class DeserializationLogger
|
internal static class DeserializationLogger
|
||||||
{
|
{
|
||||||
private static ILogger _logger;
|
private static ILogger? _logger;
|
||||||
|
|
||||||
public static void Initialize(IKernel kernel)
|
public static void Initialize(IKernel kernel)
|
||||||
{
|
{
|
||||||
@ -15,7 +15,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
public static void LogPredicateDeserializationFailure(DataModelConditionPredicate dataModelConditionPredicate, JsonException exception)
|
public static void LogPredicateDeserializationFailure(DataModelConditionPredicate dataModelConditionPredicate, JsonException exception)
|
||||||
{
|
{
|
||||||
_logger.Warning(
|
_logger?.Warning(
|
||||||
exception,
|
exception,
|
||||||
"Failed to deserialize display condition predicate {left} {operator} {right}",
|
"Failed to deserialize display condition predicate {left} {operator} {right}",
|
||||||
dataModelConditionPredicate.Entity.LeftPath?.Path,
|
dataModelConditionPredicate.Entity.LeftPath?.Path,
|
||||||
@ -26,7 +26,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
public static void LogModifierDeserializationFailure(string modifierName, JsonSerializationException exception)
|
public static void LogModifierDeserializationFailure(string modifierName, JsonSerializationException exception)
|
||||||
{
|
{
|
||||||
_logger.Warning(exception, "Failed to deserialize static parameter for modifier {modifierName}", modifierName);
|
_logger?.Warning(exception, "Failed to deserialize static parameter for modifier {modifierName}", modifierName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
// Create an expression that checks every part of the path for null
|
// Create an expression that checks every part of the path for null
|
||||||
// In the same iteration, create the accessor
|
// In the same iteration, create the accessor
|
||||||
Expression condition = null;
|
Expression? condition = null;
|
||||||
foreach (string memberName in path.Split('.'))
|
foreach (string memberName in path.Split('.'))
|
||||||
{
|
{
|
||||||
BinaryExpression notNull = Expression.NotEqual(source, Expression.Constant(null));
|
BinaryExpression notNull = Expression.NotEqual(source, Expression.Constant(null));
|
||||||
|
|||||||
@ -21,21 +21,19 @@ namespace Artemis.Core
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
_profileService = profileService;
|
_profileService = profileService;
|
||||||
_surfaceService = surfaceService;
|
_surfaceService = surfaceService;
|
||||||
CreateIntroProfile();
|
|
||||||
|
AnimationProfile = CreateIntroProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Profile AnimationProfile { get; set; }
|
public Profile AnimationProfile { get; set; }
|
||||||
|
|
||||||
public void Render(double deltaTime, SKCanvas canvas)
|
public void Render(double deltaTime, SKCanvas canvas)
|
||||||
{
|
{
|
||||||
if (AnimationProfile == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AnimationProfile.Update(deltaTime);
|
AnimationProfile.Update(deltaTime);
|
||||||
AnimationProfile.Render(canvas);
|
AnimationProfile.Render(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateIntroProfile()
|
private Profile CreateIntroProfile()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -44,24 +42,24 @@ namespace Artemis.Core
|
|||||||
ProfileEntity profileEntity = JsonConvert.DeserializeObject<ProfileEntity>(json);
|
ProfileEntity profileEntity = JsonConvert.DeserializeObject<ProfileEntity>(json);
|
||||||
// Inject every LED on the surface into each layer
|
// Inject every LED on the surface into each layer
|
||||||
foreach (LayerEntity profileEntityLayer in profileEntity.Layers)
|
foreach (LayerEntity profileEntityLayer in profileEntity.Layers)
|
||||||
{
|
|
||||||
profileEntityLayer.Leds.AddRange(_surfaceService.ActiveSurface.Devices.SelectMany(d => d.Leds).Select(l => new LedEntity
|
profileEntityLayer.Leds.AddRange(_surfaceService.ActiveSurface.Devices.SelectMany(d => d.Leds).Select(l => new LedEntity
|
||||||
{
|
{
|
||||||
DeviceIdentifier = l.Device.RgbDevice.GetDeviceIdentifier(),
|
DeviceIdentifier = l.Device.RgbDevice.GetDeviceIdentifier(),
|
||||||
LedName = l.RgbLed.Id.ToString()
|
LedName = l.RgbLed.Id.ToString()
|
||||||
}));
|
}));
|
||||||
}
|
|
||||||
|
|
||||||
Profile profile = new Profile(new DummyModule(), profileEntity);
|
Profile profile = new Profile(new DummyModule(), profileEntity);
|
||||||
profile.Activate(_surfaceService.ActiveSurface);
|
profile.Activate(_surfaceService.ActiveSurface);
|
||||||
|
|
||||||
_profileService.InstantiateProfile(profile);
|
_profileService.InstantiateProfile(profile);
|
||||||
AnimationProfile = profile;
|
return profile;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Warning(e, "Failed to load intro profile");
|
_logger.Warning(e, "Failed to load intro profile");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new Profile(new DummyModule(), "Intro");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,11 +10,11 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
Type type = typeof(TSource);
|
Type type = typeof(TSource);
|
||||||
|
|
||||||
MemberExpression member = propertyLambda.Body as MemberExpression;
|
MemberExpression? member = propertyLambda.Body as MemberExpression;
|
||||||
if (member == null)
|
if (member == null)
|
||||||
throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", propertyLambda));
|
throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", propertyLambda));
|
||||||
|
|
||||||
PropertyInfo propInfo = member.Member as PropertyInfo;
|
PropertyInfo? propInfo = member.Member as PropertyInfo;
|
||||||
if (propInfo == null)
|
if (propInfo == null)
|
||||||
throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", propertyLambda));
|
throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", propertyLambda));
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user