diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index b9e5de52a..2d5f2b177 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -26,10 +26,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - @@ -37,7 +33,6 @@ - diff --git a/src/Artemis.Core/FodyWeavers.xml b/src/Artemis.Core/FodyWeavers.xml deleted file mode 100644 index ef627f96d..000000000 --- a/src/Artemis.Core/FodyWeavers.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/Artemis.Core/FodyWeavers.xsd b/src/Artemis.Core/FodyWeavers.xsd deleted file mode 100644 index 221aeb8a5..000000000 --- a/src/Artemis.Core/FodyWeavers.xsd +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - Used to control if the On_PropertyName_Changed feature is enabled. - - - - - Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form. - - - - - Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project. - - - - - Used to control if equality checks should use the Equals method resolved from the base class. - - - - - Used to control if equality checks should use the static Equals method resolved from the base class. - - - - - Used to turn off build warnings from this weaver. - - - - - Used to turn off build warnings about mismatched On_PropertyName_Changed methods. - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs index 1ccb64cbc..984414d13 100644 --- a/src/Artemis.Core/Models/Profile/Folder.cs +++ b/src/Artemis.Core/Models/Profile/Folder.cs @@ -45,15 +45,15 @@ namespace Artemis.Core.Models.Profile // Load child folders foreach (var childFolder in Profile.ProfileEntity.Folders.Where(f => f.ParentId == EntityId)) - _children.Add(new Folder(profile, this, childFolder)); + ChildrenList.Add(new Folder(profile, this, childFolder)); // Load child layers foreach (var childLayer in Profile.ProfileEntity.Layers.Where(f => f.ParentId == EntityId)) - _children.Add(new Layer(profile, this, childLayer)); + ChildrenList.Add(new Layer(profile, this, childLayer)); // Ensure order integrity, should be unnecessary but no one is perfect specially me - _children = _children.OrderBy(c => c.Order).ToList(); - for (var index = 0; index < _children.Count; index++) - _children[index].Order = index + 1; + ChildrenList = ChildrenList.OrderBy(c => c.Order).ToList(); + for (var index = 0; index < ChildrenList.Count; index++) + ChildrenList[index].Order = index + 1; } internal FolderEntity FolderEntity { get; set; } diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index ca73d9123..917562ae5 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using Artemis.Core.Annotations; using Artemis.Core.Extensions; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Models.Profile.LayerProperties.Attributes; @@ -23,9 +22,12 @@ namespace Artemis.Core.Models.Profile /// public sealed class Layer : EffectProfileElement { + private LayerGeneralProperties _general; + private SKBitmap _layerBitmap; + private BaseLayerBrush _layerBrush; private LayerShape _layerShape; private List _leds; - private SKBitmap _layerBitmap; + private LayerTransformProperties _transform; internal Layer(Profile profile, ProfileElement parent, string name) { @@ -84,22 +86,34 @@ namespace Artemis.Core.Models.Profile get => _layerShape; set { - _layerShape = value; + SetAndNotify(ref _layerShape, value); if (Path != null) CalculateRenderProperties(); } } [PropertyGroupDescription(Name = "General", Description = "A collection of general properties")] - public LayerGeneralProperties General { get; set; } + public LayerGeneralProperties General + { + get => _general; + set => SetAndNotify(ref _general, value); + } [PropertyGroupDescription(Name = "Transform", Description = "A collection of transformation properties")] - public LayerTransformProperties Transform { get; set; } + public LayerTransformProperties Transform + { + get => _transform; + set => SetAndNotify(ref _transform, value); + } /// /// The brush that will fill the . /// - public BaseLayerBrush LayerBrush { get; internal set; } + public BaseLayerBrush LayerBrush + { + get => _layerBrush; + internal set => SetAndNotify(ref _layerBrush, value); + } public override string ToString() { @@ -239,11 +253,11 @@ namespace Artemis.Core.Models.Profile return; if (_layerBitmap == null) - _layerBitmap = new SKBitmap(new SKImageInfo((int)Path.Bounds.Width, (int)Path.Bounds.Height)); - else if (_layerBitmap.Info.Width != (int)Path.Bounds.Width || _layerBitmap.Info.Height != (int)Path.Bounds.Height) + _layerBitmap = new SKBitmap(new SKImageInfo((int) Path.Bounds.Width, (int) Path.Bounds.Height)); + else if (_layerBitmap.Info.Width != (int) Path.Bounds.Width || _layerBitmap.Info.Height != (int) Path.Bounds.Height) { _layerBitmap.Dispose(); - _layerBitmap = new SKBitmap(new SKImageInfo((int)Path.Bounds.Width, (int)Path.Bounds.Height)); + _layerBitmap = new SKBitmap(new SKImageInfo((int) Path.Bounds.Width, (int) Path.Bounds.Height)); } using var layerPath = new SKPath(Path); @@ -255,9 +269,9 @@ namespace Artemis.Core.Models.Profile Color = new SKColor(0, 0, 0, (byte) (Transform.Opacity.CurrentValue * 2.55f)) }; layerCanvas.Clear(); - + layerPath.Transform(SKMatrix.MakeTranslation(layerPath.Bounds.Left * -1, layerPath.Bounds.Top * -1)); - + foreach (var baseLayerEffect in LayerEffects.Where(e => e.Enabled)) baseLayerEffect.PreProcess(layerCanvas, _layerBitmap.Info, layerPath, layerPaint); @@ -278,7 +292,6 @@ namespace Artemis.Core.Models.Profile targetLocation = Path.Bounds.Location - parentFolder.Path.Bounds.Location; canvas.DrawBitmap(_layerBitmap, targetLocation, layerPaint); - } private void SimpleRender(SKCanvas canvas, SKImageInfo canvasInfo, SKPaint paint, SKPath layerPath) diff --git a/src/Artemis.Core/Models/Profile/Profile.cs b/src/Artemis.Core/Models/Profile/Profile.cs index 560be8fd8..df31ed9e2 100644 --- a/src/Artemis.Core/Models/Profile/Profile.cs +++ b/src/Artemis.Core/Models/Profile/Profile.cs @@ -11,6 +11,8 @@ namespace Artemis.Core.Models.Profile { public sealed class Profile : ProfileElement { + private bool _isActivated; + internal Profile(PluginInfo pluginInfo, string name) { ProfileEntity = new ProfileEntity(); @@ -38,7 +40,12 @@ namespace Artemis.Core.Models.Profile } public PluginInfo PluginInfo { get; } - public bool IsActivated { get; private set; } + + public bool IsActivated + { + get => _isActivated; + private set => SetAndNotify(ref _isActivated, value); + } internal ProfileEntity ProfileEntity { get; set; } @@ -78,14 +85,14 @@ namespace Artemis.Core.Models.Profile { Name = ProfileEntity.Name; - lock (_children) + lock (ChildrenList) { foreach (var folder in GetAllFolders()) folder.Deactivate(); foreach (var layer in GetAllLayers()) layer.Deactivate(); - _children.Clear(); + ChildrenList.Clear(); // Populate the profile starting at the root, the rest is populated recursively var rootFolder = ProfileEntity.Folders.FirstOrDefault(f => f.ParentId == EntityId); if (rootFolder == null) diff --git a/src/Artemis.Core/Models/Profile/ProfileElement.cs b/src/Artemis.Core/Models/Profile/ProfileElement.cs index 231d5bec8..fcdf4bd97 100644 --- a/src/Artemis.Core/Models/Profile/ProfileElement.cs +++ b/src/Artemis.Core/Models/Profile/ProfileElement.cs @@ -9,36 +9,68 @@ namespace Artemis.Core.Models.Profile { public abstract class ProfileElement : PropertyChangedBase { - protected List _children; + private bool _enabled; + private Guid _entityId; + private string _name; + private int _order; + private ProfileElement _parent; + private Profile _profile; + protected List ChildrenList; protected ProfileElement() { - _children = new List(); + ChildrenList = new List(); } - public Guid EntityId { get; internal set; } - public Profile Profile { get; internal set; } - public ProfileElement Parent { get; internal set; } + public Guid EntityId + { + get => _entityId; + internal set => SetAndNotify(ref _entityId, value); + } + + public Profile Profile + { + get => _profile; + internal set => SetAndNotify(ref _profile, value); + } + + public ProfileElement Parent + { + get => _parent; + internal set => SetAndNotify(ref _parent, value); + } /// /// The element's children /// - public ReadOnlyCollection Children => _children.AsReadOnly(); + public ReadOnlyCollection Children => ChildrenList.AsReadOnly(); /// /// The order in which this element appears in the update loop and editor /// - public int Order { get; internal set; } + public int Order + { + get => _order; + internal set => SetAndNotify(ref _order, value); + } /// /// The name which appears in the editor /// - public string Name { get; set; } + public string Name + { + get => _name; + set => SetAndNotify(ref _name, value); + } /// /// Gets or sets the enabled state, if not enabled the element is skipped in render and update /// - public bool Enabled { get; set; } + public bool Enabled + { + get => _enabled; + set => SetAndNotify(ref _enabled, value); + } /// /// Updates the element @@ -86,29 +118,29 @@ namespace Artemis.Core.Models.Profile /// The order where to place the child (1-based), defaults to the end of the collection public virtual void AddChild(ProfileElement child, int? order = null) { - lock (_children) + lock (ChildrenList) { // Add to the end of the list if (order == null) { - _children.Add(child); - child.Order = _children.Count; + ChildrenList.Add(child); + child.Order = ChildrenList.Count; } // Shift everything after the given order else { - foreach (var profileElement in _children.Where(c => c.Order >= order).ToList()) + foreach (var profileElement in ChildrenList.Where(c => c.Order >= order).ToList()) profileElement.Order++; int targetIndex; if (order == 0) targetIndex = 0; - else if (order > _children.Count) - targetIndex = _children.Count; + else if (order > ChildrenList.Count) + targetIndex = ChildrenList.Count; else - targetIndex = _children.FindIndex(c => c.Order == order + 1); + targetIndex = ChildrenList.FindIndex(c => c.Order == order + 1); - _children.Insert(targetIndex, child); + ChildrenList.Insert(targetIndex, child); child.Order = order.Value; } @@ -122,12 +154,12 @@ namespace Artemis.Core.Models.Profile /// The profile element to remove public virtual void RemoveChild(ProfileElement child) { - lock (_children) + lock (ChildrenList) { - _children.Remove(child); + ChildrenList.Remove(child); // Shift everything after the given order - foreach (var profileElement in _children.Where(c => c.Order > child.Order).ToList()) + foreach (var profileElement in ChildrenList.Where(c => c.Order > child.Order).ToList()) profileElement.Order--; child.Parent = null; diff --git a/src/Artemis.Core/Models/Profile/PropertiesProfileElement.cs b/src/Artemis.Core/Models/Profile/PropertiesProfileElement.cs index ae1371424..184e2d4c7 100644 --- a/src/Artemis.Core/Models/Profile/PropertiesProfileElement.cs +++ b/src/Artemis.Core/Models/Profile/PropertiesProfileElement.cs @@ -6,9 +6,8 @@ namespace Artemis.Core.Models.Profile { public abstract class PropertiesProfileElement : ProfileElement { - internal abstract PropertiesEntity PropertiesEntity { get; } - private SKPath _path; + internal abstract PropertiesEntity PropertiesEntity { get; } /// /// Gets the path containing all the LEDs this entity is applied to, any rendering outside the entity Path is @@ -19,7 +18,7 @@ namespace Artemis.Core.Models.Profile get => _path; protected set { - _path = value; + SetAndNotify(ref _path, value); // I can't really be sure about the performance impact of calling Bounds often but // SkiaSharp calls SkiaApi.sk_path_get_bounds (Handle, &rect); which sounds expensive Bounds = value?.Bounds ?? SKRect.Empty; @@ -29,12 +28,17 @@ namespace Artemis.Core.Models.Profile /// /// The bounds of this entity /// - public SKRect Bounds { get; private set; } + public SKRect Bounds + { + get => _bounds; + private set => SetAndNotify(ref _bounds, value); + } #region Property group expansion protected List _expandedPropertyGroups; - + private SKRect _bounds; + public bool IsPropertyGroupExpanded(LayerPropertyGroup layerPropertyGroup) { return _expandedPropertyGroups.Contains(layerPropertyGroup.Path); @@ -49,6 +53,5 @@ namespace Artemis.Core.Models.Profile } #endregion - } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs index 9e46be114..62c309168 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs @@ -12,6 +12,10 @@ namespace Artemis.Core.Models.Surface { public class ArtemisDevice : PropertyChangedBase { + private SKRect _renderRectangle; + private SKPath _renderPath; + private ReadOnlyCollection _leds; + internal ArtemisDevice(IRGBDevice rgbDevice, Plugin plugin, ArtemisSurface surface) { RgbDevice = rgbDevice; @@ -37,14 +41,28 @@ namespace Artemis.Core.Models.Surface Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly(); } - public SKRect RenderRectangle { get; private set; } - public SKPath RenderPath { get; private set; } + public SKRect RenderRectangle + { + get => _renderRectangle; + private set => SetAndNotify(ref _renderRectangle, value); + } + + public SKPath RenderPath + { + get => _renderPath; + private set => SetAndNotify(ref _renderPath, value); + } public IRGBDevice RgbDevice { get; } public Plugin Plugin { get; } public ArtemisSurface Surface { get; } public DeviceEntity DeviceEntity { get; } - public ReadOnlyCollection Leds { get; set; } + + public ReadOnlyCollection Leds + { + get => _leds; + set => SetAndNotify(ref _leds, value); + } public double X { diff --git a/src/Artemis.Core/Models/Surface/ArtemisLed.cs b/src/Artemis.Core/Models/Surface/ArtemisLed.cs index 3b08c7ddd..cf2b89508 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisLed.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisLed.cs @@ -7,6 +7,9 @@ namespace Artemis.Core.Models.Surface { public class ArtemisLed : PropertyChangedBase { + private SKRect _renderRectangle; + private SKRect _absoluteRenderRectangle; + public ArtemisLed(Led led, ArtemisDevice device) { RgbLed = led; @@ -18,9 +21,18 @@ namespace Artemis.Core.Models.Surface public Led RgbLed { get; } public ArtemisDevice Device { get; } - public SKRect RenderRectangle { get; private set; } - public SKRect AbsoluteRenderRectangle { get; private set; } - + public SKRect RenderRectangle + { + get => _renderRectangle; + private set => SetAndNotify(ref _renderRectangle, value); + } + + public SKRect AbsoluteRenderRectangle + { + get => _absoluteRenderRectangle; + private set => SetAndNotify(ref _absoluteRenderRectangle, value); + } + public void CalculateRenderRectangle() { RenderRectangle = SKRect.Create( diff --git a/src/Artemis.Core/Models/Surface/ArtemisSurface.cs b/src/Artemis.Core/Models/Surface/ArtemisSurface.cs index 88aaa50af..2e83611a3 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisSurface.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisSurface.cs @@ -9,6 +9,11 @@ namespace Artemis.Core.Models.Surface { public class ArtemisSurface : PropertyChangedBase { + private double _scale; + private string _name; + private bool _isActive; + private List _devices; + internal ArtemisSurface(RGBSurface rgbSurface, string name, double scale) { SurfaceEntity = new SurfaceEntity {DeviceEntities = new List()}; @@ -40,10 +45,30 @@ namespace Artemis.Core.Models.Surface } public RGBSurface RgbSurface { get; } - public double Scale { get; private set; } - public string Name { get; set; } - public bool IsActive { get; internal set; } - public List Devices { get; internal set; } + + public double Scale + { + get => _scale; + private set => SetAndNotify(ref _scale, value); + } + + public string Name + { + get => _name; + set => SetAndNotify(ref _name, value); + } + + public bool IsActive + { + get => _isActive; + internal set => SetAndNotify(ref _isActive, value); + } + + public List Devices + { + get => _devices; + internal set => SetAndNotify(ref _devices, value); + } internal SurfaceEntity SurfaceEntity { get; set; } internal Guid EntityId { get; set; } diff --git a/src/Artemis.Core/Plugins/LayerBrush/Abstract/BaseLayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrush/Abstract/BaseLayerBrush.cs index 84113e5f1..d94355474 100644 --- a/src/Artemis.Core/Plugins/LayerBrush/Abstract/BaseLayerBrush.cs +++ b/src/Artemis.Core/Plugins/LayerBrush/Abstract/BaseLayerBrush.cs @@ -13,28 +13,43 @@ namespace Artemis.Core.Plugins.LayerBrush.Abstract /// public abstract class BaseLayerBrush : PropertyChangedBase, IDisposable { + private LayerBrushType _brushType; + private LayerBrushDescriptor _descriptor; + private Layer _layer; private bool _supportsTransformation = true; /// /// Gets the layer this brush is applied to /// - public Layer Layer { get; internal set; } + public Layer Layer + { + get => _layer; + internal set => SetAndNotify(ref _layer, value); + } /// /// Gets the descriptor of this brush /// - public LayerBrushDescriptor Descriptor { get; internal set; } + public LayerBrushDescriptor Descriptor + { + get => _descriptor; + internal set => SetAndNotify(ref _descriptor, value); + } + + /// + /// Gets the type of layer brush + /// + public LayerBrushType BrushType + { + get => _brushType; + internal set => SetAndNotify(ref _brushType, value); + } /// /// Gets the plugin info that defined this brush /// public PluginInfo PluginInfo => Descriptor.LayerBrushProvider.PluginInfo; - /// - /// Gets the type of layer brush - /// - public LayerBrushType BrushType { get; internal set; } - /// /// Gets a reference to the layer property group without knowing it's type /// diff --git a/src/Artemis.Core/Plugins/LayerEffect/Abstract/BaseLayerEffect.cs b/src/Artemis.Core/Plugins/LayerEffect/Abstract/BaseLayerEffect.cs index e33d799f6..b7e8cad5a 100644 --- a/src/Artemis.Core/Plugins/LayerEffect/Abstract/BaseLayerEffect.cs +++ b/src/Artemis.Core/Plugins/LayerEffect/Abstract/BaseLayerEffect.cs @@ -12,41 +12,77 @@ namespace Artemis.Core.Plugins.LayerEffect.Abstract /// public abstract class BaseLayerEffect : PropertyChangedBase, IDisposable { + private Guid _entityId; + private EffectProfileElement _profileElement; + private string _name; + private bool _enabled; + private bool _hasBeenRenamed; + private int _order; + private LayerEffectDescriptor _descriptor; + /// /// Gets the unique ID of this effect /// - public Guid EntityId { get; internal set; } + public Guid EntityId + { + get => _entityId; + internal set => SetAndNotify(ref _entityId, value); + } /// /// Gets the profile element (such as layer or folder) this effect is applied to /// - public EffectProfileElement ProfileElement { get; internal set; } + public EffectProfileElement ProfileElement + { + get => _profileElement; + internal set => SetAndNotify(ref _profileElement, value); + } /// /// The name which appears in the editor /// - public string Name { get; set; } + public string Name + { + get => _name; + set => SetAndNotify(ref _name, value); + } /// /// Gets or sets the enabled state, if not enabled the effect is skipped in render and update /// - public bool Enabled { get; set; } + public bool Enabled + { + get => _enabled; + set => SetAndNotify(ref _enabled, value); + } /// /// Gets or sets whether the effect has been renamed by the user, if true consider refraining from changing the name /// programatically /// - public bool HasBeenRenamed { get; set; } + public bool HasBeenRenamed + { + get => _hasBeenRenamed; + set => SetAndNotify(ref _hasBeenRenamed, value); + } /// /// Gets the order in which this effect appears in the update loop and editor /// - public int Order { get; set; } + public int Order + { + get => _order; + set => SetAndNotify(ref _order, value); + } /// /// Gets the descriptor of this effect /// - public LayerEffectDescriptor Descriptor { get; internal set; } + public LayerEffectDescriptor Descriptor + { + get => _descriptor; + internal set => SetAndNotify(ref _descriptor, value); + } /// /// Gets the plugin info that defined this effect diff --git a/src/Artemis.Core/Services/RgbService.cs b/src/Artemis.Core/Services/RgbService.cs index 15a296d8b..3c8505d0e 100644 --- a/src/Artemis.Core/Services/RgbService.cs +++ b/src/Artemis.Core/Services/RgbService.cs @@ -67,9 +67,11 @@ namespace Artemis.Core.Services _logger.Warning("Device provider {deviceProvider} has no devices", deviceProvider.GetType().Name); return; } - + foreach (var surfaceDevice in deviceProvider.Devices) { + _logger.Debug("Device provider {deviceProvider} added {deviceName}", + deviceProvider.GetType().Name, surfaceDevice.DeviceInfo?.DeviceName); if (!_loadedDevices.Contains(surfaceDevice)) { _loadedDevices.Add(surfaceDevice);