Skip to content

Commit

Permalink
Made custom data in layouts typed
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertBeekman committed Oct 31, 2023
1 parent d454f94 commit ce860d5
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 67 deletions.
2 changes: 1 addition & 1 deletion RGB.NET.Devices.Debug/DebugRGBDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public sealed class DebugRGBDevice : AbstractRGBDevice<DebugRGBDeviceInfo>, IUnk
/// Internal constructor of <see cref="DebugRGBDeviceInfo"/>.
/// </summary>
internal DebugRGBDevice(IDeviceLayout layout, Action<IEnumerable<Led>>? updateLedsAction = null)
: base(new DebugRGBDeviceInfo(layout.Type, layout.Vendor ?? "RGB.NET", layout.Model ?? "Debug", layout.CustomData), new DebugDeviceUpdateQueue())
: base(new DebugRGBDeviceInfo(layout.Type, layout.Vendor ?? "RGB.NET", layout.Model ?? "Debug", layout.UntypedCustomData), new DebugDeviceUpdateQueue())
{
this.Layout = layout;
this._updateLedsAction = updateLedsAction;
Expand Down
77 changes: 32 additions & 45 deletions RGB.NET.Layout/DeviceLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,23 @@ namespace RGB.NET.Layout;
/// </summary>
[Serializable]
[XmlRoot("Device")]
public class DeviceLayout : IDeviceLayout
public class DeviceLayout : DeviceLayout<object, object>
{ }

/// <summary>
/// Represents the serializable layout of a <see cref="IRGBDevice"/>.
/// </summary>
[Serializable]
[XmlRoot("Device")]
public class DeviceLayout<TCustomData> : DeviceLayout<TCustomData, object>
{ }

/// <summary>
/// Represents the serializable layout of a <see cref="IRGBDevice"/>.
/// </summary>
[Serializable]
[XmlRoot("Device")]
public class DeviceLayout<TCustomData, TCustomLedData> : IDeviceLayout
{
#region Properties & Fields

Expand Down Expand Up @@ -92,7 +108,7 @@ public class DeviceLayout : IDeviceLayout
/// Normally you should use <see cref="Leds"/> to access this data.
/// </summary>
[XmlArray("Leds")]
public List<LedLayout> InternalLeds { get; set; } = new();
public List<LedLayout<TCustomLedData>> InternalLeds { get; set; } = new();

/// <summary>
/// Gets or sets a list of <see cref="LedLayout"/> representing all the <see cref="Led"/> of the <see cref="DeviceLayout"/>.
Expand All @@ -101,15 +117,15 @@ public class DeviceLayout : IDeviceLayout
public IEnumerable<ILedLayout> Leds => InternalLeds;

/// <summary>
/// Gets or sets the internal custom data of this layout.
/// Normally you should use <see cref="CustomData"/> to access or set this data.
/// Gets or sets the custom data of this layout.
/// </summary>
[XmlElement("CustomData")]
public object? InternalCustomData { get; set; }
public TCustomData? CustomData { get; set; }

/// <inheritdoc />
[XmlIgnore]
public object? CustomData { get; set; }
/// <summary>
/// Gets the untyped custom data of this layout.
/// </summary>
public object? UntypedCustomData => CustomData;

#endregion

Expand All @@ -119,27 +135,21 @@ public class DeviceLayout : IDeviceLayout
/// Creates a new <see cref="DeviceLayout"/> from the specified xml.
/// </summary>
/// <param name="stream">The stream that contains the layout to be loaded.</param>
/// <param name="customDeviceDataType">The type of the custom data.</param>
/// <param name="customLedDataType">The type of the custom data of the leds.</param>
/// <returns>The deserialized <see cref="DeviceLayout"/>.</returns>
public static DeviceLayout? Load(Stream stream, Type? customDeviceDataType = null, Type? customLedDataType = null)
/// <returns>The deserialized <see cref="DeviceLayout{TCustomData, TCustomLedData}"/>.</returns>
public static DeviceLayout<TCustomData, TCustomLedData>? Load(Stream stream)
{
try
{
XmlSerializer serializer = new(typeof(DeviceLayout));
DeviceLayout? layout = serializer.Deserialize(stream) as DeviceLayout;
if (layout != null)
layout.CustomData = layout.GetCustomData(layout.InternalCustomData, customDeviceDataType);
XmlSerializer serializer = new(typeof(DeviceLayout<TCustomData, TCustomLedData>));
DeviceLayout<TCustomData, TCustomLedData>? layout = serializer.Deserialize(stream) as DeviceLayout<TCustomData, TCustomLedData>;

if (layout?.InternalLeds != null)
{
LedLayout? lastLed = null;
foreach (LedLayout led in layout.InternalLeds)
LedLayout<TCustomLedData>? lastLed = null;
foreach (LedLayout<TCustomLedData> led in layout.InternalLeds)
{
led.CalculateValues(layout, lastLed);
lastLed = led;

led.CustomData = layout.GetCustomData(led.InternalCustomData, customLedDataType);
}
}

Expand All @@ -155,36 +165,13 @@ public class DeviceLayout : IDeviceLayout
/// Creates a new <see cref="DeviceLayout"/> from the specified xml.
/// </summary>
/// <param name="path">The path to the xml file.</param>
/// <param name="customDeviceDataType">The type of the custom data.</param>
/// <param name="customLedDataType">The type of the custom data of the leds.</param>
/// <returns>The deserialized <see cref="DeviceLayout"/>.</returns>
public static DeviceLayout? Load(string path, Type? customDeviceDataType = null, Type? customLedDataType = null)
public static DeviceLayout<TCustomData, TCustomLedData>? Load(string path)
{
if (!File.Exists(path)) return null;

using Stream stream = File.OpenRead(path);
return Load(stream, customDeviceDataType, customLedDataType);
}

/// <summary>
/// Gets the deserialized custom data.
/// </summary>
/// <param name="customData">The internal custom data node.</param>
/// <param name="type">The type of the custom data.</param>
/// <returns>The deserialized custom data object.</returns>
protected virtual object? GetCustomData(object? customData, Type? type)
{
XmlNode? node = (customData as XmlNode) ?? (customData as IEnumerable<XmlNode>)?.FirstOrDefault()?.ParentNode; //HACK DarthAffe 16.01.2021: This gives us the CustomData-Node
if ((node == null) || (type == null)) return null;

using MemoryStream ms = new();
using StreamWriter writer = new(ms);

writer.Write(node.OuterXml);
writer.Flush();
ms.Seek(0, SeekOrigin.Begin);

return new XmlSerializer(type).Deserialize(ms);
return Load(stream);
}

#endregion
Expand Down
16 changes: 13 additions & 3 deletions RGB.NET.Layout/IDeviceLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,24 @@ public interface IDeviceLayout
/// Gets or sets the height of the <see cref="IDeviceLayout"/>.
/// </summary>
float Height { get; }

/// <summary>
/// Gets or sets the width of one 'unit' used for the calculation of led positions and sizes.
/// </summary>
float LedUnitWidth { get; set; }

/// <summary>
/// Gets or sets the height of one 'unit' used for the calculation of led positions and sizes.
/// </summary>
float LedUnitHeight { get; set; }

/// <summary>
/// Gets or sets a list of <see cref="ILedLayout"/> representing all the <see cref="Led"/> of the <see cref="IDeviceLayout"/>.
/// </summary>
IEnumerable<ILedLayout> Leds { get; }

/// <summary>
/// Gets the the custom data associated with the device.
/// Gets the untyped custom data of this layout.
/// </summary>
object? CustomData { get; }
object? UntypedCustomData { get; }
}
4 changes: 2 additions & 2 deletions RGB.NET.Layout/ILedLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public interface ILedLayout
float Height { get; }

/// <summary>
/// Gets the the custom data associated with the LED.
/// Gets the untyped custom data of this layout.
/// </summary>
object? CustomData { get; }
object? UntypedCustomData { get; }
}
4 changes: 2 additions & 2 deletions RGB.NET.Layout/LayoutExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static class LayoutExtension
public static void ApplyTo(this IDeviceLayout layout, IRGBDevice device, bool createMissingLeds = false, bool removeExcessiveLeds = false)
{
device.Size = new Size(layout.Width, layout.Height);
device.DeviceInfo.LayoutMetadata = layout.CustomData;
device.DeviceInfo.LayoutMetadata = layout.UntypedCustomData;

HashSet<LedId> ledIds = new();
foreach (ILedLayout layoutLed in layout.Leds)
Expand All @@ -39,7 +39,7 @@ public static void ApplyTo(this IDeviceLayout layout, IRGBDevice device, bool cr
led.Size = new Size(layoutLed.Width, layoutLed.Height);
led.Shape = layoutLed.Shape;
led.ShapeData = layoutLed.ShapeData;
led.LayoutMetadata = layoutLed.CustomData;
led.LayoutMetadata = layoutLed.UntypedCustomData;
}
}
}
Expand Down
37 changes: 23 additions & 14 deletions RGB.NET.Layout/LedLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ namespace RGB.NET.Layout;
/// </summary>
[Serializable]
[XmlType("Led")]
public class LedLayout : ILedLayout
public class LedLayout : LedLayout<object>
{ }

/// <summary>
/// Represents the serializable layout of a <see cref="Led"/>.
/// </summary>
[Serializable]
[XmlType("Led")]
public class LedLayout<TCustomLedData> : ILedLayout
{
#region Properties & Fields

Expand Down Expand Up @@ -61,17 +69,6 @@ public class LedLayout : ILedLayout
[DefaultValue("1.0")]
public string DescriptiveHeight { get; set; } = "1.0";

/// <summary>
/// Gets or sets the internal custom data of this layout.
/// Normally you should use <see cref="CustomData"/> to access or set this data.
/// </summary>
[XmlElement("CustomData")]
public object? InternalCustomData { get; set; }

/// <inheritdoc />
[XmlIgnore]
public object? CustomData { get; set; }

/// <summary>
/// Gets or sets the <see cref="RGB.NET.Core.Shape"/> of the <see cref="LedLayout"/>.
/// </summary>
Expand Down Expand Up @@ -108,6 +105,17 @@ public class LedLayout : ILedLayout
[XmlIgnore]
public float Height { get; private set; }

/// <summary>
/// Gets or sets the custom data of this layout.
/// </summary>
[XmlElement("CustomData")]
public TCustomLedData? CustomData { get; set; }

/// <summary>
/// Gets the untyped custom data of this layout.
/// </summary>
public object? UntypedCustomData => CustomData;

#endregion

#region Methods
Expand All @@ -117,13 +125,14 @@ public class LedLayout : ILedLayout
/// </summary>
/// <param name="device">The <see cref="DeviceLayout"/> this <see cref="LedLayout"/> belongs to.</param>
/// <param name="lastLed">The <see cref="LedLayout"/> previously calculated.</param>
public virtual void CalculateValues(DeviceLayout device, LedLayout? lastLed)
public virtual void CalculateValues(IDeviceLayout device, ILedLayout? lastLed)
{
if (!Enum.TryParse(DescriptiveShape, true, out Shape shape))
{
shape = Shape.Custom;
ShapeData = DescriptiveShape;
}

Shape = shape;

Width = GetSizeValue(DescriptiveWidth, device.LedUnitWidth);
Expand Down Expand Up @@ -204,4 +213,4 @@ protected virtual float GetSizeValue(string value, float unitSize)
}

#endregion
}
}

0 comments on commit ce860d5

Please sign in to comment.