1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Merge pull request #714 from Artemis-RGB/development

Bugfixes
This commit is contained in:
RobertBeekman 2022-08-21 11:38:16 +02:00 committed by GitHub
commit bc8b3b5482
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
698 changed files with 37309 additions and 38379 deletions

View File

@ -8,13 +8,13 @@ using Artemis.Core.Services.Core;
using Artemis.Core.SkiaSharp; using Artemis.Core.SkiaSharp;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A few useful constant values
/// </summary>
public static class Constants
{ {
/// <summary>
/// A few useful constant values
/// </summary>
public static class Constants
{
/// <summary> /// <summary>
/// The Artemis.Core assembly /// The Artemis.Core assembly
/// </summary> /// </summary>
@ -33,7 +33,9 @@ namespace Artemis.Core
/// <summary> /// <summary>
/// The base path for Artemis application data folder /// The base path for Artemis application data folder
/// </summary> /// </summary>
public static readonly string BaseFolder = Environment.GetFolderPath(OperatingSystem.IsWindows() ? Environment.SpecialFolder.CommonApplicationData : Environment.SpecialFolder.LocalApplicationData); public static readonly string BaseFolder = Environment.GetFolderPath(OperatingSystem.IsWindows()
? Environment.SpecialFolder.CommonApplicationData
: Environment.SpecialFolder.LocalApplicationData);
/// <summary> /// <summary>
/// The full path to the Artemis data folder /// The full path to the Artemis data folder
@ -55,6 +57,11 @@ namespace Artemis.Core
/// </summary> /// </summary>
public static readonly string LayoutsFolder = Path.Combine(DataFolder, "User Layouts"); public static readonly string LayoutsFolder = Path.Combine(DataFolder, "User Layouts");
/// <summary>
/// The current API version for plugins
/// </summary>
public static readonly Version PluginApi = new(1, 0);
/// <summary> /// <summary>
/// The plugin info used by core components of Artemis /// The plugin info used by core components of Artemis
/// </summary> /// </summary>
@ -145,5 +152,4 @@ namespace Artemis.Core
/// <see cref="IRgbService.UpdateGraphicsContext" />. /// <see cref="IRgbService.UpdateGraphicsContext" />.
/// </summary> /// </summary>
public static IManagedGraphicsContext? ManagedGraphicsContext { get; internal set; } public static IManagedGraphicsContext? ManagedGraphicsContext { get; internal set; }
}
} }

View File

@ -1,19 +1,12 @@
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class BoolLayerProperty : LayerProperty<bool>
{ {
/// <inheritdoc />
public class BoolLayerProperty : LayerProperty<bool>
{
internal BoolLayerProperty() internal BoolLayerProperty()
{ {
} }
/// <inheritdoc />
protected override void OnInitialize()
{
KeyframesSupported = false;
DataBinding.RegisterDataBindingProperty(() => CurrentValue, value => CurrentValue = value, "Value");
}
/// <summary> /// <summary>
/// Implicitly converts an <see cref="BoolLayerProperty" /> to a <see cref="bool" /> /// Implicitly converts an <see cref="BoolLayerProperty" /> to a <see cref="bool" />
/// </summary> /// </summary>
@ -22,10 +15,16 @@
return p.CurrentValue; return p.CurrentValue;
} }
/// <inheritdoc />
protected override void OnInitialize()
{
KeyframesSupported = false;
DataBinding.RegisterDataBindingProperty(() => CurrentValue, value => CurrentValue = value, "Value");
}
/// <inheritdoc /> /// <inheritdoc />
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased) protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{ {
throw new ArtemisCoreException("Boolean properties do not support keyframes."); throw new ArtemisCoreException("Boolean properties do not support keyframes.");
} }
}
} }

View File

@ -1,17 +1,17 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class EnumLayerProperty<T> : LayerProperty<T> where T : Enum
{ {
/// <inheritdoc />
public class EnumLayerProperty<T> : LayerProperty<T> where T : Enum
{
internal EnumLayerProperty() internal EnumLayerProperty()
{ {
KeyframesSupported = false; KeyframesSupported = false;
} }
/// <summary> /// <summary>
/// Implicitly converts an <see cref="EnumLayerProperty{T}" /> to a <typeparamref name="T"/> /// Implicitly converts an <see cref="EnumLayerProperty{T}" /> to a <typeparamref name="T" />
/// </summary> /// </summary>
public static implicit operator T(EnumLayerProperty<T> p) public static implicit operator T(EnumLayerProperty<T> p)
{ {
@ -31,5 +31,4 @@ namespace Artemis.Core
{ {
throw new ArtemisCoreException("Enum properties do not support keyframes."); throw new ArtemisCoreException("Enum properties do not support keyframes.");
} }
}
} }

View File

@ -1,18 +1,12 @@
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class FloatLayerProperty : LayerProperty<float>
{ {
/// <inheritdoc />
public class FloatLayerProperty : LayerProperty<float>
{
internal FloatLayerProperty() internal FloatLayerProperty()
{ {
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue, value => CurrentValue = value, "Value");
}
/// <summary> /// <summary>
/// Implicitly converts an <see cref="FloatLayerProperty" /> to a <see cref="float" /> /// Implicitly converts an <see cref="FloatLayerProperty" /> to a <see cref="float" />
/// </summary> /// </summary>
@ -29,11 +23,16 @@
return p.CurrentValue; return p.CurrentValue;
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue, value => CurrentValue = value, "Value");
}
/// <inheritdoc /> /// <inheritdoc />
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased) protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{ {
float diff = NextKeyframe!.Value - CurrentKeyframe!.Value; float diff = NextKeyframe!.Value - CurrentKeyframe!.Value;
CurrentValue = CurrentKeyframe!.Value + diff * keyframeProgressEased; CurrentValue = CurrentKeyframe!.Value + diff * keyframeProgressEased;
} }
}
} }

View File

@ -1,8 +1,8 @@
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class FloatRangeLayerProperty : LayerProperty<FloatRange>
{ {
/// <inheritdoc />
public class FloatRangeLayerProperty : LayerProperty<FloatRange>
{
/// <inheritdoc /> /// <inheritdoc />
protected override void OnInitialize() protected override void OnInitialize()
{ {
@ -16,9 +16,8 @@
float startDiff = NextKeyframe!.Value.Start - CurrentKeyframe!.Value.Start; float startDiff = NextKeyframe!.Value.Start - CurrentKeyframe!.Value.Start;
float endDiff = NextKeyframe!.Value.End - CurrentKeyframe!.Value.End; float endDiff = NextKeyframe!.Value.End - CurrentKeyframe!.Value.End;
CurrentValue = new FloatRange( CurrentValue = new FloatRange(
(float) (CurrentKeyframe!.Value.Start + startDiff * keyframeProgressEased), CurrentKeyframe!.Value.Start + startDiff * keyframeProgressEased,
(float) (CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased) CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased
); );
} }
}
} }

View File

@ -1,20 +1,14 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class IntLayerProperty : LayerProperty<int>
{ {
/// <inheritdoc />
public class IntLayerProperty : LayerProperty<int>
{
internal IntLayerProperty() internal IntLayerProperty()
{ {
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue, value => CurrentValue = value, "Value");
}
/// <summary> /// <summary>
/// Implicitly converts an <see cref="IntLayerProperty" /> to an <see cref="int" /> /// Implicitly converts an <see cref="IntLayerProperty" /> to an <see cref="int" />
/// </summary> /// </summary>
@ -39,11 +33,16 @@ namespace Artemis.Core
return p.CurrentValue; return p.CurrentValue;
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue, value => CurrentValue = value, "Value");
}
/// <inheritdoc /> /// <inheritdoc />
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased) protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{ {
int diff = NextKeyframe!.Value - CurrentKeyframe!.Value; int diff = NextKeyframe!.Value - CurrentKeyframe!.Value;
CurrentValue = (int) Math.Round(CurrentKeyframe!.Value + diff * keyframeProgressEased, MidpointRounding.AwayFromZero); CurrentValue = (int) Math.Round(CurrentKeyframe!.Value + diff * keyframeProgressEased, MidpointRounding.AwayFromZero);
} }
}
} }

View File

@ -1,8 +1,8 @@
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class IntRangeLayerProperty : LayerProperty<IntRange>
{ {
/// <inheritdoc />
public class IntRangeLayerProperty : LayerProperty<IntRange>
{
/// <inheritdoc /> /// <inheritdoc />
protected override void OnInitialize() protected override void OnInitialize()
{ {
@ -20,5 +20,4 @@
(int) (CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased) (int) (CurrentKeyframe!.Value.End + endDiff * keyframeProgressEased)
); );
} }
}
} }

View File

@ -1,10 +1,10 @@
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A special layer property used to configure the selected layer brush
/// </summary>
public class LayerBrushReferenceLayerProperty : LayerProperty<LayerBrushReference?>
{ {
/// <summary>
/// A special layer property used to configure the selected layer brush
/// </summary>
public class LayerBrushReferenceLayerProperty : LayerProperty<LayerBrushReference?>
{
internal LayerBrushReferenceLayerProperty() internal LayerBrushReferenceLayerProperty()
{ {
KeyframesSupported = false; KeyframesSupported = false;
@ -23,5 +23,4 @@
{ {
throw new ArtemisCoreException("Layer brush references do not support keyframes."); throw new ArtemisCoreException("Layer brush references do not support keyframes.");
} }
}
} }

View File

@ -1,20 +1,14 @@
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class SKColorLayerProperty : LayerProperty<SKColor>
{ {
/// <inheritdoc />
public class SKColorLayerProperty : LayerProperty<SKColor>
{
internal SKColorLayerProperty() internal SKColorLayerProperty()
{ {
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue, value => CurrentValue = value, "Value");
}
/// <summary> /// <summary>
/// Implicitly converts an <see cref="SKColorLayerProperty" /> to an <see cref="SKColor" />¶ /// Implicitly converts an <see cref="SKColorLayerProperty" /> to an <see cref="SKColor" />¶
/// </summary> /// </summary>
@ -25,10 +19,15 @@ namespace Artemis.Core
return p.CurrentValue; return p.CurrentValue;
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue, value => CurrentValue = value, "Value");
}
/// <inheritdoc /> /// <inheritdoc />
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased) protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{ {
CurrentValue = CurrentKeyframe!.Value.Interpolate(NextKeyframe!.Value, keyframeProgressEased); CurrentValue = CurrentKeyframe!.Value.Interpolate(NextKeyframe!.Value, keyframeProgressEased);
} }
}
} }

View File

@ -1,21 +1,14 @@
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class SKPointLayerProperty : LayerProperty<SKPoint>
{ {
/// <inheritdoc />
public class SKPointLayerProperty : LayerProperty<SKPoint>
{
internal SKPointLayerProperty() internal SKPointLayerProperty()
{ {
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue.X, value => CurrentValue = new SKPoint(value, CurrentValue.Y), "X");
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Y, value => CurrentValue = new SKPoint(CurrentValue.X, value), "Y");
}
/// <summary> /// <summary>
/// Implicitly converts an <see cref="SKPointLayerProperty" /> to an <see cref="SKPoint" /> /// Implicitly converts an <see cref="SKPointLayerProperty" /> to an <see cref="SKPoint" />
/// </summary> /// </summary>
@ -24,6 +17,13 @@ namespace Artemis.Core
return p.CurrentValue; return p.CurrentValue;
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue.X, value => CurrentValue = new SKPoint(value, CurrentValue.Y), "X");
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Y, value => CurrentValue = new SKPoint(CurrentValue.X, value), "Y");
}
/// <inheritdoc /> /// <inheritdoc />
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased) protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{ {
@ -31,5 +31,4 @@ namespace Artemis.Core
float yDiff = NextKeyframe!.Value.Y - CurrentKeyframe!.Value.Y; float yDiff = NextKeyframe!.Value.Y - CurrentKeyframe!.Value.Y;
CurrentValue = new SKPoint(CurrentKeyframe!.Value.X + xDiff * keyframeProgressEased, CurrentKeyframe!.Value.Y + yDiff * keyframeProgressEased); CurrentValue = new SKPoint(CurrentKeyframe!.Value.X + xDiff * keyframeProgressEased, CurrentKeyframe!.Value.Y + yDiff * keyframeProgressEased);
} }
}
} }

View File

@ -1,21 +1,14 @@
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class SKSizeLayerProperty : LayerProperty<SKSize>
{ {
/// <inheritdoc />
public class SKSizeLayerProperty : LayerProperty<SKSize>
{
internal SKSizeLayerProperty() internal SKSizeLayerProperty()
{ {
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Width, (value) => CurrentValue = new SKSize(value, CurrentValue.Height), "Width");
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Height, (value) => CurrentValue = new SKSize(CurrentValue.Width, value), "Height");
}
/// <summary> /// <summary>
/// Implicitly converts an <see cref="SKSizeLayerProperty" /> to an <see cref="SKSize" /> /// Implicitly converts an <see cref="SKSizeLayerProperty" /> to an <see cref="SKSize" />
/// </summary> /// </summary>
@ -24,6 +17,13 @@ namespace Artemis.Core
return p.CurrentValue; return p.CurrentValue;
} }
/// <inheritdoc />
protected override void OnInitialize()
{
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Width, value => CurrentValue = new SKSize(value, CurrentValue.Height), "Width");
DataBinding.RegisterDataBindingProperty(() => CurrentValue.Height, value => CurrentValue = new SKSize(CurrentValue.Width, value), "Height");
}
/// <inheritdoc /> /// <inheritdoc />
protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased) protected override void UpdateCurrentValue(float keyframeProgress, float keyframeProgressEased)
{ {
@ -31,5 +31,4 @@ namespace Artemis.Core
float heightDiff = NextKeyframe!.Value.Height - CurrentKeyframe!.Value.Height; float heightDiff = NextKeyframe!.Value.Height - CurrentKeyframe!.Value.Height;
CurrentValue = new SKSize(CurrentKeyframe!.Value.Width + widthDiff * keyframeProgressEased, CurrentKeyframe!.Value.Height + heightDiff * keyframeProgressEased); CurrentValue = new SKSize(CurrentKeyframe!.Value.Width + widthDiff * keyframeProgressEased, CurrentKeyframe!.Value.Height + heightDiff * keyframeProgressEased);
} }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about data model path related events
/// </summary>
public class DataModelPathEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about data model path related events
/// </summary>
public class DataModelPathEventArgs : EventArgs
{
internal DataModelPathEventArgs(DataModelPath dataModelPath) internal DataModelPathEventArgs(DataModelPath dataModelPath)
{ {
DataModelPath = dataModelPath; DataModelPath = dataModelPath;
@ -16,5 +16,4 @@ namespace Artemis.Core
/// Gets the data model path this event is related to /// Gets the data model path this event is related to
/// </summary> /// </summary>
public DataModelPath DataModelPath { get; } public DataModelPath DataModelPath { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about device related events
/// </summary>
public class DeviceEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about device related events
/// </summary>
public class DeviceEventArgs : EventArgs
{
internal DeviceEventArgs(ArtemisDevice device) internal DeviceEventArgs(ArtemisDevice device)
{ {
Device = device; Device = device;
@ -16,5 +16,4 @@ namespace Artemis.Core
/// Gets the device this event is related to /// Gets the device this event is related to
/// </summary> /// </summary>
public ArtemisDevice Device { get; } public ArtemisDevice Device { get; }
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using Artemis.Core.Modules; using Artemis.Core.Modules;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about dynamic data model child related events
/// </summary>
public class DynamicDataModelChildEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about dynamic data model child related events
/// </summary>
public class DynamicDataModelChildEventArgs : EventArgs
{
internal DynamicDataModelChildEventArgs(DynamicChild dynamicChild, string key) internal DynamicDataModelChildEventArgs(DynamicChild dynamicChild, string key)
{ {
DynamicChild = dynamicChild; DynamicChild = dynamicChild;
@ -23,5 +23,4 @@ namespace Artemis.Core
/// Gets the key of the dynamic data model on the parent <see cref="DataModel" /> /// Gets the key of the dynamic data model on the parent <see cref="DataModel" />
/// </summary> /// </summary>
public string Key { get; } public string Key { get; }
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using RGB.NET.Core; using RGB.NET.Core;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about frame rendering related events
/// </summary>
public class FrameRenderedEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about frame rendering related events
/// </summary>
public class FrameRenderedEventArgs : EventArgs
{
internal FrameRenderedEventArgs(SKTexture texture, RGBSurface rgbSurface) internal FrameRenderedEventArgs(SKTexture texture, RGBSurface rgbSurface)
{ {
Texture = texture; Texture = texture;
@ -23,5 +23,4 @@ namespace Artemis.Core
/// Gets the RGB surface used to render this frame /// Gets the RGB surface used to render this frame
/// </summary> /// </summary>
public RGBSurface RgbSurface { get; } public RGBSurface RgbSurface { get; }
}
} }

View File

@ -2,13 +2,13 @@
using RGB.NET.Core; using RGB.NET.Core;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about frame rendered related events
/// </summary>
public class FrameRenderingEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about frame rendered related events
/// </summary>
public class FrameRenderingEventArgs : EventArgs
{
internal FrameRenderingEventArgs(SKCanvas canvas, double deltaTime, RGBSurface rgbSurface) internal FrameRenderingEventArgs(SKCanvas canvas, double deltaTime, RGBSurface rgbSurface)
{ {
Canvas = canvas; Canvas = canvas;
@ -30,5 +30,4 @@ namespace Artemis.Core
/// Gets the RGB surface used to render this frame /// Gets the RGB surface used to render this frame
/// </summary> /// </summary>
public RGBSurface RgbSurface { get; } public RGBSurface RgbSurface { get; }
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using Artemis.Core.Modules; using Artemis.Core.Modules;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about module events
/// </summary>
public class ModuleEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about module events
/// </summary>
public class ModuleEventArgs : EventArgs
{
internal ModuleEventArgs(Module module) internal ModuleEventArgs(Module module)
{ {
Module = module; Module = module;
@ -17,5 +17,4 @@ namespace Artemis.Core
/// Gets the module this event is related to /// Gets the module this event is related to
/// </summary> /// </summary>
public Module Module { get; } public Module Module { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about plugin related events
/// </summary>
public class PluginEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about plugin related events
/// </summary>
public class PluginEventArgs : EventArgs
{
internal PluginEventArgs(Plugin plugin) internal PluginEventArgs(Plugin plugin)
{ {
Plugin = plugin; Plugin = plugin;
@ -16,5 +16,4 @@ namespace Artemis.Core
/// Gets the plugin this event is related to /// Gets the plugin this event is related to
/// </summary> /// </summary>
public Plugin Plugin { get; } public Plugin Plugin { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about plugin feature related events
/// </summary>
public class PluginFeatureEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about plugin feature related events
/// </summary>
public class PluginFeatureEventArgs : EventArgs
{
internal PluginFeatureEventArgs(PluginFeature pluginFeature) internal PluginFeatureEventArgs(PluginFeature pluginFeature)
{ {
PluginFeature = pluginFeature; PluginFeature = pluginFeature;
@ -16,13 +16,13 @@ namespace Artemis.Core
/// Gets the plugin feature this event is related to /// Gets the plugin feature this event is related to
/// </summary> /// </summary>
public PluginFeature PluginFeature { get; } public PluginFeature PluginFeature { get; }
} }
/// <summary> /// <summary>
/// Provides data about plugin feature info related events /// Provides data about plugin feature info related events
/// </summary> /// </summary>
public class PluginFeatureInfoEventArgs : EventArgs public class PluginFeatureInfoEventArgs : EventArgs
{ {
internal PluginFeatureInfoEventArgs(PluginFeatureInfo pluginFeatureInfo) internal PluginFeatureInfoEventArgs(PluginFeatureInfo pluginFeatureInfo)
{ {
PluginFeatureInfo = pluginFeatureInfo; PluginFeatureInfo = pluginFeatureInfo;
@ -32,5 +32,4 @@ namespace Artemis.Core
/// Gets the plugin feature this event is related to /// Gets the plugin feature this event is related to
/// </summary> /// </summary>
public PluginFeatureInfo PluginFeatureInfo { get; } public PluginFeatureInfo PluginFeatureInfo { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data for data binding events.
/// </summary>
public class DataBindingEventArgs : EventArgs
{ {
/// <summary>
/// Provides data for data binding events.
/// </summary>
public class DataBindingEventArgs : EventArgs
{
internal DataBindingEventArgs(IDataBinding dataBinding) internal DataBindingEventArgs(IDataBinding dataBinding)
{ {
DataBinding = dataBinding; DataBinding = dataBinding;
@ -16,5 +16,4 @@ namespace Artemis.Core
/// Gets the data binding this event is related to /// Gets the data binding this event is related to
/// </summary> /// </summary>
public IDataBinding DataBinding { get; } public IDataBinding DataBinding { get; }
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data for the <see langword='DataBindingPropertyUpdatedEvent' /> event.
/// </summary>
/// <typeparam name="T"></typeparam>
public class DataBindingPropertyUpdatedEvent<T> : EventArgs
{ {
/// <summary>
/// Provides data for the <see langword='DataBindingPropertyUpdatedEvent' /> event.
/// </summary>
/// <typeparam name="T"></typeparam>
public class DataBindingPropertyUpdatedEvent<T> : EventArgs
{
internal DataBindingPropertyUpdatedEvent(T value) internal DataBindingPropertyUpdatedEvent(T value)
{ {
Value = value; Value = value;
@ -17,5 +17,4 @@ namespace Artemis.Core
/// The updated value that should be applied to the layer property /// The updated value that should be applied to the layer property
/// </summary> /// </summary>
public T Value { get; } public T Value { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data for layer property events.
/// </summary>
public class LayerPropertyEventArgs : EventArgs
{ {
/// <summary>
/// Provides data for layer property events.
/// </summary>
public class LayerPropertyEventArgs : EventArgs
{
internal LayerPropertyEventArgs(ILayerProperty layerProperty) internal LayerPropertyEventArgs(ILayerProperty layerProperty)
{ {
LayerProperty = layerProperty; LayerProperty = layerProperty;
@ -16,5 +16,4 @@ namespace Artemis.Core
/// Gets the layer property this event is related to /// Gets the layer property this event is related to
/// </summary> /// </summary>
public ILayerProperty LayerProperty { get; } public ILayerProperty LayerProperty { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data for profile configuration events.
/// </summary>
public class ProfileConfigurationEventArgs : EventArgs
{ {
/// <summary>
/// Provides data for profile configuration events.
/// </summary>
public class ProfileConfigurationEventArgs : EventArgs
{
internal ProfileConfigurationEventArgs(ProfileConfiguration profileConfiguration) internal ProfileConfigurationEventArgs(ProfileConfiguration profileConfiguration)
{ {
ProfileConfiguration = profileConfiguration; ProfileConfiguration = profileConfiguration;
@ -16,5 +16,4 @@ namespace Artemis.Core
/// Gets the profile configuration this event is related to /// Gets the profile configuration this event is related to
/// </summary> /// </summary>
public ProfileConfiguration ProfileConfiguration { get; } public ProfileConfiguration ProfileConfiguration { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data for profile element events.
/// </summary>
public class ProfileElementEventArgs : EventArgs
{ {
/// <summary>
/// Provides data for profile element events.
/// </summary>
public class ProfileElementEventArgs : EventArgs
{
internal ProfileElementEventArgs(ProfileElement profileElement) internal ProfileElementEventArgs(ProfileElement profileElement)
{ {
ProfileElement = profileElement; ProfileElement = profileElement;
@ -16,5 +16,4 @@ namespace Artemis.Core
/// Gets the profile element this event is related to /// Gets the profile element this event is related to
/// </summary> /// </summary>
public ProfileElement ProfileElement { get; } public ProfileElement ProfileElement { get; }
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about application restart events
/// </summary>
public class RestartEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about application restart events
/// </summary>
public class RestartEventArgs : EventArgs
{
internal RestartEventArgs(bool elevate, TimeSpan delay, List<string>? extraArgs) internal RestartEventArgs(bool elevate, TimeSpan delay, List<string>? extraArgs)
{ {
Elevate = elevate; Elevate = elevate;
@ -29,5 +29,4 @@ namespace Artemis.Core
/// A list of extra arguments to pass to Artemis when restarting /// A list of extra arguments to pass to Artemis when restarting
/// </summary> /// </summary>
public List<string>? ExtraArgs { get; } public List<string>? ExtraArgs { get; }
}
} }

View File

@ -1,12 +1,11 @@
namespace Artemis.Core namespace Artemis.Core;
internal class DataModelStoreEvent
{ {
internal class DataModelStoreEvent
{
public DataModelStoreEvent(DataModelRegistration registration) public DataModelStoreEvent(DataModelRegistration registration)
{ {
Registration = registration; Registration = registration;
} }
public DataModelRegistration Registration { get; } public DataModelRegistration Registration { get; }
}
} }

View File

@ -1,12 +1,11 @@
namespace Artemis.Core namespace Artemis.Core;
internal class LayerBrushStoreEvent
{ {
internal class LayerBrushStoreEvent
{
public LayerBrushStoreEvent(LayerBrushRegistration registration) public LayerBrushStoreEvent(LayerBrushRegistration registration)
{ {
Registration = registration; Registration = registration;
} }
public LayerBrushRegistration Registration { get; } public LayerBrushRegistration Registration { get; }
}
} }

View File

@ -1,12 +1,11 @@
namespace Artemis.Core namespace Artemis.Core;
internal class LayerEffectStoreEvent
{ {
internal class LayerEffectStoreEvent
{
public LayerEffectStoreEvent(LayerEffectRegistration registration) public LayerEffectStoreEvent(LayerEffectRegistration registration)
{ {
Registration = registration; Registration = registration;
} }
public LayerEffectRegistration Registration { get; } public LayerEffectRegistration Registration { get; }
}
} }

View File

@ -1,12 +1,11 @@
namespace Artemis.Core namespace Artemis.Core;
internal class NodeTypeStoreEvent
{ {
internal class NodeTypeStoreEvent
{
public NodeTypeStoreEvent(NodeTypeRegistration typeRegistration) public NodeTypeStoreEvent(NodeTypeRegistration typeRegistration)
{ {
TypeRegistration = typeRegistration; TypeRegistration = typeRegistration;
} }
public NodeTypeRegistration TypeRegistration { get; } public NodeTypeRegistration TypeRegistration { get; }
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides data about device configuration related events
/// </summary>
public class SurfaceConfigurationEventArgs : EventArgs
{ {
/// <summary>
/// Provides data about device configuration related events
/// </summary>
public class SurfaceConfigurationEventArgs : EventArgs
{
internal SurfaceConfigurationEventArgs(List<ArtemisDevice> devices) internal SurfaceConfigurationEventArgs(List<ArtemisDevice> devices)
{ {
Devices = devices; Devices = devices;
@ -17,5 +17,4 @@ namespace Artemis.Core
/// Gets the current list of devices /// Gets the current list of devices
/// </summary> /// </summary>
public List<ArtemisDevice> Devices { get; } public List<ArtemisDevice> Devices { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents errors that occur within the Artemis Core
/// </summary>
public class ArtemisCoreException : Exception
{ {
/// <summary>
/// Represents errors that occur within the Artemis Core
/// </summary>
public class ArtemisCoreException : Exception
{
internal ArtemisCoreException(string message) : base(message) internal ArtemisCoreException(string message) : base(message)
{ {
} }
@ -14,5 +14,4 @@ namespace Artemis.Core
internal ArtemisCoreException(string message, Exception inner) : base(message, inner) internal ArtemisCoreException(string message, Exception inner) : base(message, inner)
{ {
} }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents SkiaSharp graphics-context related errors
/// </summary>
public class ArtemisGraphicsContextException : Exception
{ {
/// <summary>
/// Represents SkiaSharp graphics-context related errors
/// </summary>
public class ArtemisGraphicsContextException : Exception
{
/// <inheritdoc /> /// <inheritdoc />
public ArtemisGraphicsContextException() public ArtemisGraphicsContextException()
{ {
@ -21,5 +21,4 @@ namespace Artemis.Core
public ArtemisGraphicsContextException(string message, Exception innerException) : base(message, innerException) public ArtemisGraphicsContextException(string message, Exception innerException) : base(message, innerException)
{ {
} }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// An exception thrown when a plugin-related error occurs
/// </summary>
public class ArtemisPluginException : Exception
{ {
/// <summary>
/// An exception thrown when a plugin-related error occurs
/// </summary>
public class ArtemisPluginException : Exception
{
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="ArtemisPluginException" /> class /// Creates a new instance of the <see cref="ArtemisPluginException" /> class
/// </summary> /// </summary>
@ -49,5 +49,4 @@ namespace Artemis.Core
/// Gets the plugin the error is related to /// Gets the plugin the error is related to
/// </summary> /// </summary>
public Plugin? Plugin { get; } public Plugin? Plugin { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// An exception thrown when a plugin feature-related error occurs
/// </summary>
public class ArtemisPluginFeatureException : Exception
{ {
/// <summary>
/// An exception thrown when a plugin feature-related error occurs
/// </summary>
public class ArtemisPluginFeatureException : Exception
{
internal ArtemisPluginFeatureException(PluginFeature pluginFeature) internal ArtemisPluginFeatureException(PluginFeature pluginFeature)
{ {
PluginFeature = pluginFeature; PluginFeature = pluginFeature;
@ -26,5 +26,4 @@ namespace Artemis.Core
/// Gets the plugin feature the error is related to /// Gets the plugin feature the error is related to
/// </summary> /// </summary>
public PluginFeature PluginFeature { get; } public PluginFeature PluginFeature { get; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// An exception thrown when a plugin lock file error occurs
/// </summary>
public class ArtemisPluginLockException : Exception
{ {
/// <summary>
/// An exception thrown when a plugin lock file error occurs
/// </summary>
public class ArtemisPluginLockException : Exception
{
internal ArtemisPluginLockException(Exception? innerException) : base(CreateExceptionMessage(innerException), innerException) internal ArtemisPluginLockException(Exception? innerException) : base(CreateExceptionMessage(innerException), innerException)
{ {
} }
@ -17,5 +17,4 @@ namespace Artemis.Core
? "Found a lock file, skipping load, see inner exception for last known exception." ? "Found a lock file, skipping load, see inner exception for last known exception."
: "Found a lock file, skipping load."; : "Found a lock file, skipping load.";
} }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// An exception thrown when a plugin prerequisite-related error occurs
/// </summary>
public class ArtemisPluginPrerequisiteException : Exception
{ {
/// <summary>
/// An exception thrown when a plugin prerequisite-related error occurs
/// </summary>
public class ArtemisPluginPrerequisiteException : Exception
{
internal ArtemisPluginPrerequisiteException(IPrerequisitesSubject subject) internal ArtemisPluginPrerequisiteException(IPrerequisitesSubject subject)
{ {
Subject = subject; Subject = subject;
@ -26,5 +26,4 @@ namespace Artemis.Core
/// Gets the subject the error is related to /// Gets the subject the error is related to
/// </summary> /// </summary>
public IPrerequisitesSubject Subject { get; } public IPrerequisitesSubject Subject { get; }
}
} }

View File

@ -1,9 +1,9 @@
using System.IO; using System.IO;
namespace Artemis.Core namespace Artemis.Core;
internal static class DirectoryInfoExtensions
{ {
internal static class DirectoryInfoExtensions
{
public static void CopyFilesRecursively(this DirectoryInfo source, DirectoryInfo target) public static void CopyFilesRecursively(this DirectoryInfo source, DirectoryInfo target)
{ {
foreach (DirectoryInfo dir in source.GetDirectories()) foreach (DirectoryInfo dir in source.GetDirectories())
@ -28,5 +28,4 @@ namespace Artemis.Core
baseDir.Delete(); baseDir.Delete();
} }
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A static class providing <see cref="double" /> extensions
/// </summary>
public static class DoubleExtensions
{ {
/// <summary>
/// A static class providing <see cref="double" /> extensions
/// </summary>
public static class DoubleExtensions
{
/// <summary> /// <summary>
/// Rounds the provided number away to zero and casts the result to an <see cref="int" /> /// Rounds the provided number away to zero and casts the result to an <see cref="int" />
/// </summary> /// </summary>
@ -18,5 +18,4 @@ namespace Artemis.Core
{ {
return (int) Math.Round(number, MidpointRounding.AwayFromZero); return (int) Math.Round(number, MidpointRounding.AwayFromZero);
} }
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A static class providing <see cref="float" /> extensions
/// </summary>
public static class FloatExtensions
{ {
/// <summary>
/// A static class providing <see cref="float" /> extensions
/// </summary>
public static class FloatExtensions
{
/// <summary> /// <summary>
/// Rounds the provided number away to zero and casts the result to an <see cref="int" /> /// Rounds the provided number away to zero and casts the result to an <see cref="int" />
/// </summary> /// </summary>
@ -18,5 +18,4 @@ namespace Artemis.Core
{ {
return (int) MathF.Round(number, MidpointRounding.AwayFromZero); return (int) MathF.Round(number, MidpointRounding.AwayFromZero);
} }
}
} }

View File

@ -19,17 +19,16 @@
#endregion #endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A static class providing <see cref="IEnumerable{T}" /> extensions
/// </summary>
// ReSharper disable once InconsistentNaming
public static class IEnumerableExtensions
{ {
/// <summary>
/// A static class providing <see cref="IEnumerable{T}" /> extensions
/// </summary>
// ReSharper disable once InconsistentNaming
public static class IEnumerableExtensions
{
/// <summary> /// <summary>
/// Returns the index of the provided element inside the read only collection /// Returns the index of the provided element inside the read only collection
/// </summary> /// </summary>
@ -49,5 +48,4 @@ namespace Artemis.Core
return -1; return -1;
} }
}
} }

View File

@ -1,16 +1,17 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A static class providing <see cref="Process" /> extensions
/// </summary>
[SuppressMessage("Design", "CA1060:Move pinvokes to native methods class", Justification = "I don't care, piss off")]
public static class ProcessExtensions
{ {
/// <summary>
/// A static class providing <see cref="Process" /> extensions
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1060:Move pinvokes to native methods class", Justification = "I don't care, piss off")]
public static class ProcessExtensions
{
/// <summary> /// <summary>
/// Gets the file name of the given process /// Gets the file name of the given process
/// </summary> /// </summary>
@ -37,5 +38,4 @@ namespace Artemis.Core
{ {
QueryLimitedInformation = 0x00001000 QueryLimitedInformation = 0x00001000
} }
}
} }

View File

@ -2,10 +2,10 @@
using RGB.NET.Core; using RGB.NET.Core;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
internal static class RgbDeviceExtensions
{ {
internal static class RgbDeviceExtensions
{
public static string GetDeviceIdentifier(this IRGBDevice rgbDevice) public static string GetDeviceIdentifier(this IRGBDevice rgbDevice)
{ {
StringBuilder builder = new(); StringBuilder builder = new();
@ -18,10 +18,10 @@ namespace Artemis.Core
builder.Append(rgbDevice.DeviceInfo.DeviceType); builder.Append(rgbDevice.DeviceInfo.DeviceType);
return builder.ToString(); return builder.ToString();
} }
} }
internal static class RgbRectangleExtensions internal static class RgbRectangleExtensions
{ {
public static SKRect ToSKRect(this Rectangle rectangle) public static SKRect ToSKRect(this Rectangle rectangle)
{ {
return SKRect.Create( return SKRect.Create(
@ -36,5 +36,4 @@ namespace Artemis.Core
{ {
return SKRectI.Round(ToSKRect(rectangle)); return SKRectI.Round(ToSKRect(rectangle));
} }
}
} }

View File

@ -2,13 +2,13 @@
using RGB.NET.Core; using RGB.NET.Core;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A static class providing <see cref="SKColor" /> extensions
/// </summary>
public static class SKColorExtensions
{ {
/// <summary>
/// A static class providing <see cref="SKColor" /> extensions
/// </summary>
public static class SKColorExtensions
{
/// <summary> /// <summary>
/// Converts hte SKColor to an RGB.NET color /// Converts hte SKColor to an RGB.NET color
/// </summary> /// </summary>
@ -74,5 +74,4 @@ namespace Artemis.Core
{ {
return (byte) Math.Clamp(value, 0, 255); return (byte) Math.Clamp(value, 0, 255);
} }
}
} }

View File

@ -1,9 +1,9 @@
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
internal static class SKPaintExtensions
{ {
internal static class SKPaintExtensions
{
internal static void DisposeSelfAndProperties(this SKPaint paint) internal static void DisposeSelfAndProperties(this SKPaint paint)
{ {
paint.ImageFilter?.Dispose(); paint.ImageFilter?.Dispose();
@ -12,5 +12,4 @@ namespace Artemis.Core
paint.Shader?.Dispose(); paint.Shader?.Dispose();
paint.Dispose(); paint.Dispose();
} }
}
} }

View File

@ -25,15 +25,14 @@
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Artemis.Core namespace Artemis.Core;
internal static class StreamExtensions
{ {
internal static class StreamExtensions
{
private const int DefaultBufferSize = 81920; private const int DefaultBufferSize = 81920;
/// <summary> /// <summary>
@ -130,5 +129,4 @@ namespace Artemis.Core
{ {
return CopyToAsync(source, 0L, destination, 0, progress, default); return CopyToAsync(source, 0L, destination, 0, progress, default);
} }
}
} }

View File

@ -5,13 +5,13 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using Humanizer; using Humanizer;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A static class providing <see cref="Type" /> extensions
/// </summary>
public static class TypeExtensions
{ {
/// <summary>
/// A static class providing <see cref="Type" /> extensions
/// </summary>
public static class TypeExtensions
{
private static readonly Dictionary<Type, List<Type>> PrimitiveTypeConversions = new() private static readonly Dictionary<Type, List<Type>> PrimitiveTypeConversions = new()
{ {
{typeof(decimal), new List<Type> {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char)}}, {typeof(decimal), new List<Type> {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char)}},
@ -183,7 +183,7 @@ namespace Artemis.Core
} }
/// <summary> /// <summary>
/// Determines if the <paramref name="typeToCheck"></paramref> is of a certain <paramref name="genericType"/>. /// Determines if the <paramref name="typeToCheck"></paramref> is of a certain <paramref name="genericType" />.
/// </summary> /// </summary>
/// <param name="typeToCheck">The type to check.</param> /// <param name="typeToCheck">The type to check.</param>
/// <param name="genericType">The generic type it should be or implement</param> /// <param name="genericType">The generic type it should be or implement</param>
@ -192,6 +192,28 @@ namespace Artemis.Core
return typeToCheck.IsOfGenericType(genericType, out Type? _); return typeToCheck.IsOfGenericType(genericType, out Type? _);
} }
/// <summary>
/// Determines a display name for the given type
/// </summary>
/// <param name="type">The type to determine the name for</param>
/// <param name="humanize">Whether or not to humanize the result, defaults to false</param>
/// <returns></returns>
public static string GetDisplayName(this Type type, bool humanize = false)
{
if (!type.IsGenericType)
{
string displayValue = TypeKeywords.TryGetValue(type, out string? keyword) ? keyword! : type.Name;
return humanize ? displayValue.Humanize() : displayValue;
}
Type genericTypeDefinition = type.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(Nullable<>))
return type.GenericTypeArguments[0].GetDisplayName(humanize) + "?";
string stripped = genericTypeDefinition.Name.Split('`')[0];
return $"{stripped}<{string.Join(", ", type.GenericTypeArguments.Select(t => t.GetDisplayName(humanize)))}>";
}
private static bool IsOfGenericType(this Type? typeToCheck, Type genericType, out Type? concreteGenericType) private static bool IsOfGenericType(this Type? typeToCheck, Type genericType, out Type? concreteGenericType)
{ {
while (true) while (true)
@ -221,33 +243,12 @@ namespace Artemis.Core
if (genericType.IsInterface) if (genericType.IsInterface)
foreach (Type i in typeToCheck.GetInterfaces()) foreach (Type i in typeToCheck.GetInterfaces())
{
if (i.IsOfGenericType(genericType, out concreteGenericType)) if (i.IsOfGenericType(genericType, out concreteGenericType))
return true; return true;
}
typeToCheck = typeToCheck.BaseType; typeToCheck = typeToCheck.BaseType;
} }
} }
/// <summary>
/// Determines a display name for the given type
/// </summary>
/// <param name="type">The type to determine the name for</param>
/// <param name="humanize">Whether or not to humanize the result, defaults to false</param>
/// <returns></returns>
public static string GetDisplayName(this Type type, bool humanize = false)
{
if (!type.IsGenericType)
{
string displayValue = TypeKeywords.TryGetValue(type, out string? keyword) ? keyword! : type.Name;
return humanize ? displayValue.Humanize() : displayValue;
}
Type genericTypeDefinition = type.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(Nullable<>))
return type.GenericTypeArguments[0].GetDisplayName(humanize) + "?";
string stripped = genericTypeDefinition.Name.Split('`')[0];
return $"{stripped}<{string.Join(", ", type.GenericTypeArguments.Select(t => t.GetDisplayName(humanize)))}>";
}
}
} }

View File

@ -2,13 +2,13 @@ using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace Artemis.Core.JsonConverters namespace Artemis.Core.JsonConverters;
/// <summary>
/// An int converter that, if required, will round float values
/// </summary>
internal class ForgivingIntConverter : JsonConverter<int>
{ {
/// <summary>
/// An int converter that, if required, will round float values
/// </summary>
internal class ForgivingIntConverter : JsonConverter<int>
{
public override bool CanWrite => false; public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer) public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer)
@ -29,5 +29,4 @@ namespace Artemis.Core.JsonConverters
throw new JsonReaderException("Failed to deserialize forgiving int value"); throw new JsonReaderException("Failed to deserialize forgiving int value");
} }
}
} }

View File

@ -1,10 +1,10 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Artemis.Core.JsonConverters namespace Artemis.Core.JsonConverters;
internal class NumericJsonConverter : JsonConverter<Numeric>
{ {
internal class NumericJsonConverter : JsonConverter<Numeric>
{
#region Overrides of JsonConverter<Numeric> #region Overrides of JsonConverter<Numeric>
/// <inheritdoc /> /// <inheritdoc />
@ -21,5 +21,4 @@ namespace Artemis.Core.JsonConverters
} }
#endregion #endregion
}
} }

View File

@ -2,10 +2,10 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core.JsonConverters namespace Artemis.Core.JsonConverters;
internal class SKColorConverter : JsonConverter<SKColor>
{ {
internal class SKColorConverter : JsonConverter<SKColor>
{
public override void WriteJson(JsonWriter writer, SKColor value, JsonSerializer serializer) public override void WriteJson(JsonWriter writer, SKColor value, JsonSerializer serializer)
{ {
writer.WriteValue(value.ToString()); writer.WriteValue(value.ToString());
@ -18,5 +18,4 @@ namespace Artemis.Core.JsonConverters
return SKColor.Empty; return SKColor.Empty;
} }
}
} }

View File

@ -2,11 +2,11 @@
using System.IO; using System.IO;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Artemis.Core.JsonConverters namespace Artemis.Core.JsonConverters;
/// <inheritdoc />
public class StreamConverter : JsonConverter<Stream>
{ {
/// <inheritdoc />
public class StreamConverter : JsonConverter<Stream>
{
#region Overrides of JsonConverter<Stream> #region Overrides of JsonConverter<Stream>
/// <inheritdoc /> /// <inheritdoc />
@ -41,5 +41,4 @@ namespace Artemis.Core.JsonConverters
} }
#endregion #endregion
}
} }

View File

@ -2,22 +2,18 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Artemis.Core.Properties; using Artemis.Core.Properties;
namespace Artemis.Core namespace Artemis.Core;
{
/// <summary>
/// Represents a basic bindable class which notifies when a property value changes.
/// </summary>
public abstract class CorePropertyChanged : INotifyPropertyChanged
{
#region Events
/// <summary>
/// Represents a basic bindable class which notifies when a property value changes.
/// </summary>
public abstract class CorePropertyChanged : INotifyPropertyChanged
{
/// <summary> /// <summary>
/// Occurs when a property value changes. /// Occurs when a property value changes.
/// </summary> /// </summary>
public event PropertyChangedEventHandler? PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;
#endregion
#region Methods #region Methods
/// <summary> /// <summary>
@ -70,5 +66,4 @@ namespace Artemis.Core
} }
#endregion #endregion
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Provides a default implementation for models that can have a broken state
/// </summary>
public abstract class BreakableModel : CorePropertyChanged, IBreakableModel
{ {
/// <summary>
/// Provides a default implementation for models that can have a broken state
/// </summary>
public abstract class BreakableModel : CorePropertyChanged, IBreakableModel
{
private string? _brokenState; private string? _brokenState;
private Exception? _brokenStateException; private Exception? _brokenStateException;
@ -88,5 +88,4 @@ namespace Artemis.Core
/// <inheritdoc /> /// <inheritdoc />
public event EventHandler? BrokenStateChanged; public event EventHandler? BrokenStateChanged;
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a model that can have a broken state
/// </summary>
public interface IBreakableModel
{ {
/// <summary>
/// Represents a model that can have a broken state
/// </summary>
public interface IBreakableModel
{
/// <summary> /// <summary>
/// Gets the display name of this breakable model /// Gets the display name of this breakable model
/// </summary> /// </summary>
@ -55,5 +55,4 @@ namespace Artemis.Core
/// Occurs when the broken state of this model changes /// Occurs when the broken state of this model changes
/// </summary> /// </summary>
event EventHandler BrokenStateChanged; event EventHandler BrokenStateChanged;
}
} }

View File

@ -1,10 +1,10 @@
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a model that can be loaded and saved to persistent storage
/// </summary>
public interface IStorageModel
{ {
/// <summary>
/// Represents a model that can be loaded and saved to persistent storage
/// </summary>
public interface IStorageModel
{
/// <summary> /// <summary>
/// Loads the model from its associated entity /// Loads the model from its associated entity
/// </summary> /// </summary>
@ -14,5 +14,4 @@
/// Saves the model to its associated entity /// Saves the model to its associated entity
/// </summary> /// </summary>
void Save(); void Save();
}
} }

View File

@ -1,14 +1,13 @@
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a model that updates using a delta time
/// </summary>
public interface IUpdateModel
{ {
/// <summary>
/// Represents a model that updates using a delta time
/// </summary>
public interface IUpdateModel
{
/// <summary> /// <summary>
/// Performs an update on the model /// Performs an update on the model
/// </summary> /// </summary>
/// <param name="timeline">The timeline to apply during update</param> /// <param name="timeline">The timeline to apply during update</param>
void Update(Timeline timeline); void Update(Timeline timeline);
}
} }

View File

@ -2,17 +2,17 @@
using System.Linq; using System.Linq;
using Artemis.Storage.Entities.Profile.AdaptionHints; using Artemis.Storage.Entities.Profile.AdaptionHints;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a hint that adapts layers to a certain category of devices
/// </summary>
public class CategoryAdaptionHint : CorePropertyChanged, IAdaptionHint
{ {
/// <summary>
/// Represents a hint that adapts layers to a certain category of devices
/// </summary>
public class CategoryAdaptionHint : CorePropertyChanged, IAdaptionHint
{
private DeviceCategory _category;
private int _skip;
private bool _limitAmount;
private int _amount; private int _amount;
private DeviceCategory _category;
private bool _limitAmount;
private int _skip;
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="CategoryAdaptionHint" /> class /// Creates a new instance of the <see cref="CategoryAdaptionHint" /> class
@ -95,5 +95,4 @@ namespace Artemis.Core
} }
#endregion #endregion
}
} }

View File

@ -3,17 +3,17 @@ using System.Linq;
using Artemis.Storage.Entities.Profile.AdaptionHints; using Artemis.Storage.Entities.Profile.AdaptionHints;
using RGB.NET.Core; using RGB.NET.Core;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a hint that adapts layers to a certain type of devices
/// </summary>
public class DeviceAdaptionHint : CorePropertyChanged, IAdaptionHint
{ {
/// <summary>
/// Represents a hint that adapts layers to a certain type of devices
/// </summary>
public class DeviceAdaptionHint : CorePropertyChanged, IAdaptionHint
{
private RGBDeviceType _deviceType;
private int _skip;
private bool _limitAmount;
private int _amount; private int _amount;
private RGBDeviceType _deviceType;
private bool _limitAmount;
private int _skip;
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="DeviceAdaptionHint" /> class /// Creates a new instance of the <see cref="DeviceAdaptionHint" /> class
@ -96,5 +96,4 @@ namespace Artemis.Core
} }
#endregion #endregion
}
} }

View File

@ -1,13 +1,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using Artemis.Storage.Entities.Profile.AdaptionHints; using Artemis.Storage.Entities.Profile.AdaptionHints;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents an adaption hint that's used to adapt a layer to a set of devices
/// </summary>
public interface IAdaptionHint
{ {
/// <summary>
/// Represents an adaption hint that's used to adapt a layer to a set of devices
/// </summary>
public interface IAdaptionHint
{
/// <summary> /// <summary>
/// Applies the adaptive action to the provided layer /// Applies the adaptive action to the provided layer
/// </summary> /// </summary>
@ -19,5 +19,4 @@ namespace Artemis.Core
/// Returns an adaption hint entry for this adaption hint used for persistent storage /// Returns an adaption hint entry for this adaption hint used for persistent storage
/// </summary> /// </summary>
IAdaptionHintEntity GetEntry(); IAdaptionHintEntity GetEntry();
}
} }

View File

@ -4,13 +4,13 @@ using System.Linq;
using Artemis.Storage.Entities.Profile.AdaptionHints; using Artemis.Storage.Entities.Profile.AdaptionHints;
using RGB.NET.Core; using RGB.NET.Core;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a hint that adapts layers to a certain region of keyboards
/// </summary>
public class KeyboardSectionAdaptionHint : CorePropertyChanged, IAdaptionHint
{ {
/// <summary>
/// Represents a hint that adapts layers to a certain region of keyboards
/// </summary>
public class KeyboardSectionAdaptionHint : CorePropertyChanged, IAdaptionHint
{
private static readonly Dictionary<KeyboardSection, List<LedId>> RegionLedIds = new() private static readonly Dictionary<KeyboardSection, List<LedId>> RegionLedIds = new()
{ {
{KeyboardSection.MacroKeys, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_Programmable1 && l <= LedId.Keyboard_Programmable32).ToList()}, {KeyboardSection.MacroKeys, Enum.GetValues<LedId>().Where(l => l >= LedId.Keyboard_Programmable1 && l <= LedId.Keyboard_Programmable32).ToList()},
@ -67,13 +67,13 @@ namespace Artemis.Core
} }
#endregion #endregion
} }
/// <summary> /// <summary>
/// Represents a section of LEDs on a keyboard /// Represents a section of LEDs on a keyboard
/// </summary> /// </summary>
public enum KeyboardSection public enum KeyboardSection
{ {
/// <summary> /// <summary>
/// A region containing the macro keys of a keyboard /// A region containing the macro keys of a keyboard
/// </summary> /// </summary>
@ -88,5 +88,4 @@ namespace Artemis.Core
/// A region containing extra non-standard LEDs of a keyboard /// A region containing extra non-standard LEDs of a keyboard
/// </summary> /// </summary>
Extra Extra
}
} }

View File

@ -83,14 +83,10 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
{ {
List<SKColor> result = new(); List<SKColor> result = new();
if (timesToRepeat == 0) if (timesToRepeat == 0)
{
result = this.Select(c => c.Color).ToList(); result = this.Select(c => c.Color).ToList();
}
else else
{
for (int i = 0; i <= timesToRepeat; i++) for (int i = 0; i <= timesToRepeat; i++)
result.AddRange(this.Select(c => c.Color)); result.AddRange(this.Select(c => c.Color));
}
if (seamless && !IsSeamless()) if (seamless && !IsSeamless())
result.Add(result[0]); result.Add(result[0]);
@ -413,8 +409,10 @@ public class ColorGradient : IList<ColorGradientStop>, IList, INotifyCollectionC
return false; return false;
for (int i = 0; i < Count; i++) for (int i = 0; i < Count; i++)
{
if (!Equals(this[i], other[i])) if (!Equals(this[i], other[i]))
return false; return false;
}
return true; return true;
} }

View File

@ -1,41 +1,13 @@
using System; using System;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A color with a position, usually contained in a <see cref="ColorGradient" />
/// </summary>
public class ColorGradientStop : CorePropertyChanged
{ {
/// <summary>
/// A color with a position, usually contained in a <see cref="ColorGradient" />
/// </summary>
public class ColorGradientStop : CorePropertyChanged
{
#region Equality members
/// <inheritdoc cref="object.Equals(object)" />
protected bool Equals(ColorGradientStop other)
{
return _color.Equals(other._color) && _position.Equals(other._position);
}
/// <inheritdoc />
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
if (obj.GetType() != GetType())
return false;
return Equals((ColorGradientStop) obj);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(_color, _position);
}
#endregion
private SKColor _color; private SKColor _color;
private float _position; private float _position;
@ -65,5 +37,32 @@ namespace Artemis.Core
get => _position; get => _position;
set => SetAndNotify(ref _position, value); set => SetAndNotify(ref _position, value);
} }
#region Equality members
/// <inheritdoc cref="object.Equals(object)" />
protected bool Equals(ColorGradientStop other)
{
return _color.Equals(other._color) && _position.Equals(other._position);
} }
/// <inheritdoc />
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
if (obj.GetType() != GetType())
return false;
return Equals((ColorGradientStop) obj);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(_color, _position);
}
#endregion
} }

View File

@ -2,13 +2,13 @@
using Artemis.Storage.Entities.Profile.Abstract; using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions; using Artemis.Storage.Entities.Profile.Conditions;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a condition that is always true.
/// </summary>
public class AlwaysOnCondition : ICondition
{ {
/// <summary>
/// Represents a condition that is always true.
/// </summary>
public class AlwaysOnCondition : ICondition
{
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="AlwaysOnCondition" /> class. /// Creates a new instance of the <see cref="AlwaysOnCondition" /> class.
/// </summary> /// </summary>
@ -30,15 +30,11 @@ namespace Artemis.Core
Entity = alwaysOnConditionEntity; Entity = alwaysOnConditionEntity;
} }
#region Implementation of IDisposable
/// <inheritdoc /> /// <inheritdoc />
public void Dispose() public void Dispose()
{ {
} }
#endregion
#region Implementation of IStorageModel #region Implementation of IStorageModel
/// <inheritdoc /> /// <inheritdoc />
@ -86,5 +82,4 @@ namespace Artemis.Core
} }
#endregion #endregion
}
} }

View File

@ -14,15 +14,15 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
{ {
private readonly string _displayName; private readonly string _displayName;
private readonly EventConditionEntity _entity; private readonly EventConditionEntity _entity;
private IEventConditionNode _startNode;
private DataModelPath? _eventPath; private DataModelPath? _eventPath;
private NodeScript<bool> _script;
private bool _wasMet;
private DateTime _lastProcessedTrigger; private DateTime _lastProcessedTrigger;
private object? _lastProcessedValue; private object? _lastProcessedValue;
private EventOverlapMode _overlapMode; private EventOverlapMode _overlapMode;
private EventTriggerMode _triggerMode; private NodeScript<bool> _script;
private IEventConditionNode _startNode;
private EventToggleOffMode _toggleOffMode; private EventToggleOffMode _toggleOffMode;
private EventTriggerMode _triggerMode;
private bool _wasMet;
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="EventCondition" /> class /// Creates a new instance of the <see cref="EventCondition" /> class
@ -87,7 +87,8 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
} }
/// <summary> /// <summary>
/// Gets or sets the mode for render elements when toggling off the event when using <see cref="EventTriggerMode.Toggle"/>. /// Gets or sets the mode for render elements when toggling off the event when using
/// <see cref="EventTriggerMode.Toggle" />.
/// </summary> /// </summary>
public EventToggleOffMode ToggleOffMode public EventToggleOffMode ToggleOffMode
{ {
@ -119,7 +120,9 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
_startNode = eventNode; _startNode = eventNode;
} }
else else
{
eventNode = node; eventNode = node;
}
IDataModelEvent? dataModelEvent = EventPath?.GetValue() as IDataModelEvent; IDataModelEvent? dataModelEvent = EventPath?.GetValue() as IDataModelEvent;
eventNode.CreatePins(dataModelEvent); eventNode.CreatePins(dataModelEvent);
@ -136,13 +139,25 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
ReplaceStartNode(valueChangedNode); ReplaceStartNode(valueChangedNode);
} }
else else
{
valueChangedNode = node; valueChangedNode = node;
}
valueChangedNode.UpdateOutputPins(EventPath); valueChangedNode.UpdateOutputPins(EventPath);
} }
Script.Save(); Script.Save();
} }
/// <summary>
/// Gets the start node of the event script, if any
/// </summary>
/// <returns>The start node of the event script, if any.</returns>
public INode GetStartNode()
{
return _startNode;
}
private void ReplaceStartNode(IEventConditionNode newStartNode) private void ReplaceStartNode(IEventConditionNode newStartNode)
{ {
if (Script.Nodes.Contains(_startNode)) if (Script.Nodes.Contains(_startNode))
@ -153,15 +168,6 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
Script.AddNode(_startNode); Script.AddNode(_startNode);
} }
/// <summary>
/// Gets the start node of the event script, if any
/// </summary>
/// <returns>The start node of the event script, if any.</returns>
public INode GetStartNode()
{
return _startNode;
}
private bool Evaluate() private bool Evaluate()
{ {
if (EventPath == null) if (EventPath == null)
@ -356,7 +362,8 @@ public enum EventOverlapMode
} }
/// <summary> /// <summary>
/// Represents a mode for render elements when toggling off the event when using <see cref="EventTriggerMode.Toggle"/>. /// Represents a mode for render elements when toggling off the event when using <see cref="EventTriggerMode.Toggle" />
/// .
/// </summary> /// </summary>
public enum EventToggleOffMode public enum EventToggleOffMode
{ {

View File

@ -35,7 +35,7 @@ public interface ICondition : IDisposable, IStorageModel
void UpdateTimeline(double deltaTime); void UpdateTimeline(double deltaTime);
/// <summary> /// <summary>
/// Overrides the timeline to the provided <paramref name="position"/> as the display condition sees fit. /// Overrides the timeline to the provided <paramref name="position" /> as the display condition sees fit.
/// </summary> /// </summary>
void OverrideTimeline(TimeSpan position); void OverrideTimeline(TimeSpan position);
} }

View File

@ -2,13 +2,13 @@
using Artemis.Storage.Entities.Profile.Abstract; using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions; using Artemis.Storage.Entities.Profile.Conditions;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a condition that plays once when its script evaluates to <see langword="true" />.
/// </summary>
public class PlayOnceCondition : ICondition
{ {
/// <summary>
/// Represents a condition that plays once when its script evaluates to <see langword="true"/>.
/// </summary>
public class PlayOnceCondition : ICondition
{
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="PlayOnceCondition" /> class. /// Creates a new instance of the <see cref="PlayOnceCondition" /> class.
/// </summary> /// </summary>
@ -30,15 +30,11 @@ namespace Artemis.Core
Entity = entity; Entity = entity;
} }
#region Implementation of IDisposable
/// <inheritdoc /> /// <inheritdoc />
public void Dispose() public void Dispose()
{ {
} }
#endregion
#region Implementation of IStorageModel #region Implementation of IStorageModel
/// <inheritdoc /> /// <inheritdoc />
@ -86,5 +82,4 @@ namespace Artemis.Core
} }
#endregion #endregion
}
} }

View File

@ -3,13 +3,13 @@ using System.Linq;
using Artemis.Storage.Entities.Profile.Abstract; using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions; using Artemis.Storage.Entities.Profile.Conditions;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a condition that is based on a data model value
/// </summary>
public class StaticCondition : CorePropertyChanged, INodeScriptCondition
{ {
/// <summary>
/// Represents a condition that is based on a data model value
/// </summary>
public class StaticCondition : CorePropertyChanged, INodeScriptCondition
{
private readonly string _displayName; private readonly string _displayName;
private readonly StaticConditionEntity _entity; private readonly StaticConditionEntity _entity;
private StaticPlayMode _playMode; private StaticPlayMode _playMode;
@ -44,15 +44,6 @@ namespace Artemis.Core
/// </summary> /// </summary>
public NodeScript<bool> Script { get; private set; } public NodeScript<bool> Script { get; private set; }
/// <inheritdoc />
public IConditionEntity Entity => _entity;
/// <inheritdoc />
public RenderProfileElement ProfileElement { get; }
/// <inheritdoc />
public bool IsMet { get; private set; }
/// <summary> /// <summary>
/// Gets or sets the mode in which the render element starts its timeline when display conditions are met /// Gets or sets the mode in which the render element starts its timeline when display conditions are met
/// </summary> /// </summary>
@ -71,6 +62,15 @@ namespace Artemis.Core
set => SetAndNotify(ref _stopMode, value); set => SetAndNotify(ref _stopMode, value);
} }
/// <inheritdoc />
public IConditionEntity Entity => _entity;
/// <inheritdoc />
public RenderProfileElement ProfileElement { get; }
/// <inheritdoc />
public bool IsMet { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public void Update() public void Update()
{ {
@ -85,7 +85,9 @@ namespace Artemis.Core
} }
if (!Script.ExitNodeConnected) if (!Script.ExitNodeConnected)
{
IsMet = true; IsMet = true;
}
else else
{ {
Script.Run(); Script.Run();
@ -157,13 +159,13 @@ namespace Artemis.Core
} }
#endregion #endregion
} }
/// <summary> /// <summary>
/// Represents a mode for render elements to start their timeline when display conditions are met /// Represents a mode for render elements to start their timeline when display conditions are met
/// </summary> /// </summary>
public enum StaticPlayMode public enum StaticPlayMode
{ {
/// <summary> /// <summary>
/// Continue repeating the main segment of the timeline while the condition is met /// Continue repeating the main segment of the timeline while the condition is met
/// </summary> /// </summary>
@ -173,13 +175,13 @@ namespace Artemis.Core
/// Only play the timeline once when the condition is met /// Only play the timeline once when the condition is met
/// </summary> /// </summary>
Once Once
} }
/// <summary> /// <summary>
/// Represents a mode for render elements to stop their timeline when display conditions are no longer met /// Represents a mode for render elements to stop their timeline when display conditions are no longer met
/// </summary> /// </summary>
public enum StaticStopMode public enum StaticStopMode
{ {
/// <summary> /// <summary>
/// When conditions are no longer met, finish the the current run of the main timeline /// When conditions are no longer met, finish the the current run of the main timeline
/// </summary> /// </summary>
@ -189,5 +191,4 @@ namespace Artemis.Core
/// When conditions are no longer met, skip to the end segment of the timeline /// When conditions are no longer met, skip to the end segment of the timeline
/// </summary> /// </summary>
SkipToEnd SkipToEnd
}
} }

View File

@ -4,11 +4,11 @@ using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using Artemis.Storage.Entities.Profile.DataBindings; using Artemis.Storage.Entities.Profile.DataBindings;
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class DataBinding<TLayerProperty> : IDataBinding
{ {
/// <inheritdoc />
public class DataBinding<TLayerProperty> : IDataBinding
{
private readonly List<IDataBindingProperty> _properties = new(); private readonly List<IDataBindingProperty> _properties = new();
private bool _disposed; private bool _disposed;
private bool _isEnabled; private bool _isEnabled;
@ -40,9 +40,6 @@ namespace Artemis.Core
/// </summary> /// </summary>
public LayerProperty<TLayerProperty> LayerProperty { get; } public LayerProperty<TLayerProperty> LayerProperty { get; }
/// <inheritdoc />
public INodeScript Script => _script;
/// <summary> /// <summary>
/// Gets the data binding entity this data binding uses for persistent storage /// Gets the data binding entity this data binding uses for persistent storage
/// </summary> /// </summary>
@ -152,6 +149,9 @@ namespace Artemis.Core
return LayerProperty.PropertyDescription.Name ?? LayerProperty.Path; return LayerProperty.PropertyDescription.Name ?? LayerProperty.Path;
} }
/// <inheritdoc />
public INodeScript Script => _script;
/// <inheritdoc /> /// <inheritdoc />
public ILayerProperty BaseLayerProperty => LayerProperty; public ILayerProperty BaseLayerProperty => LayerProperty;
@ -237,9 +237,10 @@ namespace Artemis.Core
Entity.NodeScript = _script.Entity; Entity.NodeScript = _script.Entity;
} }
else else
{
Entity.NodeScript = null; Entity.NodeScript = null;
} }
}
#endregion #endregion
}
} }

View File

@ -1,10 +1,10 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <inheritdoc />
public class DataBindingProperty<TProperty> : IDataBindingProperty
{ {
/// <inheritdoc />
public class DataBindingProperty<TProperty> : IDataBindingProperty
{
internal DataBindingProperty(Func<TProperty> getter, Action<TProperty?> setter, string displayName) internal DataBindingProperty(Func<TProperty> getter, Action<TProperty?> setter, string displayName)
{ {
Getter = getter ?? throw new ArgumentNullException(nameof(getter)); Getter = getter ?? throw new ArgumentNullException(nameof(getter));
@ -59,5 +59,4 @@ namespace Artemis.Core
throw new ArgumentException("Value must match the type of the data binding registration", nameof(value)); throw new ArgumentException("Value must match the type of the data binding registration", nameof(value));
} }
} }
}
} }

View File

@ -2,14 +2,14 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Artemis.Core.Modules; using Artemis.Core.Modules;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a data binding that binds a certain <see cref="LayerProperty{T}" /> to a value inside a
/// <see cref="DataModel" />
/// </summary>
public interface IDataBinding : IStorageModel, IDisposable
{ {
/// <summary>
/// Represents a data binding that binds a certain <see cref="LayerProperty{T}" /> to a value inside a
/// <see cref="DataModel" />
/// </summary>
public interface IDataBinding : IStorageModel, IDisposable
{
/// <summary> /// <summary>
/// Gets the layer property the data binding is applied to /// Gets the layer property the data binding is applied to
/// </summary> /// </summary>
@ -59,5 +59,4 @@ namespace Artemis.Core
/// Occurs when a data binding has been disabled /// Occurs when a data binding has been disabled
/// </summary> /// </summary>
public event EventHandler<DataBindingEventArgs>? DataBindingDisabled; public event EventHandler<DataBindingEventArgs>? DataBindingDisabled;
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a data binding registration
/// </summary>
public interface IDataBindingProperty
{ {
/// <summary>
/// Represents a data binding registration
/// </summary>
public interface IDataBindingProperty
{
/// <summary> /// <summary>
/// Gets or sets the display name of the data binding registration /// Gets or sets the display name of the data binding registration
/// </summary> /// </summary>
@ -28,5 +28,4 @@ namespace Artemis.Core
/// </summary> /// </summary>
/// <param name="value">A value matching the type of <see cref="ValueType" /></param> /// <param name="value">A value matching the type of <see cref="ValueType" /></param>
void SetValue(object? value); void SetValue(object? value);
}
} }

View File

@ -3,13 +3,13 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Artemis.Core.Modules; using Artemis.Core.Modules;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a data model event with event arguments of type <typeparamref name="T" />
/// </summary>
public class DataModelEvent<T> : IDataModelEvent where T : DataModelEventArgs
{ {
/// <summary>
/// Represents a data model event with event arguments of type <typeparamref name="T" />
/// </summary>
public class DataModelEvent<T> : IDataModelEvent where T : DataModelEventArgs
{
private bool _trackHistory; private bool _trackHistory;
/// <summary> /// <summary>
@ -28,24 +28,12 @@ namespace Artemis.Core
_trackHistory = trackHistory; _trackHistory = trackHistory;
} }
/// <inheritdoc />
[DataModelProperty(Name = "Last trigger", Description = "The time at which the event last triggered")]
public DateTime LastTrigger { get; private set; }
/// <inheritdoc />
[DataModelProperty(Name = "Time since trigger", Description = "The time that has passed since the last trigger")]
public TimeSpan TimeSinceLastTrigger => DateTime.Now - LastTrigger;
/// <summary> /// <summary>
/// Gets the event arguments of the last time the event was triggered /// Gets the event arguments of the last time the event was triggered
/// </summary> /// </summary>
[DataModelProperty(Description = "The arguments of the last time this event triggered")] [DataModelProperty(Description = "The arguments of the last time this event triggered")]
public T? LastEventArguments { get; private set; } public T? LastEventArguments { get; private set; }
/// <inheritdoc />
[DataModelProperty(Description = "The total amount of times this event has triggered since the module was activated")]
public int TriggerCount { get; private set; }
/// <summary> /// <summary>
/// Gets a queue of the last 20 event arguments /// Gets a queue of the last 20 event arguments
/// <para>Always empty if <see cref="TrackHistory" /> is <see langword="false" /></para> /// <para>Always empty if <see cref="TrackHistory" /> is <see langword="false" /></para>
@ -67,14 +55,12 @@ namespace Artemis.Core
TriggerCount++; TriggerCount++;
if (TrackHistory) if (TrackHistory)
{
lock (EventArgumentsHistory) lock (EventArgumentsHistory)
{ {
if (EventArgumentsHistory.Count == 20) if (EventArgumentsHistory.Count == 20)
EventArgumentsHistory.Dequeue(); EventArgumentsHistory.Dequeue();
EventArgumentsHistory.Enqueue(eventArgs); EventArgumentsHistory.Enqueue(eventArgs);
} }
}
OnEventTriggered(); OnEventTriggered();
} }
@ -84,6 +70,18 @@ namespace Artemis.Core
EventTriggered?.Invoke(this, EventArgs.Empty); EventTriggered?.Invoke(this, EventArgs.Empty);
} }
/// <inheritdoc />
[DataModelProperty(Name = "Last trigger", Description = "The time at which the event last triggered")]
public DateTime LastTrigger { get; private set; }
/// <inheritdoc />
[DataModelProperty(Name = "Time since trigger", Description = "The time that has passed since the last trigger")]
public TimeSpan TimeSinceLastTrigger => DateTime.Now - LastTrigger;
/// <inheritdoc />
[DataModelProperty(Description = "The total amount of times this event has triggered since the module was activated")]
public int TriggerCount { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
[DataModelIgnore] [DataModelIgnore]
public Type ArgumentsType => typeof(T); public Type ArgumentsType => typeof(T);
@ -126,13 +124,13 @@ namespace Artemis.Core
public void Update() public void Update()
{ {
} }
} }
/// <summary> /// <summary>
/// Represents a data model event without event arguments /// Represents a data model event without event arguments
/// </summary> /// </summary>
public class DataModelEvent : IDataModelEvent public class DataModelEvent : IDataModelEvent
{ {
private bool _trackHistory; private bool _trackHistory;
/// <summary> /// <summary>
@ -151,24 +149,12 @@ namespace Artemis.Core
_trackHistory = trackHistory; _trackHistory = trackHistory;
} }
/// <inheritdoc />
[DataModelProperty(Name = "Last trigger", Description = "The time at which the event last triggered")]
public DateTime LastTrigger { get; private set; }
/// <inheritdoc />
[DataModelProperty(Name = "Time since trigger", Description = "The time that has passed since the last trigger")]
public TimeSpan TimeSinceLastTrigger => DateTime.Now - LastTrigger;
/// <summary> /// <summary>
/// Gets the event arguments of the last time the event was triggered /// Gets the event arguments of the last time the event was triggered
/// </summary> /// </summary>
[DataModelProperty(Description = "The arguments of the last time this event triggered")] [DataModelProperty(Description = "The arguments of the last time this event triggered")]
public DataModelEventArgs? LastTriggerArguments { get; private set; } public DataModelEventArgs? LastTriggerArguments { get; private set; }
/// <inheritdoc />
[DataModelProperty(Description = "The total amount of times this event has triggered since the module was activated")]
public int TriggerCount { get; private set; }
/// <summary> /// <summary>
/// Gets a queue of the last 20 event arguments /// Gets a queue of the last 20 event arguments
/// <para>Always empty if <see cref="TrackHistory" /> is <see langword="false" /></para> /// <para>Always empty if <see cref="TrackHistory" /> is <see langword="false" /></para>
@ -188,14 +174,12 @@ namespace Artemis.Core
TriggerCount++; TriggerCount++;
if (TrackHistory) if (TrackHistory)
{
lock (EventArgumentsHistory) lock (EventArgumentsHistory)
{ {
if (EventArgumentsHistory.Count == 20) if (EventArgumentsHistory.Count == 20)
EventArgumentsHistory.Dequeue(); EventArgumentsHistory.Dequeue();
EventArgumentsHistory.Enqueue(eventArgs); EventArgumentsHistory.Enqueue(eventArgs);
} }
}
OnEventTriggered(); OnEventTriggered();
} }
@ -205,6 +189,18 @@ namespace Artemis.Core
EventTriggered?.Invoke(this, EventArgs.Empty); EventTriggered?.Invoke(this, EventArgs.Empty);
} }
/// <inheritdoc />
[DataModelProperty(Name = "Last trigger", Description = "The time at which the event last triggered")]
public DateTime LastTrigger { get; private set; }
/// <inheritdoc />
[DataModelProperty(Name = "Time since trigger", Description = "The time that has passed since the last trigger")]
public TimeSpan TimeSinceLastTrigger => DateTime.Now - LastTrigger;
/// <inheritdoc />
[DataModelProperty(Description = "The total amount of times this event has triggered since the module was activated")]
public int TriggerCount { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
[DataModelIgnore] [DataModelIgnore]
public Type ArgumentsType => typeof(DataModelEventArgs); public Type ArgumentsType => typeof(DataModelEventArgs);
@ -247,5 +243,4 @@ namespace Artemis.Core
public void Update() public void Update()
{ {
} }
}
} }

View File

@ -1,17 +1,16 @@
using System; using System;
using Artemis.Core.Modules; using Artemis.Core.Modules;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents the base class for data model events that contain event data
/// </summary>
public class DataModelEventArgs
{ {
/// <summary>
/// Represents the base class for data model events that contain event data
/// </summary>
public class DataModelEventArgs
{
/// <summary> /// <summary>
/// Gets the time at which the event with these arguments was triggered /// Gets the time at which the event with these arguments was triggered
/// </summary> /// </summary>
[DataModelIgnore] [DataModelIgnore]
public DateTime TriggerTime { get; internal set; } public DateTime TriggerTime { get; internal set; }
}
} }

View File

@ -6,13 +6,13 @@ using System.Reflection;
using Artemis.Core.Modules; using Artemis.Core.Modules;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a path that points to a property in data model
/// </summary>
public class DataModelPath : IStorageModel, IDisposable
{ {
/// <summary>
/// Represents a path that points to a property in data model
/// </summary>
public class DataModelPath : IStorageModel, IDisposable
{
private readonly LinkedList<DataModelPathSegment> _segments; private readonly LinkedList<DataModelPathSegment> _segments;
private Expression<Func<object, object>>? _accessorLambda; private Expression<Func<object, object>>? _accessorLambda;
private bool _disposed; private bool _disposed;
@ -365,7 +365,8 @@ namespace Artemis.Core
#region Equality members #region Equality members
/// <inheritdoc cref="Equals(object)"/>> /// <inheritdoc cref="Equals(object)" />
/// >
protected bool Equals(DataModelPath other) protected bool Equals(DataModelPath other)
{ {
return ReferenceEquals(Target, other.Target) && Path == other.Path; return ReferenceEquals(Target, other.Target) && Path == other.Path;
@ -389,5 +390,4 @@ namespace Artemis.Core
#endregion #endregion
#endregion #endregion
}
} }

View File

@ -6,17 +6,17 @@ using System.Reflection;
using Artemis.Core.Modules; using Artemis.Core.Modules;
using Humanizer; using Humanizer;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a segment of a data model path
/// </summary>
public class DataModelPathSegment : IDisposable
{ {
/// <summary>
/// Represents a segment of a data model path
/// </summary>
public class DataModelPathSegment : IDisposable
{
private Expression<Func<object, object>>? _accessorLambda; private Expression<Func<object, object>>? _accessorLambda;
private DataModel? _dynamicDataModel; private DataModel? _dynamicDataModel;
private Type? _dynamicDataModelType;
private DataModelPropertyAttribute? _dynamicDataModelAttribute; private DataModelPropertyAttribute? _dynamicDataModelAttribute;
private Type? _dynamicDataModelType;
private PropertyInfo? _property; private PropertyInfo? _property;
internal DataModelPathSegment(DataModelPath dataModelPath, string identifier, string path) internal DataModelPathSegment(DataModelPath dataModelPath, string identifier, string path)
@ -157,6 +157,30 @@ namespace Artemis.Core
return type; return type;
} }
/// <summary>
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">
/// <see langword="true" /> to release both managed and unmanaged resources;
/// <see langword="false" /> to release only unmanaged resources.
/// </param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_dynamicDataModel != null)
{
_dynamicDataModel.DynamicChildAdded -= DynamicChildOnDynamicChildAdded;
_dynamicDataModel.DynamicChildRemoved -= DynamicChildOnDynamicChildRemoved;
}
Type = DataModelPathSegmentType.Invalid;
_accessorLambda = null;
Accessor = null;
}
}
internal Expression? Initialize(ParameterExpression parameter, Expression expression, Expression nullCondition) internal Expression? Initialize(ParameterExpression parameter, Expression expression, Expression nullCondition)
{ {
if (IsStartSegment) if (IsStartSegment)
@ -210,21 +234,17 @@ namespace Artemis.Core
accessorExpression = expression; accessorExpression = expression;
// A static segment just needs to access the property or filed // A static segment just needs to access the property or filed
else if (Type == DataModelPathSegmentType.Static) else if (Type == DataModelPathSegmentType.Static)
{
accessorExpression = _property != null accessorExpression = _property != null
? Expression.Property(expression, _property) ? Expression.Property(expression, _property)
: Expression.PropertyOrField(expression, Identifier); : Expression.PropertyOrField(expression, Identifier);
}
// A dynamic segment calls the generic method DataModel.DynamicChild<T> and provides the identifier as an argument // A dynamic segment calls the generic method DataModel.DynamicChild<T> and provides the identifier as an argument
else else
{
accessorExpression = Expression.Call( accessorExpression = Expression.Call(
expression, expression,
nameof(DataModel.GetDynamicChildValue), nameof(DataModel.GetDynamicChildValue),
_dynamicDataModelType != null ? new[] {_dynamicDataModelType} : null, _dynamicDataModelType != null ? new[] {_dynamicDataModelType} : null,
Expression.Constant(Identifier) Expression.Constant(Identifier)
); );
}
_accessorLambda = Expression.Lambda<Func<object, object>>( _accessorLambda = Expression.Lambda<Func<object, object>>(
// Wrap with a null check // Wrap with a null check
@ -255,43 +275,6 @@ namespace Artemis.Core
Type = _property == null ? DataModelPathSegmentType.Invalid : DataModelPathSegmentType.Static; Type = _property == null ? DataModelPathSegmentType.Invalid : DataModelPathSegmentType.Static;
} }
#region IDisposable
/// <summary>
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">
/// <see langword="true" /> to release both managed and unmanaged resources;
/// <see langword="false" /> to release only unmanaged resources.
/// </param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_dynamicDataModel != null)
{
_dynamicDataModel.DynamicChildAdded -= DynamicChildOnDynamicChildAdded;
_dynamicDataModel.DynamicChildRemoved -= DynamicChildOnDynamicChildRemoved;
}
Type = DataModelPathSegmentType.Invalid;
_accessorLambda = null;
Accessor = null;
}
}
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#region Event handlers
private void DynamicChildOnDynamicChildAdded(object? sender, DynamicDataModelChildEventArgs e) private void DynamicChildOnDynamicChildAdded(object? sender, DynamicDataModelChildEventArgs e)
{ {
if (e.Key == Identifier) if (e.Key == Identifier)
@ -307,6 +290,10 @@ namespace Artemis.Core
DataModelPath.Invalidate(); DataModelPath.Invalidate();
} }
#endregion /// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} }
} }

View File

@ -1,10 +1,10 @@
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a type of data model path
/// </summary>
public enum DataModelPathSegmentType
{ {
/// <summary>
/// Represents a type of data model path
/// </summary>
public enum DataModelPathSegmentType
{
/// <summary> /// <summary>
/// Represents an invalid data model type that points to a missing data model /// Represents an invalid data model type that points to a missing data model
/// </summary> /// </summary>
@ -19,5 +19,4 @@
/// Represents a static data model type that points to a data model defined at runtime /// Represents a static data model type that points to a data model defined at runtime
/// </summary> /// </summary>
Dynamic Dynamic
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents an event that is part of a data model
/// </summary>
public interface IDataModelEvent
{ {
/// <summary>
/// Represents an event that is part of a data model
/// </summary>
public interface IDataModelEvent
{
/// <summary> /// <summary>
/// Gets the last time the event was triggered /// Gets the last time the event was triggered
/// </summary> /// </summary>
@ -65,5 +65,4 @@ namespace Artemis.Core
/// tick /// tick
/// </summary> /// </summary>
void Update(); void Update();
}
} }

View File

@ -1,19 +1,18 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using Artemis.Core.LayerEffects; using Artemis.Core.LayerEffects;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Entities.Profile.Abstract; using Artemis.Storage.Entities.Profile.Abstract;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a folder in a <see cref="Profile" />
/// </summary>
public sealed class Folder : RenderProfileElement
{ {
/// <summary>
/// Represents a folder in a <see cref="Profile" />
/// </summary>
public sealed class Folder : RenderProfileElement
{
private bool _isExpanded; private bool _isExpanded;
/// <summary> /// <summary>
@ -264,7 +263,8 @@ namespace Artemis.Core
{ {
DisplayCondition.OverrideTimeline(position); DisplayCondition.OverrideTimeline(position);
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => !e.Suspended)) foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => !e.Suspended))
baseLayerEffect.InternalUpdate(Timeline); ; baseLayerEffect.InternalUpdate(Timeline);
;
} }
/// <summary> /// <summary>
@ -272,6 +272,16 @@ namespace Artemis.Core
/// </summary> /// </summary>
public event EventHandler? RenderPropertiesUpdated; public event EventHandler? RenderPropertiesUpdated;
#region Overrides of BreakableModel
/// <inheritdoc />
public override IEnumerable<IBreakableModel> GetBrokenHierarchy()
{
return LayerEffects.Where(e => e.BrokenState != null);
}
#endregion
/// <inheritdoc /> /// <inheritdoc />
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
@ -346,15 +356,4 @@ namespace Artemis.Core
{ {
RenderPropertiesUpdated?.Invoke(this, EventArgs.Empty); RenderPropertiesUpdated?.Invoke(this, EventArgs.Empty);
} }
#region Overrides of BreakableModel
/// <inheritdoc />
public override IEnumerable<IBreakableModel> GetBrokenHierarchy()
{
return LayerEffects.Where(e => e.BrokenState != null);
}
#endregion
}
} }

View File

@ -9,13 +9,13 @@ using Artemis.Storage.Entities.Profile.Abstract;
using RGB.NET.Core; using RGB.NET.Core;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a layer in a <see cref="Profile" />
/// </summary>
public sealed class Layer : RenderProfileElement
{ {
/// <summary>
/// Represents a layer in a <see cref="Profile" />
/// </summary>
public sealed class Layer : RenderProfileElement
{
private readonly List<Layer> _renderCopies; private readonly List<Layer> _renderCopies;
private LayerGeneralProperties _general; private LayerGeneralProperties _general;
private BaseLayerBrush? _layerBrush; private BaseLayerBrush? _layerBrush;
@ -78,7 +78,7 @@ namespace Artemis.Core
} }
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="Layer" /> class by copying the provided <paramref name="source"/>. /// Creates a new instance of the <see cref="Layer" /> class by copying the provided <paramref name="source" />.
/// </summary> /// </summary>
/// <param name="source">The layer to copy</param> /// <param name="source">The layer to copy</param>
private Layer(Layer source) : base(source, source.Profile) private Layer(Layer source) : base(source, source.Profile)
@ -180,8 +180,10 @@ namespace Artemis.Core
if (LayerBrush?.BaseProperties != null) if (LayerBrush?.BaseProperties != null)
result.AddRange(LayerBrush.BaseProperties.GetAllLayerProperties()); result.AddRange(LayerBrush.BaseProperties.GetAllLayerProperties());
foreach (BaseLayerEffect layerEffect in LayerEffects) foreach (BaseLayerEffect layerEffect in LayerEffects)
{
if (layerEffect.BaseProperties != null) if (layerEffect.BaseProperties != null)
result.AddRange(layerEffect.BaseProperties.GetAllLayerProperties()); result.AddRange(layerEffect.BaseProperties.GetAllLayerProperties());
}
return result; return result;
} }
@ -802,7 +804,7 @@ namespace Artemis.Core
{ {
BaseLayerBrush? oldLayerBrush = LayerBrush; BaseLayerBrush? oldLayerBrush = LayerBrush;
General.BrushReference.SetCurrentValue(layerBrush != null ? new LayerBrushReference(layerBrush.Descriptor) : null, null); General.BrushReference.SetCurrentValue(layerBrush != null ? new LayerBrushReference(layerBrush.Descriptor) : null);
LayerBrush = layerBrush; LayerBrush = layerBrush;
oldLayerBrush?.InternalDisable(); oldLayerBrush?.InternalDisable();
@ -859,13 +861,13 @@ namespace Artemis.Core
} }
#endregion #endregion
} }
/// <summary> /// <summary>
/// Represents a type of layer shape /// Represents a type of layer shape
/// </summary> /// </summary>
public enum LayerShapeType public enum LayerShapeType
{ {
/// <summary> /// <summary>
/// A circular layer shape /// A circular layer shape
/// </summary> /// </summary>
@ -875,13 +877,13 @@ namespace Artemis.Core
/// A rectangular layer shape /// A rectangular layer shape
/// </summary> /// </summary>
Rectangle Rectangle
} }
/// <summary> /// <summary>
/// Represents a layer transform mode /// Represents a layer transform mode
/// </summary> /// </summary>
public enum LayerTransformMode public enum LayerTransformMode
{ {
/// <summary> /// <summary>
/// Normal transformation /// Normal transformation
/// </summary> /// </summary>
@ -891,5 +893,4 @@ namespace Artemis.Core
/// Transforms only a clip /// Transforms only a clip
/// </summary> /// </summary>
Clip Clip
}
} }

View File

@ -6,13 +6,13 @@ using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Entities.Profile.AdaptionHints; using Artemis.Storage.Entities.Profile.AdaptionHints;
using RGB.NET.Core; using RGB.NET.Core;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents an adapter that adapts a layer to a certain set of devices using <see cref="IAdaptionHint" />s
/// </summary>
public class LayerAdapter : IStorageModel
{ {
/// <summary>
/// Represents an adapter that adapts a layer to a certain set of devices using <see cref="IAdaptionHint" />s
/// </summary>
public class LayerAdapter : IStorageModel
{
private readonly List<IAdaptionHint> _adaptionHints; private readonly List<IAdaptionHint> _adaptionHints;
internal LayerAdapter(Layer layer) internal LayerAdapter(Layer layer)
@ -116,11 +116,6 @@ namespace Artemis.Core
return newHints; return newHints;
} }
private bool DoesLayerCoverDevice(ArtemisDevice device)
{
return device.Leds.All(l => Layer.Leds.Contains(l));
}
/// <summary> /// <summary>
/// Adds an adaption hint to the adapter. /// Adds an adaption hint to the adapter.
/// </summary> /// </summary>
@ -153,6 +148,21 @@ namespace Artemis.Core
Remove(_adaptionHints.First()); Remove(_adaptionHints.First());
} }
/// <summary>
/// Occurs whenever a new adapter hint is added to the adapter.
/// </summary>
public event EventHandler<LayerAdapterHintEventArgs>? AdapterHintAdded;
/// <summary>
/// Occurs whenever an adapter hint is removed from the adapter.
/// </summary>
public event EventHandler<LayerAdapterHintEventArgs>? AdapterHintRemoved;
private bool DoesLayerCoverDevice(ArtemisDevice device)
{
return device.Leds.All(l => Layer.Leds.Contains(l));
}
#region Implementation of IStorageModel #region Implementation of IStorageModel
/// <inheritdoc /> /// <inheritdoc />
@ -162,6 +172,7 @@ namespace Artemis.Core
// Kind of meh. // Kind of meh.
// This leaves the adapter responsible for finding the right hint for the right entity, but it's gotta be done somewhere.. // This leaves the adapter responsible for finding the right hint for the right entity, but it's gotta be done somewhere..
foreach (IAdaptionHintEntity hintEntity in Layer.LayerEntity.AdaptionHints) foreach (IAdaptionHintEntity hintEntity in Layer.LayerEntity.AdaptionHints)
{
switch (hintEntity) switch (hintEntity)
{ {
case DeviceAdaptionHintEntity entity: case DeviceAdaptionHintEntity entity:
@ -175,6 +186,7 @@ namespace Artemis.Core
break; break;
} }
} }
}
/// <inheritdoc /> /// <inheritdoc />
public void Save() public void Save()
@ -185,15 +197,4 @@ namespace Artemis.Core
} }
#endregion #endregion
/// <summary>
/// Occurs whenever a new adapter hint is added to the adapter.
/// </summary>
public event EventHandler<LayerAdapterHintEventArgs>? AdapterHintAdded;
/// <summary>
/// Occurs whenever an adapter hint is removed from the adapter.
/// </summary>
public event EventHandler<LayerAdapterHintEventArgs>? AdapterHintRemoved;
}
} }

View File

@ -1,12 +1,12 @@
using Artemis.Core.LayerBrushes; using Artemis.Core.LayerBrushes;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// A reference to a <see cref="LayerBrushDescriptor" />
/// </summary>
public class LayerBrushReference
{ {
/// <summary>
/// A reference to a <see cref="LayerBrushDescriptor" />
/// </summary>
public class LayerBrushReference
{
/// <summary> /// <summary>
/// Creates a new instance of the <see cref="LayerBrushReference" /> class /// Creates a new instance of the <see cref="LayerBrushReference" /> class
/// </summary> /// </summary>
@ -33,5 +33,4 @@ namespace Artemis.Core
/// The full type name of the brush descriptor /// The full type name of the brush descriptor
/// </summary> /// </summary>
public string? BrushType { get; set; } public string? BrushType { get; set; }
}
} }

View File

@ -1,14 +1,14 @@
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a property group on a layer
/// <para>
/// Note: You cannot initialize property groups yourself. If properly placed and annotated, the Artemis core will
/// initialize these for you.
/// </para>
/// </summary>
public abstract class LayerEffectPropertyGroup : LayerPropertyGroup
{ {
/// <summary>
/// Represents a property group on a layer
/// <para>
/// Note: You cannot initialize property groups yourself. If properly placed and annotated, the Artemis core will
/// initialize these for you.
/// </para>
/// </summary>
public abstract class LayerEffectPropertyGroup : LayerPropertyGroup
{
/// <summary> /// <summary>
/// Whether or not this layer effect is enabled /// Whether or not this layer effect is enabled
/// </summary> /// </summary>
@ -21,5 +21,4 @@
if (!IsEnabled.IsLoadedFromStorage) if (!IsEnabled.IsLoadedFromStorage)
IsEnabled.SetCurrentValue(true); IsEnabled.SetCurrentValue(true);
} }
}
} }

View File

@ -2,13 +2,13 @@
#pragma warning disable 8618 #pragma warning disable 8618
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents the general properties of a layer
/// </summary>
public class LayerGeneralProperties : LayerPropertyGroup
{ {
/// <summary>
/// Represents the general properties of a layer
/// </summary>
public class LayerGeneralProperties : LayerPropertyGroup
{
/// <summary> /// <summary>
/// The type of brush to use for this layer /// The type of brush to use for this layer
/// </summary> /// </summary>
@ -49,5 +49,4 @@ namespace Artemis.Core
protected override void DisableProperties() protected override void DisableProperties()
{ {
} }
}
} }

View File

@ -1,11 +1,10 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents an attribute that marks a layer property to be ignored
/// </summary>
public class LayerPropertyIgnoreAttribute : Attribute
{ {
/// <summary>
/// Represents an attribute that marks a layer property to be ignored
/// </summary>
public class LayerPropertyIgnoreAttribute : Attribute
{
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a description attribute used to decorate layer properties
/// </summary>
public class PropertyDescriptionAttribute : Attribute
{ {
/// <summary>
/// Represents a description attribute used to decorate layer properties
/// </summary>
public class PropertyDescriptionAttribute : Attribute
{
/// <summary> /// <summary>
/// The identifier of this property used for storage, if not set one will be generated property name in code /// The identifier of this property used for storage, if not set one will be generated property name in code
/// </summary> /// </summary>
@ -51,5 +51,4 @@ namespace Artemis.Core
/// Whether or not keyframes are always disabled /// Whether or not keyframes are always disabled
/// </summary> /// </summary>
public bool DisableKeyframes { get; set; } public bool DisableKeyframes { get; set; }
}
} }

View File

@ -1,14 +1,15 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a description attribute used to decorate layer property groups
/// </summary>
public class PropertyGroupDescriptionAttribute : Attribute
{ {
/// <summary> /// <summary>
/// Represents a description attribute used to decorate layer property groups /// The identifier of this property group used for storage, if not set one will be generated based on the group name in
/// </summary> /// code
public class PropertyGroupDescriptionAttribute : Attribute
{
/// <summary>
/// The identifier of this property group used for storage, if not set one will be generated based on the group name in code
/// </summary> /// </summary>
public string? Identifier { get; set; } public string? Identifier { get; set; }
@ -21,5 +22,4 @@ namespace Artemis.Core
/// The user-friendly description for this property group, shown in the UI. /// The user-friendly description for this property group, shown in the UI.
/// </summary> /// </summary>
public string? Description { get; set; } public string? Description { get; set; }
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a range between two single-precision floating point numbers
/// </summary>
public readonly struct FloatRange
{ {
/// <summary>
/// Represents a range between two single-precision floating point numbers
/// </summary>
public readonly struct FloatRange
{
private readonly Random _rand; private readonly Random _rand;
/// <summary> /// <summary>
@ -59,5 +59,4 @@ namespace Artemis.Core
return _rand.Next((int) (Start * 100), (int) (End * 100)) / 100f; return _rand.Next((int) (Start * 100), (int) (End * 100)) / 100f;
return _rand.Next((int) (Start * 100) + 1, (int) (End * 100)) / 100f; return _rand.Next((int) (Start * 100) + 1, (int) (End * 100)) / 100f;
} }
}
} }

View File

@ -2,17 +2,17 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a property on a layer. Properties are saved in storage and can optionally be modified from the UI.
/// <para>
/// Note: You cannot initialize layer properties yourself. If properly placed and annotated, the Artemis core will
/// initialize these for you.
/// </para>
/// </summary>
public interface ILayerProperty : IStorageModel, IDisposable
{ {
/// <summary>
/// Represents a property on a layer. Properties are saved in storage and can optionally be modified from the UI.
/// <para>
/// Note: You cannot initialize layer properties yourself. If properly placed and annotated, the Artemis core will
/// initialize these for you.
/// </para>
/// </summary>
public interface ILayerProperty : IStorageModel, IDisposable
{
/// <summary> /// <summary>
/// Gets the description attribute applied to this property /// Gets the description attribute applied to this property
/// </summary> /// </summary>
@ -103,14 +103,14 @@ namespace Artemis.Core
/// <summary> /// <summary>
/// Removes a keyframe from the layer property without knowing it's type. /// Removes a keyframe from the layer property without knowing it's type.
/// <para>Prefer <see cref="LayerProperty{T}.RemoveKeyframe"/>.</para> /// <para>Prefer <see cref="LayerProperty{T}.RemoveKeyframe" />.</para>
/// </summary> /// </summary>
/// <param name="keyframe"></param> /// <param name="keyframe"></param>
void RemoveUntypedKeyframe(ILayerPropertyKeyframe keyframe); void RemoveUntypedKeyframe(ILayerPropertyKeyframe keyframe);
/// <summary> /// <summary>
/// Adds a keyframe to the layer property without knowing it's type. /// Adds a keyframe to the layer property without knowing it's type.
/// <para>Prefer <see cref="LayerProperty{T}.AddKeyframe"/>.</para> /// <para>Prefer <see cref="LayerProperty{T}.AddKeyframe" />.</para>
/// </summary> /// </summary>
/// <param name="keyframe"></param> /// <param name="keyframe"></param>
void AddUntypedKeyframe(ILayerPropertyKeyframe keyframe); void AddUntypedKeyframe(ILayerPropertyKeyframe keyframe);
@ -149,5 +149,4 @@ namespace Artemis.Core
/// Occurs when a keyframe was removed from the layer property /// Occurs when a keyframe was removed from the layer property
/// </summary> /// </summary>
public event EventHandler<LayerPropertyKeyframeEventArgs>? KeyframeRemoved; public event EventHandler<LayerPropertyKeyframeEventArgs>? KeyframeRemoved;
}
} }

View File

@ -2,13 +2,13 @@
using System.ComponentModel; using System.ComponentModel;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a keyframe on a <see cref="ILayerProperty" /> containing a value and a timestamp
/// </summary>
public interface ILayerPropertyKeyframe : INotifyPropertyChanged
{ {
/// <summary>
/// Represents a keyframe on a <see cref="ILayerProperty" /> containing a value and a timestamp
/// </summary>
public interface ILayerPropertyKeyframe : INotifyPropertyChanged
{
/// <summary> /// <summary>
/// Gets an untyped reference to the layer property of this keyframe /// Gets an untyped reference to the layer property of this keyframe
/// </summary> /// </summary>
@ -40,5 +40,4 @@ namespace Artemis.Core
/// </summary> /// </summary>
/// <returns>The resulting copy</returns> /// <returns>The resulting copy</returns>
ILayerPropertyKeyframe CreateCopy(); ILayerPropertyKeyframe CreateCopy();
}
} }

View File

@ -1,12 +1,12 @@
using System; using System;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a range between two signed integers
/// </summary>
public readonly struct IntRange
{ {
/// <summary>
/// Represents a range between two signed integers
/// </summary>
public readonly struct IntRange
{
private readonly Random _rand; private readonly Random _rand;
/// <summary> /// <summary>
@ -59,5 +59,4 @@ namespace Artemis.Core
return _rand.Next(Start, End + 1); return _rand.Next(Start, End + 1);
return _rand.Next(Start + 1, End); return _rand.Next(Start + 1, End);
} }
}
} }

View File

@ -5,18 +5,18 @@ using System.Linq;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a property on a layer. Properties are saved in storage and can optionally be modified from the UI.
/// <para>
/// Note: You cannot initialize layer properties yourself. If properly placed and annotated, the Artemis core will
/// initialize these for you.
/// </para>
/// </summary>
/// <typeparam name="T">The type of property encapsulated in this layer property</typeparam>
public class LayerProperty<T> : CorePropertyChanged, ILayerProperty
{ {
/// <summary>
/// Represents a property on a layer. Properties are saved in storage and can optionally be modified from the UI.
/// <para>
/// Note: You cannot initialize layer properties yourself. If properly placed and annotated, the Artemis core will
/// initialize these for you.
/// </para>
/// </summary>
/// <typeparam name="T">The type of property encapsulated in this layer property</typeparam>
public class LayerProperty<T> : CorePropertyChanged, ILayerProperty
{
private bool _disposed; private bool _disposed;
/// <summary> /// <summary>
@ -69,6 +69,57 @@ namespace Artemis.Core
Disposed?.Invoke(this, EventArgs.Empty); Disposed?.Invoke(this, EventArgs.Empty);
} }
/// <summary>
/// Invokes the <see cref="Updated" /> event
/// </summary>
protected virtual void OnUpdated()
{
Updated?.Invoke(this, new LayerPropertyEventArgs(this));
}
/// <summary>
/// Invokes the <see cref="CurrentValueSet" /> event
/// </summary>
protected virtual void OnCurrentValueSet()
{
CurrentValueSet?.Invoke(this, new LayerPropertyEventArgs(this));
LayerPropertyGroup.OnLayerPropertyOnCurrentValueSet(new LayerPropertyEventArgs(this));
}
/// <summary>
/// Invokes the <see cref="VisibilityChanged" /> event
/// </summary>
protected virtual void OnVisibilityChanged()
{
VisibilityChanged?.Invoke(this, new LayerPropertyEventArgs(this));
}
/// <summary>
/// Invokes the <see cref="KeyframesToggled" /> event
/// </summary>
protected virtual void OnKeyframesToggled()
{
KeyframesToggled?.Invoke(this, new LayerPropertyEventArgs(this));
}
/// <summary>
/// Invokes the <see cref="KeyframeAdded" /> event
/// </summary>
/// <param name="keyframe"></param>
protected virtual void OnKeyframeAdded(ILayerPropertyKeyframe keyframe)
{
KeyframeAdded?.Invoke(this, new LayerPropertyKeyframeEventArgs(keyframe));
}
/// <summary>
/// Invokes the <see cref="KeyframeRemoved" /> event
/// </summary>
/// <param name="keyframe"></param>
protected virtual void OnKeyframeRemoved(ILayerPropertyKeyframe keyframe)
{
KeyframeRemoved?.Invoke(this, new LayerPropertyKeyframeEventArgs(keyframe));
}
/// <inheritdoc /> /// <inheritdoc />
public PropertyDescriptionAttribute PropertyDescription { get; internal set; } public PropertyDescriptionAttribute PropertyDescription { get; internal set; }
@ -126,6 +177,27 @@ namespace Artemis.Core
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
/// <inheritdoc />
public event EventHandler? Disposed;
/// <inheritdoc />
public event EventHandler<LayerPropertyEventArgs>? Updated;
/// <inheritdoc />
public event EventHandler<LayerPropertyEventArgs>? CurrentValueSet;
/// <inheritdoc />
public event EventHandler<LayerPropertyEventArgs>? VisibilityChanged;
/// <inheritdoc />
public event EventHandler<LayerPropertyEventArgs>? KeyframesToggled;
/// <inheritdoc />
public event EventHandler<LayerPropertyKeyframeEventArgs>? KeyframeAdded;
/// <inheritdoc />
public event EventHandler<LayerPropertyKeyframeEventArgs>? KeyframeRemoved;
#region Hierarchy #region Hierarchy
private bool _isHidden; private bool _isHidden;
@ -208,7 +280,9 @@ namespace Artemis.Core
LayerPropertyKeyframe<T>? keyframe = null; LayerPropertyKeyframe<T>? keyframe = null;
if (time == null || !KeyframesEnabled || !KeyframesSupported) if (time == null || !KeyframesEnabled || !KeyframesSupported)
{
BaseValue = value; BaseValue = value;
}
else else
{ {
// If on a keyframe, update the keyframe // If on a keyframe, update the keyframe
@ -220,8 +294,10 @@ namespace Artemis.Core
AddKeyframe(keyframe); AddKeyframe(keyframe);
} }
else else
{
keyframe.Value = value; keyframe.Value = value;
} }
}
// Force an update so that the base value is applied to the current value and // Force an update so that the base value is applied to the current value and
// keyframes/data bindings are applied using the new base value // keyframes/data bindings are applied using the new base value
@ -242,7 +318,9 @@ namespace Artemis.Core
// For value types there's no need to make a copy // For value types there's no need to make a copy
if (DefaultValue.GetType().IsValueType) if (DefaultValue.GetType().IsValueType)
{
SetCurrentValue(DefaultValue); SetCurrentValue(DefaultValue);
}
// Reference types make a deep clone (ab)using JSON // Reference types make a deep clone (ab)using JSON
else else
{ {
@ -603,81 +681,4 @@ namespace Artemis.Core
} }
#endregion #endregion
#region Events
/// <inheritdoc />
public event EventHandler? Disposed;
/// <inheritdoc />
public event EventHandler<LayerPropertyEventArgs>? Updated;
/// <inheritdoc />
public event EventHandler<LayerPropertyEventArgs>? CurrentValueSet;
/// <inheritdoc />
public event EventHandler<LayerPropertyEventArgs>? VisibilityChanged;
/// <inheritdoc />
public event EventHandler<LayerPropertyEventArgs>? KeyframesToggled;
/// <inheritdoc />
public event EventHandler<LayerPropertyKeyframeEventArgs>? KeyframeAdded;
/// <inheritdoc />
public event EventHandler<LayerPropertyKeyframeEventArgs>? KeyframeRemoved;
/// <summary>
/// Invokes the <see cref="Updated" /> event
/// </summary>
protected virtual void OnUpdated()
{
Updated?.Invoke(this, new LayerPropertyEventArgs(this));
}
/// <summary>
/// Invokes the <see cref="CurrentValueSet" /> event
/// </summary>
protected virtual void OnCurrentValueSet()
{
CurrentValueSet?.Invoke(this, new LayerPropertyEventArgs(this));
LayerPropertyGroup.OnLayerPropertyOnCurrentValueSet(new LayerPropertyEventArgs(this));
}
/// <summary>
/// Invokes the <see cref="VisibilityChanged" /> event
/// </summary>
protected virtual void OnVisibilityChanged()
{
VisibilityChanged?.Invoke(this, new LayerPropertyEventArgs(this));
}
/// <summary>
/// Invokes the <see cref="KeyframesToggled" /> event
/// </summary>
protected virtual void OnKeyframesToggled()
{
KeyframesToggled?.Invoke(this, new LayerPropertyEventArgs(this));
}
/// <summary>
/// Invokes the <see cref="KeyframeAdded" /> event
/// </summary>
/// <param name="keyframe"></param>
protected virtual void OnKeyframeAdded(ILayerPropertyKeyframe keyframe)
{
KeyframeAdded?.Invoke(this, new LayerPropertyKeyframeEventArgs(keyframe));
}
/// <summary>
/// Invokes the <see cref="KeyframeRemoved" /> event
/// </summary>
/// <param name="keyframe"></param>
protected virtual void OnKeyframeRemoved(ILayerPropertyKeyframe keyframe)
{
KeyframeRemoved?.Invoke(this, new LayerPropertyKeyframeEventArgs(keyframe));
}
#endregion
}
} }

View File

@ -1,13 +1,13 @@
using System; using System;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a keyframe on a <see cref="LayerProperty{T}" /> containing a value and a timestamp
/// </summary>
public class LayerPropertyKeyframe<T> : CorePropertyChanged, ILayerPropertyKeyframe
{ {
/// <summary>
/// Represents a keyframe on a <see cref="LayerProperty{T}" /> containing a value and a timestamp
/// </summary>
public class LayerPropertyKeyframe<T> : CorePropertyChanged, ILayerPropertyKeyframe
{
private LayerProperty<T> _layerProperty; private LayerProperty<T> _layerProperty;
private TimeSpan _position; private TimeSpan _position;
private T _value; private T _value;
@ -86,5 +86,4 @@ namespace Artemis.Core
{ {
return new LayerPropertyKeyframe<T>(Value, Position, EasingFunction, LayerProperty); return new LayerPropertyKeyframe<T>(Value, Position, EasingFunction, LayerProperty);
} }
}
} }

View File

@ -79,7 +79,8 @@ public sealed class LayerPropertyPreview<T> : IDisposable
} }
Property.SetCurrentValue(OriginalValue, Time); Property.SetCurrentValue(OriginalValue, Time);
return !Equals(OriginalValue, PreviewValue); ; return !Equals(OriginalValue, PreviewValue);
;
} }
/// <summary> /// <summary>

View File

@ -3,22 +3,20 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Artemis.Core.LayerBrushes;
using Artemis.Core.LayerEffects;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
using Humanizer; using Humanizer;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a property group on a layer
/// <para>
/// Note: You cannot initialize property groups yourself. If properly placed and annotated, the Artemis core will
/// initialize these for you.
/// </para>
/// </summary>
public abstract class LayerPropertyGroup : IDisposable
{ {
/// <summary>
/// Represents a property group on a layer
/// <para>
/// Note: You cannot initialize property groups yourself. If properly placed and annotated, the Artemis core will
/// initialize these for you.
/// </para>
/// </summary>
public abstract class LayerPropertyGroup : IDisposable
{
private readonly List<ILayerProperty> _layerProperties; private readonly List<ILayerProperty> _layerProperties;
private readonly List<LayerPropertyGroup> _layerPropertyGroups; private readonly List<LayerPropertyGroup> _layerPropertyGroups;
private bool _disposed; private bool _disposed;
@ -335,7 +333,7 @@ namespace Artemis.Core
if (PropertyGroupEntity == null) if (PropertyGroupEntity == null)
throw new ArtemisCoreException($"Can't execute {nameof(GetPropertyGroupEntity)} without {nameof(PropertyGroupEntity)} being setup"); throw new ArtemisCoreException($"Can't execute {nameof(GetPropertyGroupEntity)} without {nameof(PropertyGroupEntity)} being setup");
return PropertyGroupEntity.PropertyGroups.FirstOrDefault(g => g.Identifier == identifier) ?? new PropertyGroupEntity() {Identifier = identifier}; return PropertyGroupEntity.PropertyGroups.FirstOrDefault(g => g.Identifier == identifier) ?? new PropertyGroupEntity {Identifier = identifier};
} }
/// <inheritdoc /> /// <inheritdoc />
@ -344,5 +342,4 @@ namespace Artemis.Core
Dispose(true); Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
}
} }

View File

@ -1,12 +1,12 @@
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents an ellipse layer shape
/// </summary>
public class EllipseShape : LayerShape
{ {
/// <summary>
/// Represents an ellipse layer shape
/// </summary>
public class EllipseShape : LayerShape
{
internal EllipseShape(Layer layer) : base(layer) internal EllipseShape(Layer layer) : base(layer)
{ {
} }
@ -18,5 +18,4 @@ namespace Artemis.Core
path.AddOval(SKRect.Create(Layer.Bounds.Width, Layer.Bounds.Height)); path.AddOval(SKRect.Create(Layer.Bounds.Width, Layer.Bounds.Height));
Path = path; Path = path;
} }
}
} }

View File

@ -1,12 +1,12 @@
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents the shape of a layer
/// </summary>
public abstract class LayerShape
{ {
/// <summary>
/// Represents the shape of a layer
/// </summary>
public abstract class LayerShape
{
internal LayerShape(Layer layer) internal LayerShape(Layer layer)
{ {
Layer = layer; Layer = layer;
@ -26,5 +26,4 @@ namespace Artemis.Core
/// Calculates the <see cref="Path" /> /// Calculates the <see cref="Path" />
/// </summary> /// </summary>
public abstract void CalculateRenderProperties(); public abstract void CalculateRenderProperties();
}
} }

View File

@ -1,12 +1,12 @@
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a rectangular layer shape
/// </summary>
public class RectangleShape : LayerShape
{ {
/// <summary>
/// Represents a rectangular layer shape
/// </summary>
public class RectangleShape : LayerShape
{
internal RectangleShape(Layer layer) : base(layer) internal RectangleShape(Layer layer) : base(layer)
{ {
} }
@ -18,5 +18,4 @@ namespace Artemis.Core
path.AddRect(SKRect.Create(Layer.Bounds.Width, Layer.Bounds.Height)); path.AddRect(SKRect.Create(Layer.Bounds.Width, Layer.Bounds.Height));
Path = path; Path = path;
} }
}
} }

View File

@ -2,13 +2,13 @@
#pragma warning disable 8618 #pragma warning disable 8618
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents the transform properties of a layer
/// </summary>
public class LayerTransformProperties : LayerPropertyGroup
{ {
/// <summary>
/// Represents the transform properties of a layer
/// </summary>
public class LayerTransformProperties : LayerPropertyGroup
{
/// <summary> /// <summary>
/// The point at which the shape is attached to its position /// The point at which the shape is attached to its position
/// </summary> /// </summary>
@ -57,5 +57,4 @@ namespace Artemis.Core
protected override void DisableProperties() protected override void DisableProperties()
{ {
} }
}
} }

View File

@ -6,18 +6,18 @@ using Artemis.Core.ScriptingProviders;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a profile containing folders and layers
/// </summary>
public sealed class Profile : ProfileElement
{ {
/// <summary>
/// Represents a profile containing folders and layers
/// </summary>
public sealed class Profile : ProfileElement
{
private readonly object _lock = new(); private readonly object _lock = new();
private readonly ObservableCollection<ScriptConfiguration> _scriptConfigurations;
private readonly ObservableCollection<ProfileScript> _scripts;
private bool _isFreshImport; private bool _isFreshImport;
private ProfileElement? _lastSelectedProfileElement; private ProfileElement? _lastSelectedProfileElement;
private readonly ObservableCollection<ProfileScript> _scripts;
private readonly ObservableCollection<ScriptConfiguration> _scriptConfigurations;
internal Profile(ProfileConfiguration configuration, ProfileEntity profileEntity) : base(null!) internal Profile(ProfileConfiguration configuration, ProfileEntity profileEntity) : base(null!)
{ {
@ -165,6 +165,16 @@ namespace Artemis.Core
layer.PopulateLeds(devices); layer.PopulateLeds(devices);
} }
#region Overrides of BreakableModel
/// <inheritdoc />
public override IEnumerable<IBreakableModel> GetBrokenHierarchy()
{
return GetAllRenderElements().SelectMany(folders => folders.GetBrokenHierarchy());
}
#endregion
/// <inheritdoc /> /// <inheritdoc />
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
@ -263,7 +273,6 @@ namespace Artemis.Core
{ {
_scripts.Remove(script); _scripts.Remove(script);
script.Dispose(); script.Dispose();
} }
internal override void Save() internal override void Save()
@ -292,15 +301,4 @@ namespace Artemis.Core
ProfileEntity.ScriptConfigurations.Add(scriptConfiguration.Entity); ProfileEntity.ScriptConfigurations.Add(scriptConfiguration.Entity);
} }
} }
#region Overrides of BreakableModel
/// <inheritdoc />
public override IEnumerable<IBreakableModel> GetBrokenHierarchy()
{
return GetAllRenderElements().SelectMany(folders => folders.GetBrokenHierarchy());
}
#endregion
}
} }

View File

@ -3,13 +3,13 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents a category containing <see cref="ProfileConfigurations" />
/// </summary>
public class ProfileCategory : CorePropertyChanged, IStorageModel
{ {
/// <summary>
/// Represents a category containing <see cref="ProfileConfigurations" />
/// </summary>
public class ProfileCategory : CorePropertyChanged, IStorageModel
{
private readonly List<ProfileConfiguration> _profileConfigurations = new(); private readonly List<ProfileConfiguration> _profileConfigurations = new();
private bool _isCollapsed; private bool _isCollapsed;
private bool _isSuspended; private bool _isSuspended;
@ -103,7 +103,10 @@ namespace Artemis.Core
_profileConfigurations.Insert(targetIndex.Value, configuration); _profileConfigurations.Insert(targetIndex.Value, configuration);
} }
else else
{
_profileConfigurations.Add(configuration); _profileConfigurations.Add(configuration);
}
configuration.Category = this; configuration.Category = this;
for (int index = 0; index < _profileConfigurations.Count; index++) for (int index = 0; index < _profileConfigurations.Count; index++)
@ -117,6 +120,32 @@ namespace Artemis.Core
return $"[ProfileCategory] {Order} {nameof(Name)}: {Name}, {nameof(IsSuspended)}: {IsSuspended}"; return $"[ProfileCategory] {Order} {nameof(Name)}: {Name}, {nameof(IsSuspended)}: {IsSuspended}";
} }
/// <summary>
/// Occurs when a profile configuration is added to this <see cref="ProfileCategory" />
/// </summary>
public event EventHandler<ProfileConfigurationEventArgs>? ProfileConfigurationAdded;
/// <summary>
/// Occurs when a profile configuration is removed from this <see cref="ProfileCategory" />
/// </summary>
public event EventHandler<ProfileConfigurationEventArgs>? ProfileConfigurationRemoved;
/// <summary>
/// Invokes the <see cref="ProfileConfigurationAdded" /> event
/// </summary>
protected virtual void OnProfileConfigurationAdded(ProfileConfigurationEventArgs e)
{
ProfileConfigurationAdded?.Invoke(this, e);
}
/// <summary>
/// Invokes the <see cref="ProfileConfigurationRemoved" /> event
/// </summary>
protected virtual void OnProfileConfigurationRemoved(ProfileConfigurationEventArgs e)
{
ProfileConfigurationRemoved?.Invoke(this, e);
}
internal void RemoveProfileConfiguration(ProfileConfiguration configuration) internal void RemoveProfileConfiguration(ProfileConfiguration configuration)
{ {
if (!_profileConfigurations.Remove(configuration)) if (!_profileConfigurations.Remove(configuration))
@ -159,43 +188,13 @@ namespace Artemis.Core
} }
#endregion #endregion
}
#region Events /// <summary>
/// Represents a name of one of the default categories
/// <summary> /// </summary>
/// Occurs when a profile configuration is added to this <see cref="ProfileCategory" /> public enum DefaultCategoryName
/// </summary> {
public event EventHandler<ProfileConfigurationEventArgs>? ProfileConfigurationAdded;
/// <summary>
/// Occurs when a profile configuration is removed from this <see cref="ProfileCategory" />
/// </summary>
public event EventHandler<ProfileConfigurationEventArgs>? ProfileConfigurationRemoved;
/// <summary>
/// Invokes the <see cref="ProfileConfigurationAdded" /> event
/// </summary>
protected virtual void OnProfileConfigurationAdded(ProfileConfigurationEventArgs e)
{
ProfileConfigurationAdded?.Invoke(this, e);
}
/// <summary>
/// Invokes the <see cref="ProfileConfigurationRemoved" /> event
/// </summary>
protected virtual void OnProfileConfigurationRemoved(ProfileConfigurationEventArgs e)
{
ProfileConfigurationRemoved?.Invoke(this, e);
}
#endregion
}
/// <summary>
/// Represents a name of one of the default categories
/// </summary>
public enum DefaultCategoryName
{
/// <summary> /// <summary>
/// The category used by profiles tied to games /// The category used by profiles tied to games
/// </summary> /// </summary>
@ -210,5 +209,4 @@ namespace Artemis.Core
/// The category used by general profiles /// The category used by general profiles
/// </summary> /// </summary>
General General
}
} }

View File

@ -2,16 +2,15 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
using SkiaSharp; using SkiaSharp;
namespace Artemis.Core namespace Artemis.Core;
/// <summary>
/// Represents an element of a <see cref="Profile" />
/// </summary>
public abstract class ProfileElement : BreakableModel, IDisposable
{ {
/// <summary>
/// Represents an element of a <see cref="Profile" />
/// </summary>
public abstract class ProfileElement : BreakableModel, IDisposable
{
internal readonly List<ProfileElement> ChildrenList; internal readonly List<ProfileElement> ChildrenList;
private Guid _entityId; private Guid _entityId;
private string? _name; private string? _name;
@ -378,5 +377,4 @@ namespace Artemis.Core
internal abstract void Save(); internal abstract void Save();
#endregion #endregion
}
} }

Some files were not shown because too many files have changed in this diff Show More