Surface - Removed the ArtemisSurface and reworked device loading

This commit is contained in:
Robert committed 2021-02-16 21:46:08 +01:00
1 parent 7ccc9c54fb
commit 056b2bface
50 files changed
+1292 -1506

No files matched your search

+2 -2
View File
@@ -567,7 +567,7 @@ namespace Artemis.Core
CalculateRenderProperties();
}
internal void PopulateLeds(ArtemisSurface surface)
internal void PopulateLeds(IEnumerable<ArtemisDevice> devices)
{
if (Disposed)
throw new ObjectDisposedException("Layer");
@@ -575,7 +575,7 @@ namespace Artemis.Core
List<ArtemisLed> leds = new();
// Get the surface LEDs for this layer
List<ArtemisLed> availableLeds = surface.Devices.Where(d => d.IsEnabled).SelectMany(d => d.Leds).ToList();
List<ArtemisLed> availableLeds = devices.SelectMany(d => d.Leds).ToList();
foreach (LedEntity ledEntity in LayerEntity.Leds)
{
ArtemisLed? match = availableLeds.FirstOrDefault(a => a.Device.RgbDevice.GetDeviceIdentifier() == ledEntity.DeviceIdentifier &&
+5 -5
View File
@@ -124,14 +124,14 @@ namespace Artemis.Core
/// <summary>
/// Populates all the LEDs on the elements in this profile
/// </summary>
/// <param name="surface">The currently active surface that contains the LEDs</param>
public void PopulateLeds(ArtemisSurface surface)
/// <param name="devices">The devices to use while populating LEDs</param>
public void PopulateLeds(IEnumerable<ArtemisDevice> devices)
{
if (Disposed)
throw new ObjectDisposedException("Profile");
foreach (Layer layer in GetAllLayers())
layer.PopulateLeds(surface);
layer.PopulateLeds(devices);
}
/// <inheritdoc />
@@ -197,7 +197,7 @@ namespace Artemis.Core
ProfileEntity.Layers.AddRange(GetAllLayers().Select(f => f.LayerEntity));
}
internal void Activate(ArtemisSurface surface)
internal void Activate(IEnumerable<ArtemisDevice> devices)
{
lock (_lock)
{
@@ -206,7 +206,7 @@ namespace Artemis.Core
if (IsActivated)
return;
PopulateLeds(surface);
PopulateLeds(devices);
OnActivated();
IsActivated = true;
}
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Artemis.Core.DeviceProviders;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Surface;
using RGB.NET.Core;
using RGB.NET.Layout;
@@ -18,12 +19,11 @@ namespace Artemis.Core
private SKPath? _path;
private SKRect _rectangle;
internal ArtemisDevice(IRGBDevice rgbDevice, DeviceProvider deviceProvider, ArtemisSurface surface)
internal ArtemisDevice(IRGBDevice rgbDevice, DeviceProvider deviceProvider)
{
DeviceEntity = new DeviceEntity();
RgbDevice = rgbDevice;
DeviceProvider = deviceProvider;
Surface = surface;
Rotation = 0;
Scale = 1;
@@ -43,12 +43,11 @@ namespace Artemis.Core
CalculateRenderProperties();
}
internal ArtemisDevice(IRGBDevice rgbDevice, DeviceProvider deviceProvider, ArtemisSurface surface, DeviceEntity deviceEntity)
internal ArtemisDevice(IRGBDevice rgbDevice, DeviceProvider deviceProvider, DeviceEntity deviceEntity)
{
DeviceEntity = deviceEntity;
RgbDevice = rgbDevice;
DeviceProvider = deviceProvider;
Surface = surface;
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
foreach (DeviceInputIdentifierEntity identifierEntity in DeviceEntity.InputIdentifiers)
@@ -88,11 +87,6 @@ namespace Artemis.Core
/// </summary>
public DeviceProvider DeviceProvider { get; }
/// <summary>
/// Gets the surface containing this device
/// </summary>
public ArtemisSurface Surface { get; }
/// <summary>
/// Gets a read only collection containing the LEDs of this device
/// </summary>
@@ -214,12 +208,13 @@ namespace Artemis.Core
}
/// <summary>
/// Gets or sets a boolean indicating whether this devices is enabled or not
/// Gets a boolean indicating whether this devices is enabled or not
/// <para>Note: To enable/disable a device use the methods provided by <see cref="IRgbService" /></para>
/// </summary>
public bool IsEnabled
{
get => DeviceEntity.IsEnabled;
set
internal set
{
DeviceEntity.IsEnabled = value;
OnPropertyChanged(nameof(IsEnabled));
@@ -305,37 +300,6 @@ namespace Artemis.Core
return fileName;
}
/// <summary>
/// Loads the best layout for this device, preferring user layouts and falling back to default layouts
/// </summary>
public void LoadBestLayout()
{
// Look for a user layout
// ... here
// Try loading a device provider layout, if that comes back valid we use that
ArtemisLayout deviceProviderLayout = DeviceProvider.LoadLayout(this);
// Finally fall back to a default layout
// .. do it!
ApplyLayout(deviceProviderLayout);
}
private void ApplyKeyboardLayout()
{
if (!(RgbDevice is IKeyboard keyboard))
return;
// If supported, detect the device layout so that we can load the correct one
if (DeviceProvider.CanDetectLogicalLayout )
LogicalLayout = DeviceProvider.GetLogicalLayout(keyboard);
if (DeviceProvider.CanDetectPhysicalLayout)
PhysicalLayout = (KeyboardLayoutType) keyboard.DeviceInfo.Layout;
}
/// <summary>
/// Applies the provided layout to the device
/// </summary>
@@ -350,12 +314,13 @@ namespace Artemis.Core
Layout = layout;
Layout.ApplyDevice(this);
OnDeviceUpdated();
}
internal void ApplyToEntity()
{
// Other properties are computed
DeviceEntity.DeviceIdentifier = RgbDevice.GetDeviceIdentifier();
DeviceEntity.Id = RgbDevice.GetDeviceIdentifier();
DeviceEntity.InputIdentifiers.Clear();
foreach (ArtemisDeviceInputIdentifier identifier in InputIdentifiers)
@@ -400,6 +365,18 @@ namespace Artemis.Core
Path = path;
}
private void ApplyKeyboardLayout()
{
if (!(RgbDevice is IKeyboard keyboard))
return;
// If supported, detect the device layout so that we can load the correct one
if (DeviceProvider.CanDetectLogicalLayout)
LogicalLayout = DeviceProvider.GetLogicalLayout(keyboard);
if (DeviceProvider.CanDetectPhysicalLayout)
PhysicalLayout = (KeyboardLayoutType) keyboard.DeviceInfo.Layout;
}
#region Events
/// <summary>
@@ -1,134 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Artemis.Storage.Entities.Surface;
using RGB.NET.Core;
namespace Artemis.Core
{
/// <summary>
/// Represents a surface of a specific scale, containing all the available <see cref="ArtemisDevice" />s
/// </summary>
public class ArtemisSurface : CorePropertyChanged
{
private List<ArtemisDevice> _devices = new();
private ReadOnlyDictionary<Led, ArtemisLed> _ledMap = new(new Dictionary<Led, ArtemisLed>());
private bool _isActive;
private string _name;
internal ArtemisSurface(RGBSurface rgbSurface, string name)
{
SurfaceEntity = new SurfaceEntity {DeviceEntities = new List<DeviceEntity>()};
EntityId = Guid.NewGuid();
RgbSurface = rgbSurface;
_name = name;
_isActive = false;
ApplyToEntity();
}
internal ArtemisSurface(RGBSurface rgbSurface, SurfaceEntity surfaceEntity)
{
SurfaceEntity = surfaceEntity;
EntityId = surfaceEntity.Id;
RgbSurface = rgbSurface;
_name = surfaceEntity.Name;
_isActive = surfaceEntity.IsActive;
}
/// <summary>
/// Gets the RGB.NET surface backing this Artemis surface
/// </summary>
public RGBSurface RgbSurface { get; }
/// <summary>
/// Gets the name of the surface
/// </summary>
public string Name
{
get => _name;
set => SetAndNotify(ref _name, value);
}
/// <summary>
/// Gets a boolean indicating whether this surface is the currently active surface
/// </summary>
public bool IsActive
{
get => _isActive;
internal set => SetAndNotify(ref _isActive, value);
}
/// <summary>
/// Gets a list of devices this surface contains
/// </summary>
public List<ArtemisDevice> Devices
{
get => _devices;
internal set => SetAndNotify(ref _devices, value);
}
/// <summary>
/// Gets a dictionary containing all <see cref="ArtemisLed" />s on the surface with their corresponding RGB.NET
/// <see cref="Led" /> as key
/// </summary>
public ReadOnlyDictionary<Led, ArtemisLed> LedMap
{
get => _ledMap;
private set => SetAndNotify(ref _ledMap, value);
}
internal SurfaceEntity SurfaceEntity { get; set; }
internal Guid EntityId { get; set; }
/// <summary>
/// Attempts to retrieve the <see cref="ArtemisLed" /> that corresponds the provided RGB.NET <see cref="Led" />
/// </summary>
/// <param name="led">The RGB.NET <see cref="Led" /> to find the corresponding <see cref="ArtemisLed" /> for </param>
/// <returns>If found, the corresponding <see cref="ArtemisLed" />; otherwise <see langword="null" />.</returns>
public ArtemisLed? GetArtemisLed(Led led)
{
LedMap.TryGetValue(led, out ArtemisLed? artemisLed);
return artemisLed;
}
internal void UpdateLedMap()
{
LedMap = new ReadOnlyDictionary<Led, ArtemisLed>(
_devices.Where(d => d.IsEnabled).SelectMany(d => d.Leds.Select(al => new KeyValuePair<Led, ArtemisLed>(al.RgbLed, al))).ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
);
}
internal void ApplyToEntity()
{
SurfaceEntity.Id = EntityId;
SurfaceEntity.Name = Name;
SurfaceEntity.IsActive = IsActive;
// Add missing device entities, don't remove old ones in case they come back later
foreach (DeviceEntity deviceEntity in Devices.Select(d => d.DeviceEntity).ToList())
if (!SurfaceEntity.DeviceEntities.Contains(deviceEntity))
SurfaceEntity.DeviceEntities.Add(deviceEntity);
}
#region Events
/// <summary>
/// Occurs when the scale of the surface is changed
/// </summary>
public event EventHandler<EventArgs>? ScaleChanged;
/// <summary>
/// Invokes the <see cref="ScaleChanged" /> event
/// </summary>
protected virtual void OnScaleChanged()
{
ScaleChanged?.Invoke(this, EventArgs.Empty);
}
#endregion
}
}
@@ -20,6 +20,53 @@ namespace Artemis.Core
FilePath = filePath;
Leds = new List<ArtemisLedLayout>();
LoadLayout();
}
/// <summary>
/// Gets the file path the layout was (attempted to be) loaded from
/// </summary>
public string FilePath { get; }
/// <summary>
/// Gets the RGB.NET device layout
/// </summary>
public DeviceLayout RgbLayout { get; private set; }
/// <summary>
/// Gets the device this layout is applied to
/// </summary>
public ArtemisDevice? Device { get; private set; }
/// <summary>
/// Gets a boolean indicating whether a valid layout was loaded
/// </summary>
public bool IsValid { get; private set; }
/// <summary>
/// Gets the image of the device
/// </summary>
public Uri? Image { get; private set; }
public List<ArtemisLedLayout> Leds { get; }
internal LayoutCustomDeviceData LayoutCustomDeviceData { get; set; }
public void ReloadFromDisk()
{
Leds.Clear();
LoadLayout();
}
internal void ApplyDevice(ArtemisDevice artemisDevice)
{
Device = artemisDevice;
foreach (ArtemisLedLayout artemisLedLayout in Leds)
artemisLedLayout.ApplyDevice(Device);
}
private void LoadLayout()
{
DeviceLayout? deviceLayout = DeviceLayout.Load(FilePath, typeof(LayoutCustomDeviceData), typeof(LayoutCustomLedData));
if (deviceLayout != null)
{
@@ -39,47 +86,13 @@ namespace Artemis.Core
ApplyCustomDeviceData();
}
/// <summary>
/// Gets the file path the layout was (attempted to be) loaded from
/// </summary>
public string FilePath { get; }
/// <summary>
/// Gets the RGB.NET device layout
/// </summary>
public DeviceLayout RgbLayout { get; }
/// <summary>
/// Gets the device this layout is applied to
/// </summary>
public ArtemisDevice? Device { get; private set; }
/// <summary>
/// Gets a boolean indicating whether a valid layout was loaded
/// </summary>
public bool IsValid { get; }
/// <summary>
/// Gets the image of the device
/// </summary>
public Uri? Image { get; private set; }
public List<ArtemisLedLayout> Leds { get; }
internal LayoutCustomDeviceData LayoutCustomDeviceData { get; set; }
internal void ApplyDevice(ArtemisDevice artemisDevice)
{
Device = artemisDevice;
foreach (ArtemisLedLayout artemisLedLayout in Leds)
artemisLedLayout.ApplyDevice(Device);
}
private void ApplyCustomDeviceData()
{
Uri layoutDirectory = new(Path.GetDirectoryName(FilePath)! + "\\", UriKind.Absolute);
if (LayoutCustomDeviceData.DeviceImage != null)
Image = new Uri(layoutDirectory, new Uri(LayoutCustomDeviceData.DeviceImage, UriKind.Relative));
else
Image = null;
}
}
}