mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
Core - Nullable refactoring
Core - Nullable refactoring Core - Nullable refactoring (finish)
This commit is contained in:
1 parent
b185b28645
commit
fb3466e102
61 files changed
+320
-272
No files matched your search
@@ -20,7 +20,7 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent 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();
|
||||
EntityId = Guid.NewGuid();
|
||||
@@ -29,14 +29,11 @@ namespace Artemis.Core
|
||||
Profile = Parent.Profile;
|
||||
Name = name;
|
||||
Enabled = true;
|
||||
|
||||
LayerEffectsList = new List<BaseLayerEffect>();
|
||||
ExpandedPropertyGroups = new List<string>();
|
||||
|
||||
|
||||
Parent.AddChild(this);
|
||||
}
|
||||
|
||||
internal Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity)
|
||||
internal Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity) : base(parent.Profile)
|
||||
{
|
||||
FolderEntity = folderEntity;
|
||||
EntityId = folderEntity.Id;
|
||||
@@ -46,10 +43,7 @@ namespace Artemis.Core
|
||||
Name = folderEntity.Name;
|
||||
Enabled = folderEntity.Enabled;
|
||||
Order = folderEntity.Order;
|
||||
|
||||
LayerEffectsList = new List<BaseLayerEffect>();
|
||||
ExpandedPropertyGroups = new List<string>();
|
||||
|
||||
|
||||
Load();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent 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();
|
||||
EntityId = Guid.NewGuid();
|
||||
@@ -39,16 +39,14 @@ namespace Artemis.Core
|
||||
Enabled = true;
|
||||
_general = new LayerGeneralProperties();
|
||||
_transform = new LayerTransformProperties();
|
||||
|
||||
LayerEffectsList = new List<BaseLayerEffect>();
|
||||
|
||||
_leds = new List<ArtemisLed>();
|
||||
ExpandedPropertyGroups = new List<string>();
|
||||
|
||||
|
||||
Initialize();
|
||||
Parent.AddChild(this);
|
||||
}
|
||||
|
||||
internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity)
|
||||
internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity) : base(parent.Profile)
|
||||
{
|
||||
LayerEntity = layerEntity;
|
||||
EntityId = layerEntity.Id;
|
||||
@@ -57,10 +55,8 @@ namespace Artemis.Core
|
||||
Parent = parent;
|
||||
_general = new LayerGeneralProperties();
|
||||
_transform = new LayerTransformProperties();
|
||||
|
||||
LayerEffectsList = new List<BaseLayerEffect>();
|
||||
|
||||
_leds = new List<ArtemisLed>();
|
||||
ExpandedPropertyGroups = new List<string>();
|
||||
|
||||
Load();
|
||||
Initialize();
|
||||
@@ -263,17 +259,12 @@ namespace Artemis.Core
|
||||
|
||||
private void ApplyShapeType()
|
||||
{
|
||||
switch (General.ShapeType.CurrentValue)
|
||||
LayerShape = General.ShapeType.CurrentValue switch
|
||||
{
|
||||
case LayerShapeType.Ellipse:
|
||||
LayerShape = new EllipseShape(this);
|
||||
break;
|
||||
case LayerShapeType.Rectangle:
|
||||
LayerShape = new RectangleShape(this);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
LayerShapeType.Ellipse => new EllipseShape(this),
|
||||
LayerShapeType.Rectangle => new RectangleShape(this),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -25,7 +25,13 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
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!;
|
||||
DefaultValue = default!;
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.LayerEffects;
|
||||
using Artemis.Core.Properties;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
using Humanizer;
|
||||
|
||||
@@ -30,6 +29,12 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
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>();
|
||||
_layerPropertyGroups = new List<LayerPropertyGroup>();
|
||||
}
|
||||
@@ -52,7 +57,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// The parent group of this group
|
||||
/// </summary>
|
||||
public LayerPropertyGroup Parent { get; internal set; }
|
||||
public LayerPropertyGroup? Parent { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path of this property group
|
||||
@@ -67,12 +72,12 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// The layer brush this property group belongs to
|
||||
/// </summary>
|
||||
public BaseLayerBrush LayerBrush { get; internal set; }
|
||||
public BaseLayerBrush? LayerBrush { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The layer effect this property group belongs to
|
||||
/// </summary>
|
||||
public BaseLayerEffect LayerEffect { get; internal set; }
|
||||
public BaseLayerEffect? LayerEffect { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the property is hidden in the UI
|
||||
@@ -139,19 +144,16 @@ namespace Artemis.Core
|
||||
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)
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
if (feature == null)
|
||||
throw new ArgumentNullException(nameof(feature));
|
||||
if (path == null) throw new ArgumentNullException(nameof(path));
|
||||
|
||||
// Doubt this will happen but let's make sure
|
||||
if (PropertiesInitialized)
|
||||
throw new ArtemisCoreException("Layer property group already initialized, wut");
|
||||
|
||||
Feature = feature;
|
||||
ProfileElement = profileElement;
|
||||
Feature = feature ?? throw new ArgumentNullException(nameof(feature));
|
||||
ProfileElement = profileElement ?? throw new ArgumentNullException(nameof(profileElement));
|
||||
Path = path.TrimEnd('.');
|
||||
|
||||
// Get all properties with a PropertyDescriptionAttribute
|
||||
@@ -209,8 +211,7 @@ namespace Artemis.Core
|
||||
if (!typeof(ILayerProperty).IsAssignableFrom(propertyInfo.PropertyType))
|
||||
throw new ArtemisPluginException($"Layer property with PropertyDescription attribute must be of type LayerProperty at {path}");
|
||||
|
||||
ILayerProperty instance = (ILayerProperty) Activator.CreateInstance(propertyInfo.PropertyType, true);
|
||||
if (instance == null)
|
||||
if (!(Activator.CreateInstance(propertyInfo.PropertyType, true) is ILayerProperty instance))
|
||||
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
|
||||
@@ -230,8 +231,7 @@ namespace Artemis.Core
|
||||
if (!typeof(LayerPropertyGroup).IsAssignableFrom(propertyInfo.PropertyType))
|
||||
throw new ArtemisPluginException("Layer property with PropertyGroupDescription attribute must be of type LayerPropertyGroup");
|
||||
|
||||
LayerPropertyGroup instance = (LayerPropertyGroup) Activator.CreateInstance(propertyInfo.PropertyType);
|
||||
if (instance == null)
|
||||
if (!(Activator.CreateInstance(propertyInfo.PropertyType) is LayerPropertyGroup instance))
|
||||
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
|
||||
@@ -250,7 +250,7 @@ namespace Artemis.Core
|
||||
|
||||
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;
|
||||
if (entity == null)
|
||||
{
|
||||
@@ -298,18 +298,18 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Occurs when the property group has initialized all its children
|
||||
/// </summary>
|
||||
public event EventHandler PropertyGroupInitialized;
|
||||
public event EventHandler? PropertyGroupInitialized;
|
||||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs> LayerPropertyOnCurrentValueSet;
|
||||
public event EventHandler<LayerPropertyEventArgs>? LayerPropertyOnCurrentValueSet;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the <see cref="IsHidden" /> value of the layer property was updated
|
||||
/// </summary>
|
||||
public event EventHandler VisibilityChanged;
|
||||
public event EventHandler? VisibilityChanged;
|
||||
|
||||
internal virtual void OnVisibilityChanged()
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets a the path outlining the shape
|
||||
/// </summary>
|
||||
public SKPath Path { get; protected set; }
|
||||
public SKPath? Path { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the <see cref="Path" />
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Artemis.Core
|
||||
private bool _isActivated;
|
||||
private readonly object _lock = new object();
|
||||
|
||||
internal Profile(ProfileModule module, string name)
|
||||
internal Profile(ProfileModule module, string name) : base(null!)
|
||||
{
|
||||
ProfileEntity = new ProfileEntity();
|
||||
EntityId = Guid.NewGuid();
|
||||
@@ -30,7 +30,7 @@ namespace Artemis.Core
|
||||
Save();
|
||||
}
|
||||
|
||||
internal Profile(ProfileModule module, ProfileEntity profileEntity)
|
||||
internal Profile(ProfileModule module, ProfileEntity profileEntity) : base(null!)
|
||||
{
|
||||
Profile = this;
|
||||
ProfileEntity = profileEntity;
|
||||
@@ -149,7 +149,7 @@ namespace Artemis.Core
|
||||
ChildrenList.Clear();
|
||||
|
||||
// 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)
|
||||
{
|
||||
Folder _ = new Folder(this, "Root folder");
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Artemis.Core
|
||||
{
|
||||
private bool _enabled;
|
||||
private Guid _entityId;
|
||||
private string _name;
|
||||
private string? _name;
|
||||
private int _order;
|
||||
private ProfileElement? _parent;
|
||||
private Profile _profile;
|
||||
@@ -21,8 +21,9 @@ namespace Artemis.Core
|
||||
internal List<ProfileElement> ChildrenList;
|
||||
internal bool Disposed;
|
||||
|
||||
internal ProfileElement()
|
||||
internal ProfileElement(Profile profile)
|
||||
{
|
||||
_profile = profile;
|
||||
ChildrenList = new List<ProfileElement>();
|
||||
}
|
||||
|
||||
@@ -56,7 +57,16 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// The element's children
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<ProfileElement> Children => ChildrenList.AsReadOnly();
|
||||
public ReadOnlyCollection<ProfileElement> Children
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (ChildrenList)
|
||||
{
|
||||
return ChildrenList.AsReadOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The order in which this element appears in the update loop and editor
|
||||
@@ -70,7 +80,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// The name which appears in the editor
|
||||
/// </summary>
|
||||
public string Name
|
||||
public string? Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetAndNotify(ref _name, value);
|
||||
|
||||
@@ -16,10 +16,12 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public abstract class RenderProfileElement : ProfileElement
|
||||
{
|
||||
internal RenderProfileElement()
|
||||
internal RenderProfileElement(Profile profile) : base(profile)
|
||||
{
|
||||
Timeline = new Timeline();
|
||||
Renderer = new Renderer();
|
||||
ExpandedPropertyGroups = new List<string>();
|
||||
LayerEffectsList = new List<BaseLayerEffect>();
|
||||
|
||||
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
|
||||
LayerEffectStore.LayerEffectRemoved += LayerEffectStoreOnLayerEffectRemoved;
|
||||
@@ -68,7 +70,7 @@ namespace Artemis.Core
|
||||
LayerEffectEntity layerEffectEntity = new LayerEffectEntity
|
||||
{
|
||||
Id = layerEffect.EntityId,
|
||||
ProviderId = layerEffect.Descriptor.PlaceholderFor ?? layerEffect.ProviderId,
|
||||
ProviderId = layerEffect.Descriptor?.PlaceholderFor ?? layerEffect.ProviderId,
|
||||
EffectType = layerEffect.GetEffectTypeName(),
|
||||
Name = layerEffect.Name,
|
||||
Enabled = layerEffect.Enabled,
|
||||
@@ -76,7 +78,7 @@ namespace Artemis.Core
|
||||
Order = layerEffect.Order
|
||||
};
|
||||
RenderElementEntity.LayerEffects.Add(layerEffectEntity);
|
||||
layerEffect.BaseProperties.ApplyToEntity();
|
||||
layerEffect.BaseProperties?.ApplyToEntity();
|
||||
}
|
||||
|
||||
// Conditions
|
||||
@@ -290,8 +292,7 @@ namespace Artemis.Core
|
||||
private void LayerEffectStoreOnLayerEffectRemoved(object? sender, LayerEffectStoreEvent e)
|
||||
{
|
||||
// If effects provided by the plugin are on the element, replace them with placeholders
|
||||
List<BaseLayerEffect> pluginEffects = LayerEffectsList.Where(ef => ef.Descriptor.Provider != null &&
|
||||
ef.ProviderId == e.Registration.PluginFeature.Id).ToList();
|
||||
List<BaseLayerEffect> pluginEffects = LayerEffectsList.Where(ef => ef.ProviderId == e.Registration.PluginFeature.Id).ToList();
|
||||
foreach (BaseLayerEffect pluginEffect in pluginEffects)
|
||||
{
|
||||
LayerEffectEntity entity = RenderElementEntity.LayerEffects.First(en => en.Id == pluginEffect.EntityId);
|
||||
@@ -323,13 +324,13 @@ namespace Artemis.Core
|
||||
protected set => SetAndNotify(ref _displayConditionMet, value);
|
||||
}
|
||||
|
||||
private DataModelConditionGroup _displayCondition;
|
||||
private DataModelConditionGroup? _displayCondition;
|
||||
private bool _displayConditionMet;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the root display condition group
|
||||
/// </summary>
|
||||
public DataModelConditionGroup DisplayCondition
|
||||
public DataModelConditionGroup? DisplayCondition
|
||||
{
|
||||
get => _displayCondition;
|
||||
set => SetAndNotify(ref _displayCondition, value);
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Artemis.Core
|
||||
if (IsOpen)
|
||||
throw new ArtemisCoreException("Cannot open render context because it is already open");
|
||||
|
||||
if (!_valid)
|
||||
if (!_valid || Canvas == null)
|
||||
{
|
||||
SKRect pathBounds = path.Bounds;
|
||||
int width = (int) pathBounds.Width;
|
||||
@@ -59,7 +59,7 @@ namespace Artemis.Core
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("Renderer");
|
||||
|
||||
Canvas.Restore();
|
||||
Canvas?.Restore();
|
||||
Paint?.Dispose();
|
||||
Paint = null;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Artemis.Core
|
||||
public class ArtemisDevice : CorePropertyChanged
|
||||
{
|
||||
private ReadOnlyCollection<ArtemisLed> _leds;
|
||||
private SKPath _renderPath;
|
||||
private SKPath? _renderPath;
|
||||
private SKRect _renderRectangle;
|
||||
|
||||
internal ArtemisDevice(IRGBDevice rgbDevice, DeviceProvider deviceProvider, ArtemisSurface surface)
|
||||
@@ -23,7 +23,7 @@ namespace Artemis.Core
|
||||
DeviceProvider = deviceProvider;
|
||||
Surface = surface;
|
||||
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;
|
||||
Scale = 1;
|
||||
@@ -39,7 +39,7 @@ namespace Artemis.Core
|
||||
DeviceProvider = deviceProvider;
|
||||
Surface = surface;
|
||||
DeviceEntity = deviceEntity;
|
||||
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||
_leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -54,7 +54,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets the path surrounding the device, sized to match the render scale
|
||||
/// </summary>
|
||||
public SKPath RenderPath
|
||||
public SKPath? RenderPath
|
||||
{
|
||||
get => _renderPath;
|
||||
private set => SetAndNotify(ref _renderPath, value);
|
||||
|
||||
Reference in new issue
Block a user