mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-01-02 10:43:31 +00:00
Compare commits
No commits in common. "2e600e76b03fab8bf49aa42a492c4ba207727575" and "f0e9581fe1070c38e1c4d803db60ca1e8f8ada62" have entirely different histories.
2e600e76b0
...
f0e9581fe1
2
.github/workflows/docfx.yml
vendored
2
.github/workflows/docfx.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v2
|
uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: "8.0.x"
|
dotnet-version: "7.0.x"
|
||||||
- name: Setup DocFX
|
- name: Setup DocFX
|
||||||
run: dotnet tool update -g docfx
|
run: dotnet tool update -g docfx
|
||||||
- name: Build Core
|
- name: Build Core
|
||||||
|
|||||||
4
.github/workflows/master.yml
vendored
4
.github/workflows/master.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
rid: win-x64
|
rid: win10-x64
|
||||||
csproj: Windows
|
csproj: Windows
|
||||||
|
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
@ -60,7 +60,7 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v2
|
uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: '8.0.x'
|
dotnet-version: '7.0.x'
|
||||||
- name: Publish Artemis
|
- name: Publish Artemis
|
||||||
run: dotnet publish --configuration Release -p:Version=${{ needs.version.outputs.version-number }} --runtime ${{ matrix.rid }} --output build/${{ matrix.rid }} --self-contained Artemis/src/Artemis.UI.${{ matrix.csproj }}/Artemis.UI.${{ matrix.csproj }}.csproj
|
run: dotnet publish --configuration Release -p:Version=${{ needs.version.outputs.version-number }} --runtime ${{ matrix.rid }} --output build/${{ matrix.rid }} --self-contained Artemis/src/Artemis.UI.${{ matrix.csproj }}/Artemis.UI.${{ matrix.csproj }}.csproj
|
||||||
- name: Publish Plugins
|
- name: Publish Plugins
|
||||||
|
|||||||
2
.github/workflows/nuget.yml
vendored
2
.github/workflows/nuget.yml
vendored
@ -37,7 +37,7 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v2
|
uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: '8.0.x'
|
dotnet-version: '7.0.x'
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Pack Artemis.Core
|
- name: Pack Artemis.Core
|
||||||
|
|||||||
@ -36,20 +36,20 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DryIoc.dll" />
|
<PackageReference Include="DryIoc.dll" Version="5.4.3" />
|
||||||
<PackageReference Include="EmbedIO" />
|
<PackageReference Include="EmbedIO" Version="3.5.2" />
|
||||||
<PackageReference Include="HidSharp" />
|
<PackageReference Include="HidSharp" Version="2.1.0" />
|
||||||
<PackageReference Include="Humanizer.Core" />
|
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
|
||||||
<PackageReference Include="JetBrains.Annotations" />
|
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
|
||||||
<PackageReference Include="McMaster.NETCore.Plugins" />
|
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="RGB.NET.Core" />
|
<PackageReference Include="RGB.NET.Core" Version="2.0.4-prerelease.16" />
|
||||||
<PackageReference Include="RGB.NET.Layout" />
|
<PackageReference Include="RGB.NET.Layout" Version="2.0.4-prerelease.16" />
|
||||||
<PackageReference Include="RGB.NET.Presets" />
|
<PackageReference Include="RGB.NET.Presets" Version="2.0.4-prerelease.16" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.Debug" />
|
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" />
|
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||||
<PackageReference Include="SkiaSharp" />
|
<PackageReference Include="SkiaSharp" Version="2.88.7" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ using Artemis.Core.DryIoc.Factories;
|
|||||||
using Artemis.Core.Providers;
|
using Artemis.Core.Providers;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.Storage;
|
using Artemis.Storage;
|
||||||
using Artemis.Storage.Migrations;
|
using Artemis.Storage.Migrations.Interfaces;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using DryIoc;
|
using DryIoc;
|
||||||
|
|
||||||
@ -36,7 +36,6 @@ public static class ContainerExtensions
|
|||||||
|
|
||||||
// Bind migrations
|
// Bind migrations
|
||||||
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IStorageMigration>(), Reuse.Singleton, nonPublicServiceTypes: true);
|
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IStorageMigration>(), Reuse.Singleton, nonPublicServiceTypes: true);
|
||||||
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IProfileMigration>(), Reuse.Singleton, nonPublicServiceTypes: true);
|
|
||||||
|
|
||||||
container.RegisterMany(coreAssembly, type => type.IsAssignableTo<ILayoutProvider>(), Reuse.Singleton);
|
container.RegisterMany(coreAssembly, type => type.IsAssignableTo<ILayoutProvider>(), Reuse.Singleton);
|
||||||
container.Register<IPluginSettingsFactory, PluginSettingsFactory>(Reuse.Singleton);
|
container.Register<IPluginSettingsFactory, PluginSettingsFactory>(Reuse.Singleton);
|
||||||
|
|||||||
@ -248,8 +248,8 @@ public sealed class Layer : RenderProfileElement
|
|||||||
typeof(PropertyGroupDescriptionAttribute)
|
typeof(PropertyGroupDescriptionAttribute)
|
||||||
)!;
|
)!;
|
||||||
|
|
||||||
LayerEntity.GeneralPropertyGroup ??= new PropertyGroupEntity {Identifier = generalAttribute.Identifier!};
|
LayerEntity.GeneralPropertyGroup ??= new PropertyGroupEntity {Identifier = generalAttribute.Identifier};
|
||||||
LayerEntity.TransformPropertyGroup ??= new PropertyGroupEntity {Identifier = transformAttribute.Identifier!};
|
LayerEntity.TransformPropertyGroup ??= new PropertyGroupEntity {Identifier = transformAttribute.Identifier};
|
||||||
|
|
||||||
General.Initialize(this, null, generalAttribute, LayerEntity.GeneralPropertyGroup);
|
General.Initialize(this, null, generalAttribute, LayerEntity.GeneralPropertyGroup);
|
||||||
Transform.Initialize(this, null, transformAttribute, LayerEntity.TransformPropertyGroup);
|
Transform.Initialize(this, null, transformAttribute, LayerEntity.TransformPropertyGroup);
|
||||||
|
|||||||
@ -240,8 +240,7 @@ public abstract class LayerPropertyGroup : IDisposable
|
|||||||
foreach (LayerPropertyGroup layerPropertyGroup in LayerPropertyGroups)
|
foreach (LayerPropertyGroup layerPropertyGroup in LayerPropertyGroups)
|
||||||
{
|
{
|
||||||
layerPropertyGroup.ApplyToEntity();
|
layerPropertyGroup.ApplyToEntity();
|
||||||
if (layerPropertyGroup.PropertyGroupEntity != null)
|
PropertyGroupEntity.PropertyGroups.Add(layerPropertyGroup.PropertyGroupEntity);
|
||||||
PropertyGroupEntity.PropertyGroups.Add(layerPropertyGroup.PropertyGroupEntity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ public class ArtemisDevice : CorePropertyChanged
|
|||||||
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
||||||
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
||||||
Categories = new HashSet<DeviceCategory>();
|
Categories = new HashSet<DeviceCategory>();
|
||||||
LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LAYOUT_TYPE};
|
LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LayoutType};
|
||||||
|
|
||||||
RgbDevice.ColorCorrections.Clear();
|
RgbDevice.ColorCorrections.Clear();
|
||||||
RgbDevice.ColorCorrections.Add(new ScaleColorCorrection(this));
|
RgbDevice.ColorCorrections.Add(new ScaleColorCorrection(this));
|
||||||
@ -75,7 +75,7 @@ public class ArtemisDevice : CorePropertyChanged
|
|||||||
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
InputIdentifiers = new List<ArtemisDeviceInputIdentifier>();
|
||||||
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
InputMappings = new Dictionary<ArtemisLed, ArtemisLed>();
|
||||||
Categories = new HashSet<DeviceCategory>();
|
Categories = new HashSet<DeviceCategory>();
|
||||||
LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LAYOUT_TYPE};
|
LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LayoutType};
|
||||||
|
|
||||||
foreach (DeviceInputIdentifierEntity identifierEntity in DeviceEntity.InputIdentifiers)
|
foreach (DeviceInputIdentifierEntity identifierEntity in DeviceEntity.InputIdentifiers)
|
||||||
InputIdentifiers.Add(new ArtemisDeviceInputIdentifier(identifierEntity.InputProvider, identifierEntity.Identifier));
|
InputIdentifiers.Add(new ArtemisDeviceInputIdentifier(identifierEntity.InputProvider, identifierEntity.Identifier));
|
||||||
@ -155,9 +155,6 @@ public class ArtemisDevice : CorePropertyChanged
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public HashSet<DeviceCategory> Categories { get; }
|
public HashSet<DeviceCategory> Categories { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the layout selection applied to this device
|
|
||||||
/// </summary>
|
|
||||||
public LayoutSelection LayoutSelection { get; }
|
public LayoutSelection LayoutSelection { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -57,9 +57,6 @@ public class ArtemisLayout
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public LayoutCustomDeviceData LayoutCustomDeviceData { get; private set; } = null!;
|
public LayoutCustomDeviceData LayoutCustomDeviceData { get; private set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a boolean indicating whether this layout is a default layout or not
|
|
||||||
/// </summary>
|
|
||||||
public bool IsDefaultLayout { get; private set; }
|
public bool IsDefaultLayout { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -65,7 +65,7 @@ public class LayerBrushDescriptor
|
|||||||
BaseLayerBrush brush = (BaseLayerBrush) Provider.Plugin.Resolve(LayerBrushType);
|
BaseLayerBrush brush = (BaseLayerBrush) Provider.Plugin.Resolve(LayerBrushType);
|
||||||
brush.Layer = layer;
|
brush.Layer = layer;
|
||||||
brush.Descriptor = this;
|
brush.Descriptor = this;
|
||||||
brush.LayerBrushEntity = entity ?? new LayerBrushEntity {ProviderId = Provider.Id, BrushType = LayerBrushType.FullName ?? throw new InvalidOperationException()};
|
brush.LayerBrushEntity = entity ?? new LayerBrushEntity {ProviderId = Provider.Id, BrushType = LayerBrushType.FullName};
|
||||||
|
|
||||||
brush.Initialize();
|
brush.Initialize();
|
||||||
return brush;
|
return brush;
|
||||||
|
|||||||
@ -231,7 +231,7 @@ public abstract class BaseLayerEffect : BreakableModel, IDisposable, IStorageMod
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
LayerEffectEntity.ProviderId = Descriptor.Provider.Id;
|
LayerEffectEntity.ProviderId = Descriptor.Provider.Id;
|
||||||
LayerEffectEntity.EffectType = GetType().FullName ?? throw new InvalidOperationException();
|
LayerEffectEntity.EffectType = GetType().FullName;
|
||||||
BaseProperties?.ApplyToEntity();
|
BaseProperties?.ApplyToEntity();
|
||||||
LayerEffectEntity.PropertyGroup = BaseProperties?.PropertyGroupEntity;
|
LayerEffectEntity.PropertyGroup = BaseProperties?.PropertyGroupEntity;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,81 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Reflection;
|
|
||||||
using SkiaSharp;
|
|
||||||
|
|
||||||
namespace Artemis.Core.Nodes;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Allows you to register one or more <see cref="INode" />s usable by node scripts.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class NodeProvider : PluginFeature
|
|
||||||
{
|
|
||||||
private readonly List<NodeData> _nodeDescriptors;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of the <see cref="NodeProvider"/> class.
|
|
||||||
/// </summary>
|
|
||||||
public NodeProvider()
|
|
||||||
{
|
|
||||||
_nodeDescriptors = new List<NodeData>();
|
|
||||||
NodeDescriptors = new ReadOnlyCollection<NodeData>(_nodeDescriptors);
|
|
||||||
Disabled += OnDisabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A read-only collection of all nodes added with <see cref="RegisterNodeType{T}" />
|
|
||||||
/// </summary>
|
|
||||||
public ReadOnlyCollection<NodeData> NodeDescriptors { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a node descriptor for a given node, so that it appears in the UI.
|
|
||||||
/// <para>Note: You do not need to manually remove these on disable</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of the node you wish to register</typeparam>
|
|
||||||
protected void RegisterNodeType<T>() where T : INode
|
|
||||||
{
|
|
||||||
RegisterNodeType(typeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a node descriptor for a given node, so that it appears in the UI.
|
|
||||||
/// <para>Note: You do not need to manually remove these on disable</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="nodeType">The type of the node you wish to register</param>
|
|
||||||
protected void RegisterNodeType(Type nodeType)
|
|
||||||
{
|
|
||||||
if (!IsEnabled)
|
|
||||||
throw new ArtemisPluginFeatureException(this, "Can only add a node descriptor when the plugin is enabled");
|
|
||||||
if (nodeType == null)
|
|
||||||
throw new ArgumentNullException(nameof(nodeType));
|
|
||||||
if (!nodeType.IsAssignableTo(typeof(INode)))
|
|
||||||
throw new ArgumentException("Node has to be a base type of the Node-Type.", nameof(nodeType));
|
|
||||||
|
|
||||||
NodeAttribute? nodeAttribute = nodeType.GetCustomAttribute<NodeAttribute>();
|
|
||||||
string name = nodeAttribute?.Name ?? nodeType.Name;
|
|
||||||
string description = nodeAttribute?.Description ?? string.Empty;
|
|
||||||
string category = nodeAttribute?.Category ?? string.Empty;
|
|
||||||
string helpUrl = nodeAttribute?.HelpUrl ?? string.Empty;
|
|
||||||
|
|
||||||
NodeData nodeData = new(this, nodeType, name, description, category, helpUrl, nodeAttribute?.InputType, nodeAttribute?.OutputType);
|
|
||||||
_nodeDescriptors.Add(nodeData);
|
|
||||||
NodeTypeStore.Add(nodeData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a color for lines of the provided type.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="color">The color to add.</param>
|
|
||||||
/// <typeparam name="T">The type to use the color for.</typeparam>
|
|
||||||
protected TypeColorRegistration RegisterTypeColor<T>(SKColor color)
|
|
||||||
{
|
|
||||||
return NodeTypeStore.AddColor(typeof(T), color, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDisabled(object? sender, EventArgs e)
|
|
||||||
{
|
|
||||||
// The store will clean up the registrations by itself, the plugin feature just needs to clear its own list
|
|
||||||
_nodeDescriptors.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -41,7 +41,7 @@ public class PluginSettings
|
|||||||
if (_settingEntities.ContainsKey(name))
|
if (_settingEntities.ContainsKey(name))
|
||||||
return (PluginSetting<T>) _settingEntities[name];
|
return (PluginSetting<T>) _settingEntities[name];
|
||||||
// Try to find in database
|
// Try to find in database
|
||||||
PluginSettingEntity? settingEntity = _pluginRepository.GetSettingByNameAndGuid(name, Plugin.Guid);
|
PluginSettingEntity settingEntity = _pluginRepository.GetSettingByNameAndGuid(name, Plugin.Guid);
|
||||||
// If not found, create a new one
|
// If not found, create a new one
|
||||||
if (settingEntity == null)
|
if (settingEntity == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,14 +1,8 @@
|
|||||||
namespace Artemis.Core.Providers;
|
namespace Artemis.Core.Providers;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a layout provider that loads a layout from a custom path.
|
|
||||||
/// </summary>
|
|
||||||
public class CustomPathLayoutProvider : ILayoutProvider
|
public class CustomPathLayoutProvider : ILayoutProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
public static string LayoutType = "CustomPath";
|
||||||
/// The layout type of this layout provider.
|
|
||||||
/// </summary>
|
|
||||||
public const string LAYOUT_TYPE = "CustomPath";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ArtemisLayout? GetDeviceLayout(ArtemisDevice device)
|
public ArtemisLayout? GetDeviceLayout(ArtemisDevice device)
|
||||||
@ -27,7 +21,7 @@ public class CustomPathLayoutProvider : ILayoutProvider
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsMatch(ArtemisDevice device)
|
public bool IsMatch(ArtemisDevice device)
|
||||||
{
|
{
|
||||||
return device.LayoutSelection.Type == LAYOUT_TYPE;
|
return device.LayoutSelection.Type == LayoutType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -37,7 +31,7 @@ public class CustomPathLayoutProvider : ILayoutProvider
|
|||||||
/// <param name="path">The path to the custom layout.</param>
|
/// <param name="path">The path to the custom layout.</param>
|
||||||
public void ConfigureDevice(ArtemisDevice device, string? path)
|
public void ConfigureDevice(ArtemisDevice device, string? path)
|
||||||
{
|
{
|
||||||
device.LayoutSelection.Type = LAYOUT_TYPE;
|
device.LayoutSelection.Type = LayoutType;
|
||||||
device.LayoutSelection.Parameter = path;
|
device.LayoutSelection.Parameter = path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,14 +1,8 @@
|
|||||||
namespace Artemis.Core.Providers;
|
namespace Artemis.Core.Providers;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a layout provider that loads a layout from the plugin and falls back to a default layout.
|
|
||||||
/// </summary>
|
|
||||||
public class DefaultLayoutProvider : ILayoutProvider
|
public class DefaultLayoutProvider : ILayoutProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
public static string LayoutType = "Default";
|
||||||
/// The layout type of this layout provider.
|
|
||||||
/// </summary>
|
|
||||||
public const string LAYOUT_TYPE = "Default";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ArtemisLayout? GetDeviceLayout(ArtemisDevice device)
|
public ArtemisLayout? GetDeviceLayout(ArtemisDevice device)
|
||||||
@ -32,7 +26,7 @@ public class DefaultLayoutProvider : ILayoutProvider
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsMatch(ArtemisDevice device)
|
public bool IsMatch(ArtemisDevice device)
|
||||||
{
|
{
|
||||||
return device.LayoutSelection.Type == LAYOUT_TYPE;
|
return device.LayoutSelection.Type == LayoutType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -41,7 +35,7 @@ public class DefaultLayoutProvider : ILayoutProvider
|
|||||||
/// <param name="device">The device to apply the provider to.</param>
|
/// <param name="device">The device to apply the provider to.</param>
|
||||||
public void ConfigureDevice(ArtemisDevice device)
|
public void ConfigureDevice(ArtemisDevice device)
|
||||||
{
|
{
|
||||||
device.LayoutSelection.Type = LAYOUT_TYPE;
|
device.LayoutSelection.Type = LayoutType;
|
||||||
device.LayoutSelection.Parameter = null;
|
device.LayoutSelection.Parameter = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12,17 +12,6 @@ public interface ILayoutProvider
|
|||||||
/// <returns>The resulting layout if one was available; otherwise <see langword="null" />.</returns>
|
/// <returns>The resulting layout if one was available; otherwise <see langword="null" />.</returns>
|
||||||
ArtemisLayout? GetDeviceLayout(ArtemisDevice device);
|
ArtemisLayout? GetDeviceLayout(ArtemisDevice device);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Applies the layout to the provided device.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="device">The device to apply to.</param>
|
|
||||||
/// <param name="layout">The layout to apply.</param>
|
|
||||||
void ApplyLayout(ArtemisDevice device, ArtemisLayout layout);
|
void ApplyLayout(ArtemisDevice device, ArtemisLayout layout);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether the provided device is configured to use this layout provider.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="device">The device to check.</param>
|
|
||||||
/// <returns>A value indicating whether the provided device is configured to use this layout provider.</returns>
|
|
||||||
bool IsMatch(ArtemisDevice device);
|
bool IsMatch(ArtemisDevice device);
|
||||||
}
|
}
|
||||||
@ -1,14 +1,8 @@
|
|||||||
namespace Artemis.Core.Providers;
|
namespace Artemis.Core.Providers;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a layout provider that does not load a layout.
|
|
||||||
/// </summary>
|
|
||||||
public class NoneLayoutProvider : ILayoutProvider
|
public class NoneLayoutProvider : ILayoutProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
public static string LayoutType = "None";
|
||||||
/// The layout type of this layout provider.
|
|
||||||
/// </summary>
|
|
||||||
public const string LAYOUT_TYPE = "None";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ArtemisLayout? GetDeviceLayout(ArtemisDevice device)
|
public ArtemisLayout? GetDeviceLayout(ArtemisDevice device)
|
||||||
@ -25,7 +19,7 @@ public class NoneLayoutProvider : ILayoutProvider
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsMatch(ArtemisDevice device)
|
public bool IsMatch(ArtemisDevice device)
|
||||||
{
|
{
|
||||||
return device.LayoutSelection.Type == LAYOUT_TYPE;
|
return device.LayoutSelection.Type == LayoutType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -34,7 +28,7 @@ public class NoneLayoutProvider : ILayoutProvider
|
|||||||
/// <param name="device">The device to apply the provider to.</param>
|
/// <param name="device">The device to apply the provider to.</param>
|
||||||
public void ConfigureDevice(ArtemisDevice device)
|
public void ConfigureDevice(ArtemisDevice device)
|
||||||
{
|
{
|
||||||
device.LayoutSelection.Type = LAYOUT_TYPE;
|
device.LayoutSelection.Type = LayoutType;
|
||||||
device.LayoutSelection.Parameter = null;
|
device.LayoutSelection.Parameter = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Artemis.Storage.Entities.Profile.Nodes;
|
using Artemis.Storage.Entities.Profile.Nodes;
|
||||||
|
using DryIoc;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
@ -11,8 +13,31 @@ namespace Artemis.Core.Services;
|
|||||||
|
|
||||||
internal class NodeService : INodeService
|
internal class NodeService : INodeService
|
||||||
{
|
{
|
||||||
|
#region Constants
|
||||||
|
|
||||||
|
private static readonly Type TypeNode = typeof(INode);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private readonly IContainer _container;
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public NodeService(IContainer container)
|
||||||
|
{
|
||||||
|
_container = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
public IEnumerable<NodeData> AvailableNodes => NodeTypeStore.GetAll();
|
public IEnumerable<NodeData> AvailableNodes => NodeTypeStore.GetAll();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public List<Type> GetRegisteredTypes()
|
public List<Type> GetRegisteredTypes()
|
||||||
{
|
{
|
||||||
@ -28,7 +53,7 @@ internal class NodeService : INodeService
|
|||||||
|
|
||||||
// Objects represent an input that can take any type, these are hardcoded white
|
// Objects represent an input that can take any type, these are hardcoded white
|
||||||
if (type == typeof(object))
|
if (type == typeof(object))
|
||||||
return new TypeColorRegistration(type, new SKColor(255, 255, 255, 255), Constants.CorePluginFeature);
|
return new TypeColorRegistration(type, new SKColor(255, 255, 255, 255), Constants.CorePlugin);
|
||||||
|
|
||||||
// Come up with a random color based on the type name that should be the same each time
|
// Come up with a random color based on the type name that should be the same each time
|
||||||
MD5 md5Hasher = MD5.Create();
|
MD5 md5Hasher = MD5.Create();
|
||||||
@ -36,7 +61,32 @@ internal class NodeService : INodeService
|
|||||||
int hash = BitConverter.ToInt32(hashed, 0);
|
int hash = BitConverter.ToInt32(hashed, 0);
|
||||||
|
|
||||||
SKColor baseColor = SKColor.FromHsl(hash % 255, 50 + hash % 50, 50);
|
SKColor baseColor = SKColor.FromHsl(hash % 255, 50 + hash % 50, 50);
|
||||||
return new TypeColorRegistration(type, baseColor, Constants.CorePluginFeature);
|
return new TypeColorRegistration(type, baseColor, Constants.CorePlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodeTypeRegistration RegisterNodeType(Plugin plugin, Type nodeType)
|
||||||
|
{
|
||||||
|
if (plugin == null) throw new ArgumentNullException(nameof(plugin));
|
||||||
|
if (nodeType == null) throw new ArgumentNullException(nameof(nodeType));
|
||||||
|
|
||||||
|
if (!TypeNode.IsAssignableFrom(nodeType)) throw new ArgumentException("Node has to be a base type of the Node-Type.", nameof(nodeType));
|
||||||
|
|
||||||
|
NodeAttribute? nodeAttribute = nodeType.GetCustomAttribute<NodeAttribute>();
|
||||||
|
string name = nodeAttribute?.Name ?? nodeType.Name;
|
||||||
|
string description = nodeAttribute?.Description ?? string.Empty;
|
||||||
|
string category = nodeAttribute?.Category ?? string.Empty;
|
||||||
|
string helpUrl = nodeAttribute?.HelpUrl ?? string.Empty;
|
||||||
|
|
||||||
|
NodeData nodeData = new(plugin, nodeType, name, description, category, helpUrl, nodeAttribute?.InputType, nodeAttribute?.OutputType, (s, e) => CreateNode(s, e, nodeType));
|
||||||
|
return NodeTypeStore.Add(nodeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeColorRegistration RegisterTypeColor(Plugin plugin, Type type, SKColor color)
|
||||||
|
{
|
||||||
|
if (plugin == null) throw new ArgumentNullException(nameof(plugin));
|
||||||
|
if (type == null) throw new ArgumentNullException(nameof(type));
|
||||||
|
|
||||||
|
return NodeTypeStore.AddColor(type, color, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ExportScript(NodeScript nodeScript)
|
public string ExportScript(NodeScript nodeScript)
|
||||||
@ -53,6 +103,33 @@ internal class NodeService : INodeService
|
|||||||
|
|
||||||
target.LoadFromEntity(entity);
|
target.LoadFromEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private INode CreateNode(INodeScript script, NodeEntity? entity, Type nodeType)
|
||||||
|
{
|
||||||
|
INode node = _container.Resolve(nodeType) as INode ?? throw new InvalidOperationException($"Node {nodeType} is not an INode");
|
||||||
|
if (node is Node concreteNode)
|
||||||
|
concreteNode.Container = _container;
|
||||||
|
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
node.X = entity.X;
|
||||||
|
node.Y = entity.Y;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (node is Node nodeImplementation)
|
||||||
|
nodeImplementation.DeserializeStorage(entity.Storage);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node.TryInitialize(script);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -76,6 +153,21 @@ public interface INodeService : IArtemisService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
TypeColorRegistration GetTypeColorRegistration(Type type);
|
TypeColorRegistration GetTypeColorRegistration(Type type);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a node of the provided <paramref name="nodeType" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin">The plugin the node belongs to</param>
|
||||||
|
/// <param name="nodeType">The type of node to initialize</param>
|
||||||
|
NodeTypeRegistration RegisterNodeType(Plugin plugin, Type nodeType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a type with a provided color for use in the node editor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin">The plugin making the registration</param>
|
||||||
|
/// <param name="type">The type to associate the color with</param>
|
||||||
|
/// <param name="color">The color to display</param>
|
||||||
|
TypeColorRegistration RegisterTypeColor(Plugin plugin, Type type, SKColor color);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Exports the provided node script to JSON.
|
/// Exports the provided node script to JSON.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -7,9 +7,6 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace Artemis.Core.Services;
|
namespace Artemis.Core.Services;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a monitor that efficiently keeps track of running processes.
|
|
||||||
/// </summary>
|
|
||||||
public static partial class ProcessMonitor
|
public static partial class ProcessMonitor
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
@ -18,11 +15,8 @@ public static partial class ProcessMonitor
|
|||||||
|
|
||||||
private static Timer? _timer;
|
private static Timer? _timer;
|
||||||
|
|
||||||
private static readonly Dictionary<int, ProcessInfo> _processes = new();
|
private static Dictionary<int, ProcessInfo> _processes = new();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets an immutable array of the current processes.
|
|
||||||
/// </summary>
|
|
||||||
public static ImmutableArray<ProcessInfo> Processes
|
public static ImmutableArray<ProcessInfo> Processes
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -31,17 +25,9 @@ public static partial class ProcessMonitor
|
|||||||
return _processes.Values.ToImmutableArray();
|
return _processes.Values.ToImmutableArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the date time at which the last update took place.
|
|
||||||
/// </summary>
|
|
||||||
public static DateTime LastUpdate { get; private set; }
|
public static DateTime LastUpdate { get; private set; }
|
||||||
|
|
||||||
private static TimeSpan _updateInterval = TimeSpan.FromSeconds(1);
|
private static TimeSpan _updateInterval = TimeSpan.FromSeconds(1);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the interval at which to update the list of processes.
|
|
||||||
/// </summary>
|
|
||||||
public static TimeSpan UpdateInterval
|
public static TimeSpan UpdateInterval
|
||||||
{
|
{
|
||||||
get => _updateInterval;
|
get => _updateInterval;
|
||||||
@ -54,9 +40,6 @@ public static partial class ProcessMonitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the monitoring has started.
|
|
||||||
/// </summary>
|
|
||||||
public static bool IsStarted
|
public static bool IsStarted
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -70,14 +53,7 @@ public static partial class ProcessMonitor
|
|||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when a new process is started.
|
|
||||||
/// </summary>
|
|
||||||
public static event EventHandler<ProcessEventArgs>? ProcessStarted;
|
public static event EventHandler<ProcessEventArgs>? ProcessStarted;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when a process is stopped.
|
|
||||||
/// </summary>
|
|
||||||
public static event EventHandler<ProcessEventArgs>? ProcessStopped;
|
public static event EventHandler<ProcessEventArgs>? ProcessStopped;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -93,9 +69,6 @@ public static partial class ProcessMonitor
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Starts monitoring processes.
|
|
||||||
/// </summary>
|
|
||||||
public static void Start()
|
public static void Start()
|
||||||
{
|
{
|
||||||
lock (LOCK)
|
lock (LOCK)
|
||||||
@ -114,9 +87,6 @@ public static partial class ProcessMonitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stops monitoring processes.
|
|
||||||
/// </summary>
|
|
||||||
public static void Stop()
|
public static void Stop()
|
||||||
{
|
{
|
||||||
lock (LOCK)
|
lock (LOCK)
|
||||||
@ -130,7 +100,7 @@ public static partial class ProcessMonitor
|
|||||||
FreeBuffer();
|
FreeBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns whether the specified process is running
|
/// Returns whether the specified process is running
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -141,7 +111,7 @@ public static partial class ProcessMonitor
|
|||||||
{
|
{
|
||||||
if (!IsStarted || (processName == null && processLocation == null))
|
if (!IsStarted || (processName == null && processLocation == null))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
lock (LOCK)
|
lock (LOCK)
|
||||||
{
|
{
|
||||||
return _processes.Values.Any(x => IsProcessRunning(x, processName, processLocation));
|
return _processes.Values.Any(x => IsProcessRunning(x, processName, processLocation));
|
||||||
@ -160,19 +130,19 @@ public static partial class ProcessMonitor
|
|||||||
OnProcessStopped(info);
|
OnProcessStopped(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsProcessRunning(ProcessInfo info, string? processName, string? processLocation)
|
private static bool IsProcessRunning(ProcessInfo info, string? processName, string? processLocation)
|
||||||
{
|
{
|
||||||
if (processName != null && processLocation != null)
|
if (processName != null && processLocation != null)
|
||||||
return string.Equals(info.ProcessName, processName, StringComparison.InvariantCultureIgnoreCase) &&
|
return string.Equals(info.ProcessName, processName, StringComparison.InvariantCultureIgnoreCase) &&
|
||||||
string.Equals(Path.GetDirectoryName(info.Executable), processLocation, StringComparison.InvariantCultureIgnoreCase);
|
string.Equals(Path.GetDirectoryName(info.Executable), processLocation, StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
|
||||||
if (processName != null)
|
if (processName != null)
|
||||||
return string.Equals(info.ProcessName, processName, StringComparison.InvariantCultureIgnoreCase);
|
return string.Equals(info.ProcessName, processName, StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
|
||||||
if (processLocation != null)
|
if (processLocation != null)
|
||||||
return string.Equals(Path.GetDirectoryName(info.Executable), processLocation, StringComparison.InvariantCultureIgnoreCase);
|
return string.Equals(Path.GetDirectoryName(info.Executable), processLocation, StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,10 +152,7 @@ public static partial class ProcessMonitor
|
|||||||
{
|
{
|
||||||
ProcessStarted?.Invoke(null, new ProcessEventArgs(processInfo));
|
ProcessStarted?.Invoke(null, new ProcessEventArgs(processInfo));
|
||||||
}
|
}
|
||||||
catch
|
catch { /* Subscribers are idiots! */ }
|
||||||
{
|
|
||||||
/* Subscribers are idiots! */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnProcessStopped(ProcessInfo processInfo)
|
private static void OnProcessStopped(ProcessInfo processInfo)
|
||||||
@ -194,10 +161,7 @@ public static partial class ProcessMonitor
|
|||||||
{
|
{
|
||||||
ProcessStopped?.Invoke(null, new ProcessEventArgs(processInfo));
|
ProcessStopped?.Invoke(null, new ProcessEventArgs(processInfo));
|
||||||
}
|
}
|
||||||
catch
|
catch { /* Subscribers are idiots! */ }
|
||||||
{
|
|
||||||
/* Subscribers are idiots! */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -42,7 +42,6 @@ internal class LayerBrushService : ILayerBrushService
|
|||||||
BrushType = "SolidBrush"
|
BrushType = "SolidBrush"
|
||||||
});
|
});
|
||||||
|
|
||||||
defaultReference.Value ??= new LayerBrushReference();
|
|
||||||
defaultReference.Value.LayerBrushProviderId ??= "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba";
|
defaultReference.Value.LayerBrushProviderId ??= "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba";
|
||||||
defaultReference.Value.BrushType ??= "SolidBrush";
|
defaultReference.Value.BrushType ??= "SolidBrush";
|
||||||
return LayerBrushStore.Get(defaultReference.Value.LayerBrushProviderId, defaultReference.Value.BrushType)?.LayerBrushDescriptor;
|
return LayerBrushStore.Get(defaultReference.Value.LayerBrushProviderId, defaultReference.Value.BrushType)?.LayerBrushDescriptor;
|
||||||
|
|||||||
@ -8,10 +8,8 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.Storage.Migrations;
|
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
@ -26,10 +24,9 @@ internal class ProfileService : IProfileService
|
|||||||
private readonly List<ArtemisKeyboardKeyEventArgs> _pendingKeyboardEvents = new();
|
private readonly List<ArtemisKeyboardKeyEventArgs> _pendingKeyboardEvents = new();
|
||||||
private readonly List<ProfileCategory> _profileCategories;
|
private readonly List<ProfileCategory> _profileCategories;
|
||||||
private readonly IProfileRepository _profileRepository;
|
private readonly IProfileRepository _profileRepository;
|
||||||
private readonly List<IProfileMigration> _profileMigrators;
|
|
||||||
private readonly List<Exception> _renderExceptions = new();
|
private readonly List<Exception> _renderExceptions = new();
|
||||||
private readonly List<Exception> _updateExceptions = new();
|
private readonly List<Exception> _updateExceptions = new();
|
||||||
|
|
||||||
private DateTime _lastRenderExceptionLog;
|
private DateTime _lastRenderExceptionLog;
|
||||||
private DateTime _lastUpdateExceptionLog;
|
private DateTime _lastUpdateExceptionLog;
|
||||||
|
|
||||||
@ -38,15 +35,13 @@ internal class ProfileService : IProfileService
|
|||||||
IPluginManagementService pluginManagementService,
|
IPluginManagementService pluginManagementService,
|
||||||
IInputService inputService,
|
IInputService inputService,
|
||||||
IDeviceService deviceService,
|
IDeviceService deviceService,
|
||||||
IProfileRepository profileRepository,
|
IProfileRepository profileRepository)
|
||||||
List<IProfileMigration> profileMigrators)
|
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_profileCategoryRepository = profileCategoryRepository;
|
_profileCategoryRepository = profileCategoryRepository;
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_deviceService = deviceService;
|
_deviceService = deviceService;
|
||||||
_profileRepository = profileRepository;
|
_profileRepository = profileRepository;
|
||||||
_profileMigrators = profileMigrators;
|
|
||||||
_profileCategories = new List<ProfileCategory>(_profileCategoryRepository.GetAll().Select(c => new ProfileCategory(c)).OrderBy(c => c.Order));
|
_profileCategories = new List<ProfileCategory>(_profileCategoryRepository.GetAll().Select(c => new ProfileCategory(c)).OrderBy(c => c.Order));
|
||||||
|
|
||||||
_deviceService.LedsChanged += DeviceServiceOnLedsChanged;
|
_deviceService.LedsChanged += DeviceServiceOnLedsChanged;
|
||||||
@ -63,7 +58,7 @@ internal class ProfileService : IProfileService
|
|||||||
public ProfileConfiguration? FocusProfile { get; set; }
|
public ProfileConfiguration? FocusProfile { get; set; }
|
||||||
public ProfileElement? FocusProfileElement { get; set; }
|
public ProfileElement? FocusProfileElement { get; set; }
|
||||||
public bool UpdateFocusProfile { get; set; }
|
public bool UpdateFocusProfile { get; set; }
|
||||||
|
|
||||||
public bool ProfileRenderingDisabled { get; set; }
|
public bool ProfileRenderingDisabled { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -226,7 +221,7 @@ internal class ProfileService : IProfileService
|
|||||||
return profileConfiguration.Profile;
|
return profileConfiguration.Profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileEntity? profileEntity;
|
ProfileEntity profileEntity;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
||||||
@ -285,7 +280,7 @@ internal class ProfileService : IProfileService
|
|||||||
{
|
{
|
||||||
DeactivateProfile(profileConfiguration);
|
DeactivateProfile(profileConfiguration);
|
||||||
|
|
||||||
ProfileEntity? profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
ProfileEntity profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
||||||
if (profileEntity == null)
|
if (profileEntity == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -358,7 +353,7 @@ internal class ProfileService : IProfileService
|
|||||||
|
|
||||||
DeactivateProfile(profileConfiguration);
|
DeactivateProfile(profileConfiguration);
|
||||||
SaveProfileCategory(profileConfiguration.Category);
|
SaveProfileCategory(profileConfiguration.Category);
|
||||||
ProfileEntity? profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
ProfileEntity profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
||||||
if (profileEntity != null)
|
if (profileEntity != null)
|
||||||
_profileRepository.Remove(profileEntity);
|
_profileRepository.Remove(profileEntity);
|
||||||
|
|
||||||
@ -466,12 +461,7 @@ internal class ProfileService : IProfileService
|
|||||||
|
|
||||||
await using Stream profileStream = profileEntry.Open();
|
await using Stream profileStream = profileEntry.Open();
|
||||||
using StreamReader profileReader = new(profileStream);
|
using StreamReader profileReader = new(profileStream);
|
||||||
JObject? profileJson = JsonConvert.DeserializeObject<JObject>(await profileReader.ReadToEndAsync(), IProfileService.ExportSettings);
|
ProfileEntity? profileEntity = JsonConvert.DeserializeObject<ProfileEntity>(await profileReader.ReadToEndAsync(), IProfileService.ExportSettings);
|
||||||
|
|
||||||
// Before deserializing, apply any pending migrations
|
|
||||||
MigrateProfile(configurationEntity, profileJson);
|
|
||||||
|
|
||||||
ProfileEntity? profileEntity = profileJson?.ToObject<ProfileEntity>(JsonSerializer.Create(IProfileService.ExportSettings));
|
|
||||||
if (profileEntity == null)
|
if (profileEntity == null)
|
||||||
throw new ArtemisCoreException("Could not import profile, failed to deserialize profile.json");
|
throw new ArtemisCoreException("Could not import profile, failed to deserialize profile.json");
|
||||||
|
|
||||||
@ -524,10 +514,10 @@ internal class ProfileService : IProfileService
|
|||||||
public async Task<ProfileConfiguration> OverwriteProfile(MemoryStream archiveStream, ProfileConfiguration profileConfiguration)
|
public async Task<ProfileConfiguration> OverwriteProfile(MemoryStream archiveStream, ProfileConfiguration profileConfiguration)
|
||||||
{
|
{
|
||||||
ProfileConfiguration imported = await ImportProfile(archiveStream, profileConfiguration.Category, true, true, null, profileConfiguration.Order + 1);
|
ProfileConfiguration imported = await ImportProfile(archiveStream, profileConfiguration.Category, true, true, null, profileConfiguration.Order + 1);
|
||||||
|
|
||||||
DeleteProfile(profileConfiguration);
|
DeleteProfile(profileConfiguration);
|
||||||
SaveProfileCategory(imported.Category);
|
SaveProfileCategory(imported.Category);
|
||||||
|
|
||||||
return imported;
|
return imported;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,21 +545,6 @@ internal class ProfileService : IProfileService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MigrateProfile(ProfileConfigurationEntity configurationEntity, JObject? profileJson)
|
|
||||||
{
|
|
||||||
if (profileJson == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (IProfileMigration profileMigrator in _profileMigrators.OrderBy(m => m.Version))
|
|
||||||
{
|
|
||||||
if (profileMigrator.Version <= configurationEntity.Version)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
profileMigrator.Migrate(profileJson);
|
|
||||||
configurationEntity.Version = profileMigrator.Version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Populates all missing LEDs on all currently active profiles
|
/// Populates all missing LEDs on all currently active profiles
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -100,7 +100,7 @@ public interface IWebServerService : IArtemisService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes an existing Web API controller and restarts the web server
|
/// Removes an existing Web API controller and restarts the web server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="registration">The registration of the controller to remove.</param>
|
/// <typeparam name="T">The type of Web API controller to remove</typeparam>
|
||||||
void RemoveController(WebApiControllerRegistration registration);
|
void RemoveController(WebApiControllerRegistration registration);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -13,13 +13,16 @@ internal class NodeTypeStore
|
|||||||
|
|
||||||
public static NodeTypeRegistration Add(NodeData nodeData)
|
public static NodeTypeRegistration Add(NodeData nodeData)
|
||||||
{
|
{
|
||||||
|
if (nodeData.Plugin == null)
|
||||||
|
throw new ArtemisCoreException("Cannot add a data binding modifier type that is not associated with a plugin");
|
||||||
|
|
||||||
NodeTypeRegistration typeRegistration;
|
NodeTypeRegistration typeRegistration;
|
||||||
lock (Registrations)
|
lock (Registrations)
|
||||||
{
|
{
|
||||||
if (Registrations.Any(r => r.NodeData == nodeData))
|
if (Registrations.Any(r => r.NodeData == nodeData))
|
||||||
throw new ArtemisCoreException($"Data binding modifier type store already contains modifier '{nodeData.Name}'");
|
throw new ArtemisCoreException($"Data binding modifier type store already contains modifier '{nodeData.Name}'");
|
||||||
|
|
||||||
typeRegistration = new NodeTypeRegistration(nodeData, nodeData.Provider) {IsInStore = true};
|
typeRegistration = new NodeTypeRegistration(nodeData, nodeData.Plugin) {IsInStore = true};
|
||||||
Registrations.Add(typeRegistration);
|
Registrations.Add(typeRegistration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,12 +60,24 @@ internal class NodeTypeStore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TypeColorRegistration AddColor(Type type, SKColor color, PluginFeature pluginFeature)
|
public static Plugin? GetPlugin(INode node)
|
||||||
|
{
|
||||||
|
Type nodeType = node.GetType();
|
||||||
|
lock (Registrations)
|
||||||
|
{
|
||||||
|
return Registrations.FirstOrDefault(r => r.NodeData.Type == nodeType)?.Plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TypeColorRegistration AddColor(Type type, SKColor color, Plugin plugin)
|
||||||
{
|
{
|
||||||
TypeColorRegistration typeColorRegistration;
|
TypeColorRegistration typeColorRegistration;
|
||||||
lock (ColorRegistrations)
|
lock (ColorRegistrations)
|
||||||
{
|
{
|
||||||
typeColorRegistration = new TypeColorRegistration(type, color, pluginFeature) {IsInStore = true};
|
if (ColorRegistrations.Any(r => r.Type == type))
|
||||||
|
throw new ArtemisCoreException($"Node color store already contains a color for '{type.Name}'");
|
||||||
|
|
||||||
|
typeColorRegistration = new TypeColorRegistration(type, color, plugin) {IsInStore = true};
|
||||||
ColorRegistrations.Add(typeColorRegistration);
|
ColorRegistrations.Add(typeColorRegistration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,12 +9,12 @@ namespace Artemis.Core;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class NodeTypeRegistration
|
public class NodeTypeRegistration
|
||||||
{
|
{
|
||||||
internal NodeTypeRegistration(NodeData nodeData, PluginFeature pluginFeature)
|
internal NodeTypeRegistration(NodeData nodeData, Plugin plugin)
|
||||||
{
|
{
|
||||||
NodeData = nodeData;
|
NodeData = nodeData;
|
||||||
PluginFeature = pluginFeature;
|
Plugin = plugin;
|
||||||
|
|
||||||
PluginFeature.Disabled += OnDisabled;
|
Plugin.Disabled += OnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -23,9 +23,9 @@ public class NodeTypeRegistration
|
|||||||
public NodeData NodeData { get; }
|
public NodeData NodeData { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin feature the node is associated with
|
/// Gets the plugin the node is associated with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginFeature PluginFeature { get; }
|
public Plugin Plugin { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||||
@ -39,12 +39,12 @@ public class NodeTypeRegistration
|
|||||||
/// <returns><see langword="true" /> if the entity matches this registration; otherwise <see langword="false" />.</returns>
|
/// <returns><see langword="true" /> if the entity matches this registration; otherwise <see langword="false" />.</returns>
|
||||||
public bool MatchesEntity(NodeEntity entity)
|
public bool MatchesEntity(NodeEntity entity)
|
||||||
{
|
{
|
||||||
return PluginFeature.Id == entity.ProviderId && NodeData.Type.Name == entity.Type;
|
return Plugin.Guid == entity.PluginId && NodeData.Type.Name == entity.Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDisabled(object? sender, EventArgs e)
|
private void OnDisabled(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
PluginFeature.Disabled -= OnDisabled;
|
Plugin.Disabled -= OnDisabled;
|
||||||
if (IsInStore)
|
if (IsInStore)
|
||||||
NodeTypeStore.Remove(this);
|
NodeTypeStore.Remove(this);
|
||||||
}
|
}
|
||||||
@ -55,13 +55,13 @@ public class NodeTypeRegistration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class TypeColorRegistration
|
public class TypeColorRegistration
|
||||||
{
|
{
|
||||||
internal TypeColorRegistration(Type type, SKColor color, PluginFeature pluginFeature)
|
internal TypeColorRegistration(Type type, SKColor color, Plugin plugin)
|
||||||
{
|
{
|
||||||
Type = type;
|
Type = type;
|
||||||
Color = color;
|
Color = color;
|
||||||
PluginFeature = pluginFeature;
|
Plugin = plugin;
|
||||||
|
|
||||||
PluginFeature.Disabled += OnDisabled;
|
Plugin.Disabled += OnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -80,9 +80,9 @@ public class TypeColorRegistration
|
|||||||
public SKColor DarkenedColor => Color.Darken(0.35f);
|
public SKColor DarkenedColor => Color.Darken(0.35f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin feature this type color is associated with
|
/// Gets the plugin type color is associated with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginFeature PluginFeature { get; }
|
public Plugin Plugin { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||||
@ -91,7 +91,7 @@ public class TypeColorRegistration
|
|||||||
|
|
||||||
private void OnDisabled(object? sender, EventArgs e)
|
private void OnDisabled(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
PluginFeature.Disabled -= OnDisabled;
|
Plugin.Disabled -= OnDisabled;
|
||||||
if (IsInStore)
|
if (IsInStore)
|
||||||
NodeTypeStore.RemoveColor(this);
|
NodeTypeStore.RemoveColor(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,11 +14,6 @@ public interface INode : INotifyPropertyChanged, IBreakableModel
|
|||||||
/// Gets or sets the ID of the node.
|
/// Gets or sets the ID of the node.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Guid Id { get; set; }
|
Guid Id { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the node data with information about this node
|
|
||||||
/// </summary>
|
|
||||||
NodeData? NodeData { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the node
|
/// Gets the name of the node
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.Core.Nodes;
|
|
||||||
using Artemis.Storage.Entities.Profile.Nodes;
|
using Artemis.Storage.Entities.Profile.Nodes;
|
||||||
|
|
||||||
namespace Artemis.Core;
|
namespace Artemis.Core;
|
||||||
@ -11,9 +10,9 @@ public class NodeData
|
|||||||
{
|
{
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
internal NodeData(NodeProvider provider, Type type, string name, string description, string category, string helpUrl, Type? inputType, Type? outputType)
|
internal NodeData(Plugin plugin, Type type, string name, string description, string category, string helpUrl, Type? inputType, Type? outputType, Func<INodeScript, NodeEntity?, INode> create)
|
||||||
{
|
{
|
||||||
Provider = provider;
|
Plugin = plugin;
|
||||||
Type = type;
|
Type = type;
|
||||||
Name = name;
|
Name = name;
|
||||||
Description = description;
|
Description = description;
|
||||||
@ -21,6 +20,7 @@ public class NodeData
|
|||||||
HelpUrl = helpUrl;
|
HelpUrl = helpUrl;
|
||||||
InputType = inputType;
|
InputType = inputType;
|
||||||
OutputType = outputType;
|
OutputType = outputType;
|
||||||
|
_create = create;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -35,31 +35,14 @@ public class NodeData
|
|||||||
/// <returns>The returning node of type <see cref="Type" /></returns>
|
/// <returns>The returning node of type <see cref="Type" /></returns>
|
||||||
public INode CreateNode(INodeScript script, NodeEntity? entity)
|
public INode CreateNode(INodeScript script, NodeEntity? entity)
|
||||||
{
|
{
|
||||||
INode node = (INode) Provider.Plugin.Resolve(Type);
|
INode node = _create(script, entity);
|
||||||
node.NodeData = this;
|
|
||||||
if (string.IsNullOrWhiteSpace(node.Name))
|
if (string.IsNullOrWhiteSpace(node.Name))
|
||||||
node.Name = Name;
|
node.Name = Name;
|
||||||
if (string.IsNullOrWhiteSpace(node.Description))
|
if (string.IsNullOrWhiteSpace(node.Description))
|
||||||
node.Description = Description;
|
node.Description = Description;
|
||||||
if (string.IsNullOrWhiteSpace(node.HelpUrl))
|
if (string.IsNullOrWhiteSpace(node.HelpUrl))
|
||||||
node.HelpUrl = HelpUrl;
|
node.HelpUrl = HelpUrl;
|
||||||
|
|
||||||
if (entity != null)
|
|
||||||
{
|
|
||||||
node.X = entity.X;
|
|
||||||
node.Y = entity.Y;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (node is Node nodeImplementation)
|
|
||||||
nodeImplementation.DeserializeStorage(entity.Storage);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
node.TryInitialize(script);
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,11 +91,11 @@ public class NodeData
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the node provider that provided this node data
|
/// Gets the plugin that provided this node data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NodeProvider Provider { get; }
|
public Plugin Plugin { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type of <see cref="INode" /> this data represents
|
/// Gets the type of <see cref="INode" /> this data represents
|
||||||
@ -149,5 +132,7 @@ public class NodeData
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Type? OutputType { get; }
|
public Type? OutputType { get; }
|
||||||
|
|
||||||
|
private readonly Func<INodeScript, NodeEntity?, INode> _create;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@ -161,7 +161,6 @@ public abstract class NodeScript : CorePropertyChanged, INodeScript
|
|||||||
{
|
{
|
||||||
foreach (INode node in _nodes)
|
foreach (INode node in _nodes)
|
||||||
{
|
{
|
||||||
// ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins
|
|
||||||
if (node is IDisposable disposable)
|
if (node is IDisposable disposable)
|
||||||
disposable.Dispose();
|
disposable.Dispose();
|
||||||
}
|
}
|
||||||
@ -182,7 +181,6 @@ public abstract class NodeScript : CorePropertyChanged, INodeScript
|
|||||||
foreach (INode removeNode in removeNodes)
|
foreach (INode removeNode in removeNodes)
|
||||||
{
|
{
|
||||||
RemoveNode(removeNode);
|
RemoveNode(removeNode);
|
||||||
// ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins
|
|
||||||
if (removeNode is IDisposable disposable)
|
if (removeNode is IDisposable disposable)
|
||||||
disposable.Dispose();
|
disposable.Dispose();
|
||||||
}
|
}
|
||||||
@ -314,7 +312,7 @@ public abstract class NodeScript : CorePropertyChanged, INodeScript
|
|||||||
NodeEntity nodeEntity = new()
|
NodeEntity nodeEntity = new()
|
||||||
{
|
{
|
||||||
Id = node.Id,
|
Id = node.Id,
|
||||||
ProviderId = node.NodeData?.Provider.Id ?? Constants.CorePluginFeature.Id,
|
PluginId = NodeTypeStore.GetPlugin(node)?.Guid ?? Constants.CorePlugin.Guid,
|
||||||
Type = node.GetType().Name,
|
Type = node.GetType().Name,
|
||||||
X = node.X,
|
X = node.X,
|
||||||
Y = node.Y,
|
Y = node.Y,
|
||||||
|
|||||||
@ -41,9 +41,6 @@ public abstract class Node : BreakableModel, INode
|
|||||||
set => SetAndNotify(ref _id, value);
|
set => SetAndNotify(ref _id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public NodeData? NodeData { get; set; }
|
|
||||||
|
|
||||||
private string _name;
|
private string _name;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -107,6 +104,8 @@ public abstract class Node : BreakableModel, INode
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string BrokenDisplayName => Name;
|
public override string BrokenDisplayName => Name;
|
||||||
|
|
||||||
|
internal IContainer Container { get; set; } = null!;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Construtors
|
#region Construtors
|
||||||
|
|||||||
@ -25,9 +25,7 @@ public abstract class Node<TStorage, TViewModel> : Node<TStorage>, ICustomViewMo
|
|||||||
/// <param name="nodeScript"></param>
|
/// <param name="nodeScript"></param>
|
||||||
public virtual TViewModel GetViewModel(NodeScript nodeScript)
|
public virtual TViewModel GetViewModel(NodeScript nodeScript)
|
||||||
{
|
{
|
||||||
if (NodeData == null)
|
return Container.Resolve<TViewModel>(args: new object[] {this, nodeScript});
|
||||||
throw new ArtemisCoreException("Nodes without node data (default nodes or exit nodes) cannot have custom view models");
|
|
||||||
return NodeData.Provider.Plugin.Container.Resolve<TViewModel>(args: new object[] {this, nodeScript});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<PreserveCompilationContext>false</PreserveCompilationContext>
|
<PreserveCompilationContext>false</PreserveCompilationContext>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="LiteDB" />
|
<PackageReference Include="LiteDB" Version="5.0.18" />
|
||||||
<PackageReference Include="Serilog" />
|
<PackageReference Include="Serilog" Version="3.1.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -11,7 +11,7 @@ public class QueuedActionEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public string Type { get; set; } = string.Empty;
|
public string Type { get; set; }
|
||||||
public DateTimeOffset CreatedAt { get; set; }
|
public DateTimeOffset CreatedAt { get; set; }
|
||||||
|
|
||||||
public Dictionary<string, object> Parameters { get; set; }
|
public Dictionary<string, object> Parameters { get; set; }
|
||||||
|
|||||||
@ -6,6 +6,6 @@ public class ReleaseEntity
|
|||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
public string Version { get; set; } = string.Empty;
|
public string Version { get; set; }
|
||||||
public DateTimeOffset? InstalledAt { get; set; }
|
public DateTimeOffset? InstalledAt { get; set; }
|
||||||
}
|
}
|
||||||
@ -6,7 +6,7 @@ public class ScriptConfigurationEntity
|
|||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; }
|
||||||
public string ScriptingProviderId { get; set; } = string.Empty;
|
public string ScriptingProviderId { get; set; }
|
||||||
public string? ScriptContent { get; set; }
|
public string ScriptContent { get; set; }
|
||||||
}
|
}
|
||||||
@ -24,6 +24,6 @@ public class PluginEntity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginFeatureEntity
|
public class PluginFeatureEntity
|
||||||
{
|
{
|
||||||
public string Type { get; set; } = string.Empty;
|
public string Type { get; set; }
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
}
|
}
|
||||||
@ -10,6 +10,6 @@ public class PluginSettingEntity
|
|||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid PluginGuid { get; set; }
|
public Guid PluginGuid { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; }
|
||||||
public string Value { get; set; } = string.Empty;
|
public string Value { get; set; }
|
||||||
}
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Entities.Profile.Abstract;
|
||||||
|
|
||||||
|
public abstract class DataModelConditionPartEntity
|
||||||
|
{
|
||||||
|
public List<DataModelConditionPartEntity> Children { get; set; }
|
||||||
|
}
|
||||||
@ -8,8 +8,8 @@ public abstract class RenderElementEntity
|
|||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid ParentId { get; set; }
|
public Guid ParentId { get; set; }
|
||||||
|
|
||||||
public List<LayerEffectEntity> LayerEffects { get; set; } = new();
|
public List<LayerEffectEntity> LayerEffects { get; set; }
|
||||||
|
|
||||||
public IConditionEntity? DisplayCondition { get; set; }
|
public IConditionEntity DisplayCondition { get; set; }
|
||||||
public TimelineEntity? Timeline { get; set; }
|
public TimelineEntity Timeline { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
namespace Artemis.Storage.Entities.Profile.AdaptionHints;
|
namespace Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||||
|
|
||||||
public interface IAdaptionHintEntity;
|
public interface IAdaptionHintEntity
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -2,4 +2,6 @@
|
|||||||
|
|
||||||
namespace Artemis.Storage.Entities.Profile.Conditions;
|
namespace Artemis.Storage.Entities.Profile.Conditions;
|
||||||
|
|
||||||
public class AlwaysOnConditionEntity : IConditionEntity;
|
public class AlwaysOnConditionEntity : IConditionEntity
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -8,6 +8,6 @@ public class EventConditionEntity : IConditionEntity
|
|||||||
public int TriggerMode { get; set; }
|
public int TriggerMode { get; set; }
|
||||||
public int OverlapMode { get; set; }
|
public int OverlapMode { get; set; }
|
||||||
public int ToggleOffMode { get; set; }
|
public int ToggleOffMode { get; set; }
|
||||||
public DataModelPathEntity? EventPath { get; set; }
|
public DataModelPathEntity EventPath { get; set; }
|
||||||
public NodeScriptEntity? Script { get; set; }
|
public NodeScriptEntity Script { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
namespace Artemis.Storage.Entities.Profile.Abstract;
|
namespace Artemis.Storage.Entities.Profile.Abstract;
|
||||||
|
|
||||||
public interface IConditionEntity;
|
public interface IConditionEntity
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -2,4 +2,6 @@
|
|||||||
|
|
||||||
namespace Artemis.Storage.Entities.Profile.Conditions;
|
namespace Artemis.Storage.Entities.Profile.Conditions;
|
||||||
|
|
||||||
public class PlayOnceConditionEntity : IConditionEntity;
|
public class PlayOnceConditionEntity : IConditionEntity
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -7,5 +7,5 @@ public class StaticConditionEntity : IConditionEntity
|
|||||||
{
|
{
|
||||||
public int PlayMode { get; set; }
|
public int PlayMode { get; set; }
|
||||||
public int StopMode { get; set; }
|
public int StopMode { get; set; }
|
||||||
public NodeScriptEntity? Script { get; set; }
|
public NodeScriptEntity Script { get; set; }
|
||||||
}
|
}
|
||||||
@ -4,6 +4,7 @@ namespace Artemis.Storage.Entities.Profile.DataBindings;
|
|||||||
|
|
||||||
public class DataBindingEntity
|
public class DataBindingEntity
|
||||||
{
|
{
|
||||||
|
public string Identifier { get; set; }
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
public NodeScriptEntity? NodeScript { get; set; }
|
public NodeScriptEntity NodeScript { get; set; }
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
public class DataModelPathEntity
|
public class DataModelPathEntity
|
||||||
{
|
{
|
||||||
public string Path { get; set; } = string.Empty;
|
public string Path { get; set; }
|
||||||
public string? DataModelId { get; set; }
|
public string DataModelId { get; set; }
|
||||||
public string? Type { get; set; }
|
public string Type { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Artemis.Storage.Entities.Profile.Abstract;
|
using Artemis.Storage.Entities.Profile.Abstract;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
@ -6,13 +7,18 @@ namespace Artemis.Storage.Entities.Profile;
|
|||||||
|
|
||||||
public class FolderEntity : RenderElementEntity
|
public class FolderEntity : RenderElementEntity
|
||||||
{
|
{
|
||||||
|
public FolderEntity()
|
||||||
|
{
|
||||||
|
LayerEffects = new List<LayerEffectEntity>();
|
||||||
|
}
|
||||||
|
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
public string? Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool IsExpanded { get; set; }
|
public bool IsExpanded { get; set; }
|
||||||
public bool Suspended { get; set; }
|
public bool Suspended { get; set; }
|
||||||
|
|
||||||
[BsonRef("ProfileEntity")]
|
[BsonRef("ProfileEntity")]
|
||||||
public ProfileEntity Profile { get; set; } = null!;
|
public ProfileEntity Profile { get; set; }
|
||||||
|
|
||||||
public Guid ProfileId { get; set; }
|
public Guid ProfileId { get; set; }
|
||||||
}
|
}
|
||||||
@ -6,6 +6,6 @@ public class KeyframeEntity
|
|||||||
{
|
{
|
||||||
public TimeSpan Position { get; set; }
|
public TimeSpan Position { get; set; }
|
||||||
public int Timeline { get; set; }
|
public int Timeline { get; set; }
|
||||||
public string Value { get; set; } = string.Empty;
|
public string Value { get; set; }
|
||||||
public int EasingFunction { get; set; }
|
public int EasingFunction { get; set; }
|
||||||
}
|
}
|
||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
public class LayerBrushEntity
|
public class LayerBrushEntity
|
||||||
{
|
{
|
||||||
public string ProviderId { get; set; } = string.Empty;
|
public string ProviderId { get; set; }
|
||||||
public string BrushType { get; set; } = string.Empty;
|
public string BrushType { get; set; }
|
||||||
|
|
||||||
public PropertyGroupEntity? PropertyGroup { get; set; }
|
public PropertyGroupEntity PropertyGroup { get; set; }
|
||||||
}
|
}
|
||||||
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
public class LayerEffectEntity
|
public class LayerEffectEntity
|
||||||
{
|
{
|
||||||
public string ProviderId { get; set; } = string.Empty;
|
public string ProviderId { get; set; }
|
||||||
public string EffectType { get; set; } = string.Empty;
|
public string EffectType { get; set; }
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; }
|
||||||
public bool HasBeenRenamed { get; set; }
|
public bool HasBeenRenamed { get; set; }
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
||||||
public PropertyGroupEntity? PropertyGroup { get; set; }
|
public PropertyGroupEntity PropertyGroup { get; set; }
|
||||||
}
|
}
|
||||||
@ -12,21 +12,22 @@ public class LayerEntity : RenderElementEntity
|
|||||||
{
|
{
|
||||||
Leds = new List<LedEntity>();
|
Leds = new List<LedEntity>();
|
||||||
AdaptionHints = new List<IAdaptionHintEntity>();
|
AdaptionHints = new List<IAdaptionHintEntity>();
|
||||||
|
LayerEffects = new List<LayerEffectEntity>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
public string? Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool Suspended { get; set; }
|
public bool Suspended { get; set; }
|
||||||
|
|
||||||
public List<LedEntity> Leds { get; set; }
|
public List<LedEntity> Leds { get; set; }
|
||||||
public List<IAdaptionHintEntity> AdaptionHints { get; set; }
|
public List<IAdaptionHintEntity> AdaptionHints { get; set; }
|
||||||
|
|
||||||
public PropertyGroupEntity? GeneralPropertyGroup { get; set; }
|
public PropertyGroupEntity GeneralPropertyGroup { get; set; }
|
||||||
public PropertyGroupEntity? TransformPropertyGroup { get; set; }
|
public PropertyGroupEntity TransformPropertyGroup { get; set; }
|
||||||
public LayerBrushEntity? LayerBrush { get; set; }
|
public LayerBrushEntity LayerBrush { get; set; }
|
||||||
|
|
||||||
[BsonRef("ProfileEntity")]
|
[BsonRef("ProfileEntity")]
|
||||||
public ProfileEntity Profile { get; set; } = null!;
|
public ProfileEntity Profile { get; set; }
|
||||||
|
|
||||||
public Guid ProfileId { get; set; }
|
public Guid ProfileId { get; set; }
|
||||||
}
|
}
|
||||||
@ -5,8 +5,8 @@ namespace Artemis.Storage.Entities.Profile;
|
|||||||
|
|
||||||
public class LedEntity
|
public class LedEntity
|
||||||
{
|
{
|
||||||
public string LedName { get; set; } = string.Empty;
|
public string LedName { get; set; }
|
||||||
public string DeviceIdentifier { get; set; } = string.Empty;
|
public string DeviceIdentifier { get; set; }
|
||||||
|
|
||||||
public int? PhysicalLayout { get; set; }
|
public int? PhysicalLayout { get; set; }
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ public class LedEntity
|
|||||||
|
|
||||||
private sealed class LedEntityEqualityComparer : IEqualityComparer<LedEntity>
|
private sealed class LedEntityEqualityComparer : IEqualityComparer<LedEntity>
|
||||||
{
|
{
|
||||||
public bool Equals(LedEntity? x, LedEntity? y)
|
public bool Equals(LedEntity x, LedEntity y)
|
||||||
{
|
{
|
||||||
if (ReferenceEquals(x, y))
|
if (ReferenceEquals(x, y))
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -20,12 +20,12 @@ public class NodeConnectionEntity
|
|||||||
TargetPinId = nodeConnectionEntity.TargetPinId;
|
TargetPinId = nodeConnectionEntity.TargetPinId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string SourceType { get; set; } = string.Empty;
|
public string SourceType { get; set; }
|
||||||
public Guid SourceNode { get; set; }
|
public Guid SourceNode { get; set; }
|
||||||
public Guid TargetNode { get; set; }
|
public Guid TargetNode { get; set; }
|
||||||
public int SourcePinCollectionId { get; set; }
|
public int SourcePinCollectionId { get; set; }
|
||||||
public int SourcePinId { get; set; }
|
public int SourcePinId { get; set; }
|
||||||
public string TargetType { get; set; } = string.Empty;
|
public string TargetType { get; set; }
|
||||||
public int TargetPinCollectionId { get; set; }
|
public int TargetPinCollectionId { get; set; }
|
||||||
public int TargetPinId { get; set; }
|
public int TargetPinId { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ public class NodeEntity
|
|||||||
{
|
{
|
||||||
Id = nodeEntity.Id;
|
Id = nodeEntity.Id;
|
||||||
Type = nodeEntity.Type;
|
Type = nodeEntity.Type;
|
||||||
ProviderId = nodeEntity.ProviderId;
|
PluginId = nodeEntity.PluginId;
|
||||||
|
|
||||||
Name = nodeEntity.Name;
|
Name = nodeEntity.Name;
|
||||||
Description = nodeEntity.Description;
|
Description = nodeEntity.Description;
|
||||||
@ -28,15 +28,15 @@ public class NodeEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public string Type { get; set; } = string.Empty;
|
public string Type { get; set; }
|
||||||
public string ProviderId { get; set; } = string.Empty;
|
public Guid PluginId { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; }
|
||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; }
|
||||||
public bool IsExitNode { get; set; }
|
public bool IsExitNode { get; set; }
|
||||||
public double X { get; set; }
|
public double X { get; set; }
|
||||||
public double Y { get; set; }
|
public double Y { get; set; }
|
||||||
public string Storage { get; set; } = string.Empty;
|
public string Storage { get; set; }
|
||||||
|
|
||||||
public List<NodePinCollectionEntity> PinCollections { get; set; }
|
public List<NodePinCollectionEntity> PinCollections { get; set; }
|
||||||
}
|
}
|
||||||
@ -10,8 +10,8 @@ public class NodeScriptEntity
|
|||||||
Connections = new List<NodeConnectionEntity>();
|
Connections = new List<NodeConnectionEntity>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; }
|
||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; }
|
||||||
|
|
||||||
public List<NodeEntity> Nodes { get; set; }
|
public List<NodeEntity> Nodes { get; set; }
|
||||||
public List<NodeConnectionEntity> Connections { get; set; }
|
public List<NodeConnectionEntity> Connections { get; set; }
|
||||||
|
|||||||
@ -7,7 +7,7 @@ public class ProfileCategoryEntity
|
|||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; }
|
||||||
public bool IsCollapsed { get; set; }
|
public bool IsCollapsed { get; set; }
|
||||||
public bool IsSuspended { get; set; }
|
public bool IsSuspended { get; set; }
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|||||||
@ -5,8 +5,8 @@ namespace Artemis.Storage.Entities.Profile;
|
|||||||
|
|
||||||
public class ProfileConfigurationEntity
|
public class ProfileConfigurationEntity
|
||||||
{
|
{
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; }
|
||||||
public string? MaterialIcon { get; set; }
|
public string MaterialIcon { get; set; }
|
||||||
public Guid FileIconId { get; set; }
|
public Guid FileIconId { get; set; }
|
||||||
public int IconType { get; set; }
|
public int IconType { get; set; }
|
||||||
public bool IconFill { get; set; }
|
public bool IconFill { get; set; }
|
||||||
@ -14,17 +14,16 @@ public class ProfileConfigurationEntity
|
|||||||
|
|
||||||
public bool IsSuspended { get; set; }
|
public bool IsSuspended { get; set; }
|
||||||
public int ActivationBehaviour { get; set; }
|
public int ActivationBehaviour { get; set; }
|
||||||
public NodeScriptEntity? ActivationCondition { get; set; }
|
public NodeScriptEntity ActivationCondition { get; set; }
|
||||||
|
|
||||||
public int HotkeyMode { get; set; }
|
public int HotkeyMode { get; set; }
|
||||||
public ProfileConfigurationHotkeyEntity? EnableHotkey { get; set; }
|
public ProfileConfigurationHotkeyEntity EnableHotkey { get; set; }
|
||||||
public ProfileConfigurationHotkeyEntity? DisableHotkey { get; set; }
|
public ProfileConfigurationHotkeyEntity DisableHotkey { get; set; }
|
||||||
|
|
||||||
public string? ModuleId { get; set; }
|
public string ModuleId { get; set; }
|
||||||
|
|
||||||
public Guid ProfileCategoryId { get; set; }
|
public Guid ProfileCategoryId { get; set; }
|
||||||
public Guid ProfileId { get; set; }
|
public Guid ProfileId { get; set; }
|
||||||
|
|
||||||
public bool FadeInAndOut { get; set; }
|
public bool FadeInAndOut { get; set; }
|
||||||
public int Version { get; set; }
|
|
||||||
}
|
}
|
||||||
@ -16,7 +16,7 @@ public class ProfileEntity
|
|||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; }
|
||||||
public bool IsFreshImport { get; set; }
|
public bool IsFreshImport { get; set; }
|
||||||
|
|
||||||
public List<FolderEntity> Folders { get; set; }
|
public List<FolderEntity> Folders { get; set; }
|
||||||
@ -28,7 +28,7 @@ public class ProfileEntity
|
|||||||
Guid oldGuid = Id;
|
Guid oldGuid = Id;
|
||||||
Id = guid;
|
Id = guid;
|
||||||
|
|
||||||
FolderEntity? rootFolder = Folders.FirstOrDefault(f => f.ParentId == oldGuid);
|
FolderEntity rootFolder = Folders.FirstOrDefault(f => f.ParentId == oldGuid);
|
||||||
if (rootFolder != null)
|
if (rootFolder != null)
|
||||||
rootFolder.ParentId = Id;
|
rootFolder.ParentId = Id;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,10 @@ namespace Artemis.Storage.Entities.Profile;
|
|||||||
|
|
||||||
public class PropertyEntity
|
public class PropertyEntity
|
||||||
{
|
{
|
||||||
public string Identifier { get; set; } = string.Empty;
|
public string Identifier { get; set; }
|
||||||
public string Value { get; set; } = string.Empty;
|
public string Value { get; set; }
|
||||||
public bool KeyframesEnabled { get; set; }
|
public bool KeyframesEnabled { get; set; }
|
||||||
|
|
||||||
public DataBindingEntity? DataBinding { get; set; }
|
public DataBindingEntity DataBinding { get; set; }
|
||||||
public List<KeyframeEntity> KeyframeEntities { get; set; } = new();
|
public List<KeyframeEntity> KeyframeEntities { get; set; } = new();
|
||||||
}
|
}
|
||||||
@ -4,7 +4,7 @@ namespace Artemis.Storage.Entities.Profile;
|
|||||||
|
|
||||||
public class PropertyGroupEntity
|
public class PropertyGroupEntity
|
||||||
{
|
{
|
||||||
public string Identifier { get; set; } = string.Empty;
|
public string Identifier { get; set; }
|
||||||
public List<PropertyEntity> Properties { get; set; } = new();
|
public List<PropertyEntity> Properties { get; set; } = new();
|
||||||
public List<PropertyGroupEntity> PropertyGroups { get; set; } = new();
|
public List<PropertyGroupEntity> PropertyGroups { get; set; } = new();
|
||||||
}
|
}
|
||||||
@ -11,8 +11,8 @@ public class DeviceEntity
|
|||||||
Categories = new List<int>();
|
Categories = new List<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Id { get; set; } = string.Empty;
|
public string Id { get; set; }
|
||||||
public string DeviceProvider { get; set; } = string.Empty;
|
public string DeviceProvider { get; set; }
|
||||||
public float X { get; set; }
|
public float X { get; set; }
|
||||||
public float Y { get; set; }
|
public float Y { get; set; }
|
||||||
public float Rotation { get; set; }
|
public float Rotation { get; set; }
|
||||||
@ -24,9 +24,9 @@ public class DeviceEntity
|
|||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
public int PhysicalLayout { get; set; }
|
public int PhysicalLayout { get; set; }
|
||||||
public string? LogicalLayout { get; set; }
|
public string LogicalLayout { get; set; }
|
||||||
public string? LayoutType { get; set; }
|
public string LayoutType { get; set; }
|
||||||
public string? LayoutParameter { get; set; }
|
public string LayoutParameter { get; set; }
|
||||||
|
|
||||||
public List<DeviceInputIdentifierEntity> InputIdentifiers { get; set; }
|
public List<DeviceInputIdentifierEntity> InputIdentifiers { get; set; }
|
||||||
public List<InputMappingEntity> InputMappings { get; set; }
|
public List<InputMappingEntity> InputMappings { get; set; }
|
||||||
@ -41,6 +41,6 @@ public class InputMappingEntity
|
|||||||
|
|
||||||
public class DeviceInputIdentifierEntity
|
public class DeviceInputIdentifierEntity
|
||||||
{
|
{
|
||||||
public string InputProvider { get; set; } = string.Empty;
|
public string InputProvider { get; set; }
|
||||||
public object Identifier { get; set; } = string.Empty;
|
public object Identifier { get; set; }
|
||||||
}
|
}
|
||||||
@ -10,12 +10,13 @@ public class EntryEntity
|
|||||||
public long EntryId { get; set; }
|
public long EntryId { get; set; }
|
||||||
public int EntryType { get; set; }
|
public int EntryType { get; set; }
|
||||||
|
|
||||||
public string Author { get; set; } = string.Empty;
|
public string Author { get; set; }
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
|
public string Summary { get; set; } = string.Empty;
|
||||||
|
|
||||||
public long ReleaseId { get; set; }
|
public long ReleaseId { get; set; }
|
||||||
public string ReleaseVersion { get; set; } = string.Empty;
|
public string ReleaseVersion { get; set; }
|
||||||
public DateTimeOffset InstalledAt { get; set; }
|
public DateTimeOffset InstalledAt { get; set; }
|
||||||
|
|
||||||
public Dictionary<string,object>? Metadata { get; set; }
|
public Dictionary<string,object> Metadata { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,9 +0,0 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations;
|
|
||||||
|
|
||||||
public interface IProfileMigration
|
|
||||||
{
|
|
||||||
int Version { get; }
|
|
||||||
void Migrate(JObject profileJson);
|
|
||||||
}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations;
|
namespace Artemis.Storage.Migrations.Interfaces;
|
||||||
|
|
||||||
public interface IStorageMigration
|
public interface IStorageMigration
|
||||||
{
|
{
|
||||||
@ -1,8 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Artemis.Storage.Migrations.Interfaces;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
namespace Artemis.Storage.Migrations;
|
||||||
|
|
||||||
public class M0020AvaloniaReset : IStorageMigration
|
public class M0020AvaloniaReset : IStorageMigration
|
||||||
{
|
{
|
||||||
@ -3,17 +3,18 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.Storage.Entities.Profile.Nodes;
|
using Artemis.Storage.Entities.Profile.Nodes;
|
||||||
|
using Artemis.Storage.Migrations.Interfaces;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
namespace Artemis.Storage.Migrations;
|
||||||
|
|
||||||
public class M0021GradientNodes : IStorageMigration
|
public class M0021GradientNodes : IStorageMigration
|
||||||
{
|
{
|
||||||
private void MigrateDataBinding(PropertyEntity property)
|
private void MigrateDataBinding(PropertyEntity property)
|
||||||
{
|
{
|
||||||
NodeScriptEntity? script = property.DataBinding?.NodeScript;
|
NodeScriptEntity script = property.DataBinding.NodeScript;
|
||||||
NodeEntity? exitNode = script?.Nodes.FirstOrDefault(s => s.IsExitNode);
|
NodeEntity exitNode = script.Nodes.FirstOrDefault(s => s.IsExitNode);
|
||||||
if (script == null || exitNode == null)
|
if (exitNode == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create a new node at the same position of the exit node
|
// Create a new node at the same position of the exit node
|
||||||
@ -21,7 +22,7 @@ public class M0021GradientNodes : IStorageMigration
|
|||||||
{
|
{
|
||||||
Id = Guid.NewGuid(),
|
Id = Guid.NewGuid(),
|
||||||
Type = "ColorGradientNode",
|
Type = "ColorGradientNode",
|
||||||
ProviderId = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78",
|
PluginId = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"),
|
||||||
Name = "Color Gradient",
|
Name = "Color Gradient",
|
||||||
Description = "Outputs a color gradient with the given colors",
|
Description = "Outputs a color gradient with the given colors",
|
||||||
X = exitNode.X,
|
X = exitNode.X,
|
||||||
@ -58,11 +59,8 @@ public class M0021GradientNodes : IStorageMigration
|
|||||||
exitNode.Y += 30;
|
exitNode.Y += 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MigrateDataBinding(PropertyGroupEntity? propertyGroup)
|
private void MigrateDataBinding(PropertyGroupEntity propertyGroup)
|
||||||
{
|
{
|
||||||
if (propertyGroup == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (PropertyGroupEntity propertyGroupPropertyGroup in propertyGroup.PropertyGroups)
|
foreach (PropertyGroupEntity propertyGroupPropertyGroup in propertyGroup.PropertyGroups)
|
||||||
MigrateDataBinding(propertyGroupPropertyGroup);
|
MigrateDataBinding(propertyGroupPropertyGroup);
|
||||||
|
|
||||||
@ -82,7 +80,7 @@ public class M0021GradientNodes : IStorageMigration
|
|||||||
foreach (ProfileEntity profileEntity in profiles)
|
foreach (ProfileEntity profileEntity in profiles)
|
||||||
{
|
{
|
||||||
foreach (LayerEntity layer in profileEntity.Layers.Where(le => le.LayerBrush != null))
|
foreach (LayerEntity layer in profileEntity.Layers.Where(le => le.LayerBrush != null))
|
||||||
MigrateDataBinding(layer.LayerBrush?.PropertyGroup);
|
MigrateDataBinding(layer.LayerBrush.PropertyGroup);
|
||||||
|
|
||||||
repository.Update(profileEntity);
|
repository.Update(profileEntity);
|
||||||
}
|
}
|
||||||
@ -3,13 +3,14 @@ using Artemis.Storage.Entities.Profile;
|
|||||||
using Artemis.Storage.Entities.Profile.Abstract;
|
using Artemis.Storage.Entities.Profile.Abstract;
|
||||||
using Artemis.Storage.Entities.Profile.Conditions;
|
using Artemis.Storage.Entities.Profile.Conditions;
|
||||||
using Artemis.Storage.Entities.Profile.Nodes;
|
using Artemis.Storage.Entities.Profile.Nodes;
|
||||||
|
using Artemis.Storage.Migrations.Interfaces;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
namespace Artemis.Storage.Migrations;
|
||||||
|
|
||||||
public class M0022TransitionNodes : IStorageMigration
|
public class M0022TransitionNodes : IStorageMigration
|
||||||
{
|
{
|
||||||
private void MigrateNodeScript(NodeScriptEntity? nodeScript)
|
private void MigrateNodeScript(NodeScriptEntity nodeScript)
|
||||||
{
|
{
|
||||||
if (nodeScript == null)
|
if (nodeScript == null)
|
||||||
return;
|
return;
|
||||||
@ -27,7 +28,7 @@ public class M0022TransitionNodes : IStorageMigration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MigratePropertyGroup(PropertyGroupEntity? propertyGroup)
|
private void MigratePropertyGroup(PropertyGroupEntity propertyGroup)
|
||||||
{
|
{
|
||||||
if (propertyGroup == null)
|
if (propertyGroup == null)
|
||||||
return;
|
return;
|
||||||
@ -38,7 +39,7 @@ public class M0022TransitionNodes : IStorageMigration
|
|||||||
MigrateNodeScript(property.DataBinding?.NodeScript);
|
MigrateNodeScript(property.DataBinding?.NodeScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MigrateDisplayCondition(IConditionEntity? conditionEntity)
|
private void MigrateDisplayCondition(IConditionEntity conditionEntity)
|
||||||
{
|
{
|
||||||
if (conditionEntity is EventConditionEntity eventConditionEntity)
|
if (conditionEntity is EventConditionEntity eventConditionEntity)
|
||||||
MigrateNodeScript(eventConditionEntity.Script);
|
MigrateNodeScript(eventConditionEntity.Script);
|
||||||
@ -69,14 +70,14 @@ public class M0022TransitionNodes : IStorageMigration
|
|||||||
MigratePropertyGroup(layer.GeneralPropertyGroup);
|
MigratePropertyGroup(layer.GeneralPropertyGroup);
|
||||||
MigratePropertyGroup(layer.TransformPropertyGroup);
|
MigratePropertyGroup(layer.TransformPropertyGroup);
|
||||||
foreach (LayerEffectEntity layerEffectEntity in layer.LayerEffects)
|
foreach (LayerEffectEntity layerEffectEntity in layer.LayerEffects)
|
||||||
MigratePropertyGroup(layerEffectEntity.PropertyGroup);
|
MigratePropertyGroup(layerEffectEntity?.PropertyGroup);
|
||||||
MigrateDisplayCondition(layer.DisplayCondition);
|
MigrateDisplayCondition(layer.DisplayCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (FolderEntity folder in profileEntity.Folders)
|
foreach (FolderEntity folder in profileEntity.Folders)
|
||||||
{
|
{
|
||||||
foreach (LayerEffectEntity folderLayerEffect in folder.LayerEffects)
|
foreach (LayerEffectEntity folderLayerEffect in folder.LayerEffects)
|
||||||
MigratePropertyGroup(folderLayerEffect.PropertyGroup);
|
MigratePropertyGroup(folderLayerEffect?.PropertyGroup);
|
||||||
MigrateDisplayCondition(folder.DisplayCondition);
|
MigrateDisplayCondition(folder.DisplayCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,7 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Artemis.Storage.Migrations.Interfaces;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
namespace Artemis.Storage.Migrations;
|
||||||
|
|
||||||
public class M0023LayoutProviders : IStorageMigration
|
public class M0023LayoutProviders : IStorageMigration
|
||||||
{
|
{
|
||||||
@ -1,88 +0,0 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Profile;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Migrates nodes to be provider-based.
|
|
||||||
/// This requires giving them a ProviderId and updating the their namespaces to match the namespace of the new plugin.
|
|
||||||
/// </summary>
|
|
||||||
internal class M0001NodeProviders : IProfileMigration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public int Version => 1;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Migrate(JObject profileJson)
|
|
||||||
{
|
|
||||||
JArray? folders = (JArray?) profileJson["Folders"]?["$values"];
|
|
||||||
JArray? layers = (JArray?) profileJson["Layers"]?["$values"];
|
|
||||||
|
|
||||||
if (folders != null)
|
|
||||||
{
|
|
||||||
foreach (JToken folder in folders)
|
|
||||||
MigrateProfileElement(folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layers != null)
|
|
||||||
{
|
|
||||||
foreach (JToken layer in layers)
|
|
||||||
{
|
|
||||||
MigrateProfileElement(layer);
|
|
||||||
MigratePropertyGroup(layer["GeneralPropertyGroup"]);
|
|
||||||
MigratePropertyGroup(layer["TransformPropertyGroup"]);
|
|
||||||
MigratePropertyGroup(layer["LayerBrush"]?["PropertyGroup"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateProfileElement(JToken profileElement)
|
|
||||||
{
|
|
||||||
JArray? layerEffects = (JArray?) profileElement["LayerEffects"]?["$values"];
|
|
||||||
if (layerEffects != null)
|
|
||||||
{
|
|
||||||
foreach (JToken layerEffect in layerEffects)
|
|
||||||
MigratePropertyGroup(layerEffect["PropertyGroup"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
JToken? displayCondition = profileElement["DisplayCondition"];
|
|
||||||
if (displayCondition != null)
|
|
||||||
MigrateNodeScript(displayCondition["Script"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigratePropertyGroup(JToken? propertyGroup)
|
|
||||||
{
|
|
||||||
if (propertyGroup == null || !propertyGroup.HasValues)
|
|
||||||
return;
|
|
||||||
|
|
||||||
JArray? properties = (JArray?) propertyGroup["Properties"]?["$values"];
|
|
||||||
JArray? propertyGroups = (JArray?) propertyGroup["PropertyGroups"]?["$values"];
|
|
||||||
|
|
||||||
if (properties != null)
|
|
||||||
{
|
|
||||||
foreach (JToken property in properties)
|
|
||||||
MigrateNodeScript(property["DataBinding"]?["NodeScript"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propertyGroups != null)
|
|
||||||
{
|
|
||||||
foreach (JToken childPropertyGroup in propertyGroups)
|
|
||||||
MigratePropertyGroup(childPropertyGroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateNodeScript(JToken? nodeScript)
|
|
||||||
{
|
|
||||||
if (nodeScript == null || !nodeScript.HasValues)
|
|
||||||
return;
|
|
||||||
|
|
||||||
JArray? nodes = (JArray?) nodeScript["Nodes"]?["$values"];
|
|
||||||
if (nodes == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (JToken node in nodes)
|
|
||||||
{
|
|
||||||
node["Type"] = node["Type"]?.Value<string>()?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes");
|
|
||||||
node["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,100 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
|
||||||
|
|
||||||
public class M0024NodeProviders : IStorageMigration
|
|
||||||
{
|
|
||||||
public int UserVersion => 24;
|
|
||||||
|
|
||||||
public void Apply(LiteRepository repository)
|
|
||||||
{
|
|
||||||
List<ProfileCategoryEntity> profileCategories = repository.Query<ProfileCategoryEntity>().ToList();
|
|
||||||
foreach (ProfileCategoryEntity profileCategory in profileCategories)
|
|
||||||
{
|
|
||||||
foreach (ProfileConfigurationEntity profileConfigurationEntity in profileCategory.ProfileConfigurations)
|
|
||||||
{
|
|
||||||
profileConfigurationEntity.Version = 1;
|
|
||||||
}
|
|
||||||
repository.Update(profileCategory);
|
|
||||||
}
|
|
||||||
|
|
||||||
ILiteCollection<BsonDocument> collection = repository.Database.GetCollection("ProfileEntity");
|
|
||||||
foreach (BsonDocument profileBson in collection.FindAll())
|
|
||||||
{
|
|
||||||
BsonArray? folders = profileBson["Folders"]?.AsArray;
|
|
||||||
BsonArray? layers = profileBson["Layers"]?.AsArray;
|
|
||||||
|
|
||||||
if (folders != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue folder in folders)
|
|
||||||
MigrateProfileElement(folder.AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layers != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue layer in layers)
|
|
||||||
{
|
|
||||||
MigrateProfileElement(layer.AsDocument);
|
|
||||||
MigratePropertyGroup(layer.AsDocument["GeneralPropertyGroup"].AsDocument);
|
|
||||||
MigratePropertyGroup(layer.AsDocument["TransformPropertyGroup"].AsDocument);
|
|
||||||
MigratePropertyGroup(layer.AsDocument["LayerBrush"]?["PropertyGroup"].AsDocument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
collection.Update(profileBson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateProfileElement(BsonDocument profileElement)
|
|
||||||
{
|
|
||||||
BsonArray? layerEffects = profileElement["LayerEffects"]?.AsArray;
|
|
||||||
if (layerEffects != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue layerEffect in layerEffects)
|
|
||||||
MigratePropertyGroup(layerEffect.AsDocument["PropertyGroup"].AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
BsonValue? displayCondition = profileElement["DisplayCondition"];
|
|
||||||
if (displayCondition != null)
|
|
||||||
MigrateNodeScript(displayCondition.AsDocument["Script"].AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigratePropertyGroup(BsonDocument? propertyGroup)
|
|
||||||
{
|
|
||||||
if (propertyGroup == null || propertyGroup.Keys.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BsonArray? properties = propertyGroup["Properties"]?.AsArray;
|
|
||||||
BsonArray? propertyGroups = propertyGroup["PropertyGroups"]?.AsArray;
|
|
||||||
|
|
||||||
if (properties != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue property in properties)
|
|
||||||
MigrateNodeScript(property.AsDocument["DataBinding"]?["NodeScript"]?.AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propertyGroups != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue childPropertyGroup in propertyGroups)
|
|
||||||
MigratePropertyGroup(childPropertyGroup.AsDocument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateNodeScript(BsonDocument? nodeScript)
|
|
||||||
{
|
|
||||||
if (nodeScript == null || nodeScript.Keys.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BsonArray? nodes = nodeScript["Nodes"]?.AsArray;
|
|
||||||
if (nodes == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (BsonValue node in nodes)
|
|
||||||
{
|
|
||||||
node.AsDocument["Type"] = node.AsDocument["Type"]?.AsString?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes");
|
|
||||||
node.AsDocument["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -25,7 +25,7 @@ internal class DeviceRepository : IDeviceRepository
|
|||||||
_repository.Delete<DeviceEntity>(deviceEntity.Id);
|
_repository.Delete<DeviceEntity>(deviceEntity.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceEntity? Get(string id)
|
public DeviceEntity Get(string id)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<DeviceEntity>(s => s.Id == id);
|
return _repository.FirstOrDefault<DeviceEntity>(s => s.Id == id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,12 +27,12 @@ internal class EntryRepository : IEntryRepository
|
|||||||
_repository.Delete<EntryEntity>(entryEntity.Id);
|
_repository.Delete<EntryEntity>(entryEntity.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntryEntity? Get(Guid id)
|
public EntryEntity Get(Guid id)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<EntryEntity>(s => s.Id == id);
|
return _repository.FirstOrDefault<EntryEntity>(s => s.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntryEntity? GetByEntryId(long entryId)
|
public EntryEntity GetByEntryId(long entryId)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<EntryEntity>(s => s.EntryId == entryId);
|
return _repository.FirstOrDefault<EntryEntity>(s => s.EntryId == entryId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ public interface IDeviceRepository : IRepository
|
|||||||
{
|
{
|
||||||
void Add(DeviceEntity deviceEntity);
|
void Add(DeviceEntity deviceEntity);
|
||||||
void Remove(DeviceEntity deviceEntity);
|
void Remove(DeviceEntity deviceEntity);
|
||||||
DeviceEntity? Get(string id);
|
DeviceEntity Get(string id);
|
||||||
List<DeviceEntity> GetAll();
|
List<DeviceEntity> GetAll();
|
||||||
void Save(DeviceEntity deviceEntity);
|
void Save(DeviceEntity deviceEntity);
|
||||||
void Save(IEnumerable<DeviceEntity> deviceEntities);
|
void Save(IEnumerable<DeviceEntity> deviceEntities);
|
||||||
|
|||||||
@ -8,8 +8,8 @@ public interface IEntryRepository : IRepository
|
|||||||
{
|
{
|
||||||
void Add(EntryEntity entryEntity);
|
void Add(EntryEntity entryEntity);
|
||||||
void Remove(EntryEntity entryEntity);
|
void Remove(EntryEntity entryEntity);
|
||||||
EntryEntity? Get(Guid id);
|
EntryEntity Get(Guid id);
|
||||||
EntryEntity? GetByEntryId(long entryId);
|
EntryEntity GetByEntryId(long entryId);
|
||||||
List<EntryEntity> GetAll();
|
List<EntryEntity> GetAll();
|
||||||
void Save(EntryEntity entryEntity);
|
void Save(EntryEntity entryEntity);
|
||||||
void Save(IEnumerable<EntryEntity> entryEntities);
|
void Save(IEnumerable<EntryEntity> entryEntities);
|
||||||
|
|||||||
@ -6,12 +6,12 @@ namespace Artemis.Storage.Repositories.Interfaces;
|
|||||||
public interface IPluginRepository : IRepository
|
public interface IPluginRepository : IRepository
|
||||||
{
|
{
|
||||||
void AddPlugin(PluginEntity pluginEntity);
|
void AddPlugin(PluginEntity pluginEntity);
|
||||||
PluginEntity? GetPluginByGuid(Guid pluginGuid);
|
PluginEntity GetPluginByGuid(Guid pluginGuid);
|
||||||
void SavePlugin(PluginEntity pluginEntity);
|
void SavePlugin(PluginEntity pluginEntity);
|
||||||
|
|
||||||
void AddSetting(PluginSettingEntity pluginSettingEntity);
|
void AddSetting(PluginSettingEntity pluginSettingEntity);
|
||||||
PluginSettingEntity? GetSettingByGuid(Guid pluginGuid);
|
PluginSettingEntity GetSettingByGuid(Guid pluginGuid);
|
||||||
PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
||||||
void SaveSetting(PluginSettingEntity pluginSettingEntity);
|
void SaveSetting(PluginSettingEntity pluginSettingEntity);
|
||||||
void RemoveSettings(Guid pluginGuid);
|
void RemoveSettings(Guid pluginGuid);
|
||||||
}
|
}
|
||||||
@ -10,8 +10,8 @@ public interface IProfileCategoryRepository : IRepository
|
|||||||
void Add(ProfileCategoryEntity profileCategoryEntity);
|
void Add(ProfileCategoryEntity profileCategoryEntity);
|
||||||
void Remove(ProfileCategoryEntity profileCategoryEntity);
|
void Remove(ProfileCategoryEntity profileCategoryEntity);
|
||||||
List<ProfileCategoryEntity> GetAll();
|
List<ProfileCategoryEntity> GetAll();
|
||||||
ProfileCategoryEntity? Get(Guid id);
|
ProfileCategoryEntity Get(Guid id);
|
||||||
Stream? GetProfileIconStream(Guid id);
|
Stream GetProfileIconStream(Guid id);
|
||||||
void SaveProfileIconStream(ProfileConfigurationEntity profileConfigurationEntity, Stream stream);
|
void SaveProfileIconStream(ProfileConfigurationEntity profileConfigurationEntity, Stream stream);
|
||||||
ProfileCategoryEntity IsUnique(string name, Guid? id);
|
ProfileCategoryEntity IsUnique(string name, Guid? id);
|
||||||
void Save(ProfileCategoryEntity profileCategoryEntity);
|
void Save(ProfileCategoryEntity profileCategoryEntity);
|
||||||
|
|||||||
@ -9,6 +9,6 @@ public interface IProfileRepository : IRepository
|
|||||||
void Add(ProfileEntity profileEntity);
|
void Add(ProfileEntity profileEntity);
|
||||||
void Remove(ProfileEntity profileEntity);
|
void Remove(ProfileEntity profileEntity);
|
||||||
List<ProfileEntity> GetAll();
|
List<ProfileEntity> GetAll();
|
||||||
ProfileEntity? Get(Guid id);
|
ProfileEntity Get(Guid id);
|
||||||
void Save(ProfileEntity profileEntity);
|
void Save(ProfileEntity profileEntity);
|
||||||
}
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
namespace Artemis.Storage.Repositories.Interfaces;
|
namespace Artemis.Storage.Repositories.Interfaces;
|
||||||
|
|
||||||
public interface IRepository;
|
public interface IRepository
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -21,7 +21,7 @@ internal class PluginRepository : IPluginRepository
|
|||||||
_repository.Insert(pluginEntity);
|
_repository.Insert(pluginEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginEntity? GetPluginByGuid(Guid pluginGuid)
|
public PluginEntity GetPluginByGuid(Guid pluginGuid)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<PluginEntity>(p => p.Id == pluginGuid);
|
return _repository.FirstOrDefault<PluginEntity>(p => p.Id == pluginGuid);
|
||||||
}
|
}
|
||||||
@ -29,6 +29,7 @@ internal class PluginRepository : IPluginRepository
|
|||||||
public void SavePlugin(PluginEntity pluginEntity)
|
public void SavePlugin(PluginEntity pluginEntity)
|
||||||
{
|
{
|
||||||
_repository.Upsert(pluginEntity);
|
_repository.Upsert(pluginEntity);
|
||||||
|
_repository.Database.Checkpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddSetting(PluginSettingEntity pluginSettingEntity)
|
public void AddSetting(PluginSettingEntity pluginSettingEntity)
|
||||||
@ -36,12 +37,12 @@ internal class PluginRepository : IPluginRepository
|
|||||||
_repository.Insert(pluginSettingEntity);
|
_repository.Insert(pluginSettingEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginSettingEntity? GetSettingByGuid(Guid pluginGuid)
|
public PluginSettingEntity GetSettingByGuid(Guid pluginGuid)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.PluginGuid == pluginGuid);
|
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.PluginGuid == pluginGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid)
|
public PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.Name == name && p.PluginGuid == pluginGuid);
|
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.Name == name && p.PluginGuid == pluginGuid);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ internal class ProfileCategoryRepository : IProfileCategoryRepository
|
|||||||
return _repository.Query<ProfileCategoryEntity>().ToList();
|
return _repository.Query<ProfileCategoryEntity>().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileCategoryEntity? Get(Guid id)
|
public ProfileCategoryEntity Get(Guid id)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Id == id);
|
return _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Id == id);
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ internal class ProfileCategoryRepository : IProfileCategoryRepository
|
|||||||
_repository.Upsert(profileCategoryEntity);
|
_repository.Upsert(profileCategoryEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream? GetProfileIconStream(Guid id)
|
public Stream GetProfileIconStream(Guid id)
|
||||||
{
|
{
|
||||||
if (!_profileIcons.Exists(id))
|
if (!_profileIcons.Exists(id))
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -31,7 +31,7 @@ internal class ProfileRepository : IProfileRepository
|
|||||||
return _repository.Query<ProfileEntity>().ToList();
|
return _repository.Query<ProfileEntity>().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileEntity? Get(Guid id)
|
public ProfileEntity Get(Guid id)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<ProfileEntity>(p => p.Id == id);
|
return _repository.FirstOrDefault<ProfileEntity>(p => p.Id == id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Storage.Migrations;
|
using Artemis.Storage.Migrations.Interfaces;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
@ -10,17 +10,17 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Avalonia" />
|
<PackageReference Include="Avalonia" Version="11.0.9" />
|
||||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" />
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.9" />
|
||||||
<PackageReference Include="Avalonia.Controls.ItemsRepeater" />
|
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="11.0.9" />
|
||||||
<PackageReference Include="Avalonia.ReactiveUI" />
|
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.9" />
|
||||||
<PackageReference Include="Avalonia.Xaml.Behaviors" />
|
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.0.6" />
|
||||||
<PackageReference Include="DynamicData" />
|
<PackageReference Include="DynamicData" Version="8.3.27" />
|
||||||
<PackageReference Include="FluentAvaloniaUI" />
|
<PackageReference Include="FluentAvaloniaUI" Version="2.0.5" />
|
||||||
<PackageReference Include="Material.Icons.Avalonia" />
|
<PackageReference Include="Material.Icons.Avalonia" Version="2.1.0" />
|
||||||
<PackageReference Include="ReactiveUI" />
|
<PackageReference Include="ReactiveUI" Version="19.5.41" />
|
||||||
<PackageReference Include="ReactiveUI.Validation" />
|
<PackageReference Include="ReactiveUI.Validation" Version="3.1.7" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
|
|||||||
@ -18,20 +18,16 @@ internal class DataModelUIService : IDataModelUIService
|
|||||||
private readonly IContainer _container;
|
private readonly IContainer _container;
|
||||||
private readonly List<DataModelVisualizationRegistration> _registeredDataModelDisplays;
|
private readonly List<DataModelVisualizationRegistration> _registeredDataModelDisplays;
|
||||||
private readonly List<DataModelVisualizationRegistration> _registeredDataModelEditors;
|
private readonly List<DataModelVisualizationRegistration> _registeredDataModelEditors;
|
||||||
private readonly PluginSetting<bool> _showFullPaths;
|
|
||||||
private readonly PluginSetting<bool> _showDataModelValues;
|
|
||||||
|
|
||||||
public DataModelUIService(IDataModelService dataModelService, IContainer container, ISettingsService settingsService)
|
public DataModelUIService(IDataModelService dataModelService, IContainer container)
|
||||||
{
|
{
|
||||||
_dataModelService = dataModelService;
|
_dataModelService = dataModelService;
|
||||||
_container = container;
|
_container = container;
|
||||||
_registeredDataModelEditors = new List<DataModelVisualizationRegistration>();
|
_registeredDataModelEditors = new List<DataModelVisualizationRegistration>();
|
||||||
_registeredDataModelDisplays = new List<DataModelVisualizationRegistration>();
|
_registeredDataModelDisplays = new List<DataModelVisualizationRegistration>();
|
||||||
|
|
||||||
RegisteredDataModelEditors = new ReadOnlyCollection<DataModelVisualizationRegistration>(_registeredDataModelEditors);
|
RegisteredDataModelEditors = new ReadOnlyCollection<DataModelVisualizationRegistration>(_registeredDataModelEditors);
|
||||||
RegisteredDataModelDisplays = new ReadOnlyCollection<DataModelVisualizationRegistration>(_registeredDataModelDisplays);
|
RegisteredDataModelDisplays = new ReadOnlyCollection<DataModelVisualizationRegistration>(_registeredDataModelDisplays);
|
||||||
ShowFullPaths = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true);
|
|
||||||
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataModelInputViewModel InstantiateDataModelInputViewModel(DataModelVisualizationRegistration registration, DataModelPropertyAttribute? description, object? initialValue)
|
private DataModelInputViewModel InstantiateDataModelInputViewModel(DataModelVisualizationRegistration registration, DataModelPropertyAttribute? description, object? initialValue)
|
||||||
@ -47,9 +43,7 @@ internal class DataModelUIService : IDataModelUIService
|
|||||||
|
|
||||||
public IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelEditors { get; }
|
public IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelEditors { get; }
|
||||||
public IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelDisplays { get; }
|
public IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelDisplays { get; }
|
||||||
public PluginSetting<bool> ShowFullPaths { get; }
|
|
||||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
|
||||||
|
|
||||||
public DataModelPropertiesViewModel GetMainDataModelVisualization()
|
public DataModelPropertiesViewModel GetMainDataModelVisualization()
|
||||||
{
|
{
|
||||||
DataModelPropertiesViewModel viewModel = new(null, null, null);
|
DataModelPropertiesViewModel viewModel = new(null, null, null);
|
||||||
|
|||||||
@ -104,14 +104,4 @@ public interface IDataModelUIService : IArtemisSharedUIService
|
|||||||
/// <param name="updateCallback">A function to call whenever the input was updated (submitted or not)</param>
|
/// <param name="updateCallback">A function to call whenever the input was updated (submitted or not)</param>
|
||||||
/// <returns>The most appropriate input view model for the provided <paramref name="propertyType" /></returns>
|
/// <returns>The most appropriate input view model for the provided <paramref name="propertyType" /></returns>
|
||||||
DataModelInputViewModel? GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute? description, object? initialValue, Action<object?, bool> updateCallback);
|
DataModelInputViewModel? GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute? description, object? initialValue, Action<object?, bool> updateCallback);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a boolean indicating whether or not to show full paths when displaying data model paths.
|
|
||||||
/// </summary>
|
|
||||||
PluginSetting<bool> ShowFullPaths { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a boolean indicating whether or not to show values when displaying data model paths.
|
|
||||||
/// </summary>
|
|
||||||
PluginSetting<bool> ShowDataModelValues { get; }
|
|
||||||
}
|
}
|
||||||
@ -27,7 +27,6 @@ public class AddNode : INodeEditorCommand, IDisposable
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins
|
|
||||||
if (_isRemoved && _node is IDisposable disposableNode)
|
if (_isRemoved && _node is IDisposable disposableNode)
|
||||||
disposableNode.Dispose();
|
disposableNode.Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,6 @@ public class DeleteNode : INodeEditorCommand, IDisposable
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins
|
|
||||||
if (_isRemoved && _node is IDisposable disposableNode)
|
if (_isRemoved && _node is IDisposable disposableNode)
|
||||||
disposableNode.Dispose();
|
disposableNode.Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,7 +87,6 @@ public class DuplicateNode : INodeEditorCommand, IDisposable
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins
|
|
||||||
if (!_executed && _copy is IDisposable disposableNode)
|
if (!_executed && _copy is IDisposable disposableNode)
|
||||||
disposableNode.Dispose();
|
disposableNode.Dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/Artemis.UI.Shared/nuget.config
Normal file
11
src/Artemis.UI.Shared/nuget.config
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
To use the Avalonia CI feed to get unstable packages, move this file to the root of your solution.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="AvaloniaCI" value="https://www.myget.org/F/avalonia-ci/api/v2"/>
|
||||||
|
</packageSources>
|
||||||
|
</configuration>
|
||||||
@ -21,12 +21,13 @@
|
|||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Avalonia.Win32" />
|
<PackageReference Include="Avalonia.Win32" Version="11.0.9" />
|
||||||
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" />
|
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
||||||
<PackageReference Include="Microsoft.Win32" />
|
<PackageReference Include="Microsoft.Win32" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Windows.Compatibility" />
|
<!-- Note: Do NOT upgrade this compatibility package to 8.X before updating to net8, it WILL break -->
|
||||||
<PackageReference Include="RawInput.Sharp" />
|
<PackageReference Include="Microsoft.Windows.Compatibility" Version="8.0.2" />
|
||||||
<PackageReference Include="SkiaSharp.Vulkan.SharpVk" />
|
<PackageReference Include="RawInput.Sharp" Version="0.1.3" />
|
||||||
|
<PackageReference Include="SkiaSharp.Vulkan.SharpVk" Version="2.88.7" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
|
|||||||
@ -10,25 +10,26 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
<ProjectReference Include="..\Artemis.UI.Shared\Artemis.UI.Shared.csproj" />
|
<ProjectReference Include="..\Artemis.UI.Shared\Artemis.UI.Shared.csproj" />
|
||||||
|
<ProjectReference Include="..\Artemis.VisualScripting\Artemis.VisualScripting.csproj" />
|
||||||
<ProjectReference Include="..\Artemis.WebClient.Updating\Artemis.WebClient.Updating.csproj" />
|
<ProjectReference Include="..\Artemis.WebClient.Updating\Artemis.WebClient.Updating.csproj" />
|
||||||
<ProjectReference Include="..\Artemis.WebClient.Workshop\Artemis.WebClient.Workshop.csproj" />
|
<ProjectReference Include="..\Artemis.WebClient.Workshop\Artemis.WebClient.Workshop.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AsyncImageLoader.Avalonia" />
|
<PackageReference Include="AsyncImageLoader.Avalonia" Version="3.2.1" />
|
||||||
<PackageReference Include="Avalonia.AvaloniaEdit" />
|
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.0.6" />
|
||||||
<PackageReference Include="Avalonia.Controls.PanAndZoom" />
|
<PackageReference Include="Avalonia.Controls.PanAndZoom" Version="11.0.0.2" />
|
||||||
<PackageReference Include="Avalonia.Desktop" />
|
<PackageReference Include="Avalonia.Desktop" Version="11.0.9" />
|
||||||
<PackageReference Include="Avalonia.Skia.Lottie" />
|
<PackageReference Include="Avalonia.Skia.Lottie" Version="11.0.0" />
|
||||||
<PackageReference Include="AvaloniaEdit.TextMate" />
|
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.0.6" />
|
||||||
<PackageReference Include="Markdown.Avalonia.Tight" />
|
<PackageReference Include="Markdown.Avalonia.Tight" Version="11.0.2" />
|
||||||
<PackageReference Include="Octopus.Octodiff" />
|
<PackageReference Include="Octopus.Octodiff" Version="2.0.546" />
|
||||||
<PackageReference Include="PropertyChanged.SourceGenerator">
|
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.1.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Splat.DryIoc" />
|
<PackageReference Include="Splat.DryIoc" Version="14.8.12" />
|
||||||
<PackageReference Include="TextMateSharp.Grammars" />
|
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.56" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -10,8 +10,10 @@ using Artemis.UI.Screens.Root;
|
|||||||
using Artemis.UI.Shared.DataModelPicker;
|
using Artemis.UI.Shared.DataModelPicker;
|
||||||
using Artemis.UI.Shared.DryIoc;
|
using Artemis.UI.Shared.DryIoc;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
|
using Artemis.VisualScripting.DryIoc;
|
||||||
using Artemis.WebClient.Updating.DryIoc;
|
using Artemis.WebClient.Updating.DryIoc;
|
||||||
using Artemis.WebClient.Workshop.DryIoc;
|
using Artemis.WebClient.Workshop.DryIoc;
|
||||||
|
using Artemis.WebClient.Workshop.Services;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
@ -47,6 +49,7 @@ public static class ArtemisBootstrapper
|
|||||||
_container.RegisterSharedUI();
|
_container.RegisterSharedUI();
|
||||||
_container.RegisterUpdatingClient();
|
_container.RegisterUpdatingClient();
|
||||||
_container.RegisterWorkshopClient();
|
_container.RegisterWorkshopClient();
|
||||||
|
_container.RegisterNoStringEvaluating();
|
||||||
configureServices?.Invoke(_container);
|
configureServices?.Invoke(_container);
|
||||||
|
|
||||||
_container.UseDryIocDependencyResolver();
|
_container.UseDryIocDependencyResolver();
|
||||||
|
|||||||
@ -18,13 +18,11 @@ using DynamicData;
|
|||||||
using DynamicData.Binding;
|
using DynamicData.Binding;
|
||||||
using PropertyChanged.SourceGenerator;
|
using PropertyChanged.SourceGenerator;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.VisualScripting;
|
namespace Artemis.UI.Screens.VisualScripting;
|
||||||
|
|
||||||
public partial class NodeViewModel : ActivatableViewModelBase
|
public partial class NodeViewModel : ActivatableViewModelBase
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
|
||||||
private readonly INodeEditorService _nodeEditorService;
|
private readonly INodeEditorService _nodeEditorService;
|
||||||
private readonly IWindowService _windowService;
|
private readonly IWindowService _windowService;
|
||||||
private ObservableAsPropertyHelper<bool>? _hasInputPins;
|
private ObservableAsPropertyHelper<bool>? _hasInputPins;
|
||||||
@ -41,9 +39,8 @@ public partial class NodeViewModel : ActivatableViewModelBase
|
|||||||
[Notify] private bool _displayCustomViewModelBelow;
|
[Notify] private bool _displayCustomViewModelBelow;
|
||||||
[Notify] private VerticalAlignment _customViewModelVerticalAlignment;
|
[Notify] private VerticalAlignment _customViewModelVerticalAlignment;
|
||||||
|
|
||||||
public NodeViewModel(NodeScriptViewModel nodeScriptViewModel, INode node, ILogger logger, INodeVmFactory nodeVmFactory, INodeEditorService nodeEditorService, IWindowService windowService)
|
public NodeViewModel(NodeScriptViewModel nodeScriptViewModel, INode node, INodeVmFactory nodeVmFactory, INodeEditorService nodeEditorService, IWindowService windowService)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
|
||||||
_nodeEditorService = nodeEditorService;
|
_nodeEditorService = nodeEditorService;
|
||||||
_windowService = windowService;
|
_windowService = windowService;
|
||||||
NodeScriptViewModel = nodeScriptViewModel;
|
NodeScriptViewModel = nodeScriptViewModel;
|
||||||
@ -140,7 +137,25 @@ public partial class NodeViewModel : ActivatableViewModelBase
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Set up the custom node VM if needed
|
// Set up the custom node VM if needed
|
||||||
SetupCustomNodeViewModel();
|
if (Node is ICustomViewModelNode customViewModelNode)
|
||||||
|
{
|
||||||
|
CustomNodeViewModel = customViewModelNode.GetCustomViewModel(nodeScriptViewModel.NodeScript);
|
||||||
|
if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.AbovePins)
|
||||||
|
DisplayCustomViewModelAbove = true;
|
||||||
|
else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BelowPins)
|
||||||
|
DisplayCustomViewModelBelow = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisplayCustomViewModelBetween = true;
|
||||||
|
|
||||||
|
if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop)
|
||||||
|
CustomViewModelVerticalAlignment = VerticalAlignment.Top;
|
||||||
|
else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop)
|
||||||
|
CustomViewModelVerticalAlignment = VerticalAlignment.Center;
|
||||||
|
else
|
||||||
|
CustomViewModelVerticalAlignment = VerticalAlignment.Bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,35 +209,4 @@ public partial class NodeViewModel : ActivatableViewModelBase
|
|||||||
if (Node.BrokenState != null && Node.BrokenStateException != null)
|
if (Node.BrokenState != null && Node.BrokenStateException != null)
|
||||||
_windowService.ShowExceptionDialog(Node.BrokenState, Node.BrokenStateException);
|
_windowService.ShowExceptionDialog(Node.BrokenState, Node.BrokenStateException);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupCustomNodeViewModel()
|
|
||||||
{
|
|
||||||
if (Node is not ICustomViewModelNode customViewModelNode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CustomNodeViewModel = customViewModelNode.GetCustomViewModel(NodeScriptViewModel.NodeScript);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.Error(e, "Failed to instantiate custom node view model");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.AbovePins)
|
|
||||||
DisplayCustomViewModelAbove = true;
|
|
||||||
else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BelowPins)
|
|
||||||
DisplayCustomViewModelBelow = true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DisplayCustomViewModelBetween = true;
|
|
||||||
|
|
||||||
if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop)
|
|
||||||
CustomViewModelVerticalAlignment = VerticalAlignment.Top;
|
|
||||||
else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop)
|
|
||||||
CustomViewModelVerticalAlignment = VerticalAlignment.Center;
|
|
||||||
else
|
|
||||||
CustomViewModelVerticalAlignment = VerticalAlignment.Bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -93,14 +93,6 @@ public partial class ImageSubmissionViewModel : ValidatableViewModelBase
|
|||||||
Name = vm.Name;
|
Name = vm.Name;
|
||||||
Description = vm.Description;
|
Description = vm.Description;
|
||||||
|
|
||||||
// TODO: Just get rid of this stupid mechanism
|
|
||||||
if (ImageUploadRequest != null)
|
|
||||||
{
|
|
||||||
if (Name != null)
|
|
||||||
ImageUploadRequest.Name = Name;
|
|
||||||
ImageUploadRequest.Description = Description;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,4 +6,5 @@ public interface IRegistrationService : IArtemisUIService
|
|||||||
void RegisterBuiltInDataModelInputs();
|
void RegisterBuiltInDataModelInputs();
|
||||||
void RegisterBuiltInPropertyEditors();
|
void RegisterBuiltInPropertyEditors();
|
||||||
void RegisterControllers();
|
void RegisterControllers();
|
||||||
|
void RegisterBuiltInNodeTypes();
|
||||||
}
|
}
|
||||||
@ -1,4 +1,7 @@
|
|||||||
using System.Linq;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Controllers;
|
using Artemis.UI.Controllers;
|
||||||
@ -10,8 +13,10 @@ using Artemis.UI.Shared.Routing;
|
|||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using Artemis.UI.Shared.Services.ProfileEditor;
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using Artemis.UI.Shared.Services.PropertyInput;
|
using Artemis.UI.Shared.Services.PropertyInput;
|
||||||
|
using Artemis.VisualScripting.Nodes.Mathematics;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using DryIoc;
|
using DryIoc;
|
||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.UI.Services;
|
namespace Artemis.UI.Services;
|
||||||
|
|
||||||
@ -21,6 +26,7 @@ public class RegistrationService : IRegistrationService
|
|||||||
private readonly IInputService _inputService;
|
private readonly IInputService _inputService;
|
||||||
private readonly IContainer _container;
|
private readonly IContainer _container;
|
||||||
private readonly IRouter _router;
|
private readonly IRouter _router;
|
||||||
|
private readonly INodeService _nodeService;
|
||||||
private readonly IPropertyInputService _propertyInputService;
|
private readonly IPropertyInputService _propertyInputService;
|
||||||
private readonly IWebServerService _webServerService;
|
private readonly IWebServerService _webServerService;
|
||||||
private bool _registeredBuiltInPropertyEditors;
|
private bool _registeredBuiltInPropertyEditors;
|
||||||
@ -30,6 +36,7 @@ public class RegistrationService : IRegistrationService
|
|||||||
IInputService inputService,
|
IInputService inputService,
|
||||||
IPropertyInputService propertyInputService,
|
IPropertyInputService propertyInputService,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
|
INodeService nodeService,
|
||||||
IDataModelUIService dataModelUIService,
|
IDataModelUIService dataModelUIService,
|
||||||
IWebServerService webServerService,
|
IWebServerService webServerService,
|
||||||
IDeviceLayoutService deviceLayoutService // here to make sure it is instantiated
|
IDeviceLayoutService deviceLayoutService // here to make sure it is instantiated
|
||||||
@ -39,11 +46,13 @@ public class RegistrationService : IRegistrationService
|
|||||||
_router = router;
|
_router = router;
|
||||||
_inputService = inputService;
|
_inputService = inputService;
|
||||||
_propertyInputService = propertyInputService;
|
_propertyInputService = propertyInputService;
|
||||||
|
_nodeService = nodeService;
|
||||||
_dataModelUIService = dataModelUIService;
|
_dataModelUIService = dataModelUIService;
|
||||||
_webServerService = webServerService;
|
_webServerService = webServerService;
|
||||||
|
|
||||||
CreateCursorResources();
|
CreateCursorResources();
|
||||||
RegisterRoutes();
|
RegisterRoutes();
|
||||||
|
RegisterBuiltInNodeTypes();
|
||||||
RegisterControllers();
|
RegisterControllers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,4 +105,22 @@ public class RegistrationService : IRegistrationService
|
|||||||
{
|
{
|
||||||
_webServerService.AddController<RemoteController>(Constants.CorePlugin.Features.First().Instance!);
|
_webServerService.AddController<RemoteController>(Constants.CorePlugin.Features.First().Instance!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterBuiltInNodeTypes()
|
||||||
|
{
|
||||||
|
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(bool), new SKColor(0xFFCD3232));
|
||||||
|
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(string), new SKColor(0xFFFFD700));
|
||||||
|
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(Numeric), new SKColor(0xFF32CD32));
|
||||||
|
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(float), new SKColor(0xFFFF7C00));
|
||||||
|
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(SKColor), new SKColor(0xFFAD3EED));
|
||||||
|
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(IList), new SKColor(0xFFED3E61));
|
||||||
|
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(Enum), new SKColor(0xFF1E90FF));
|
||||||
|
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(ColorGradient), new SKColor(0xFF00B2A9));
|
||||||
|
|
||||||
|
foreach (Type nodeType in typeof(SumNumericsNode).Assembly.GetTypes().Where(t => typeof(INode).IsAssignableFrom(t) && t.IsPublic && !t.IsAbstract && !t.IsInterface))
|
||||||
|
{
|
||||||
|
if (nodeType.GetCustomAttribute(typeof(NodeAttribute)) != null)
|
||||||
|
_nodeService.RegisterNodeType(Constants.CorePlugin, nodeType);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
17
src/Artemis.VisualScripting/Artemis.VisualScripting.csproj
Normal file
17
src/Artemis.VisualScripting/Artemis.VisualScripting.csproj
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<Platforms>x64</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="NoStringEvaluating" Version="2.5.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\Artemis.UI.Shared\Artemis.UI.Shared.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
25
src/Artemis.VisualScripting/Converters/JsonConverter.cs
Normal file
25
src/Artemis.VisualScripting/Converters/JsonConverter.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Artemis.VisualScripting.Converters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts input into <see cref="Numeric" />.
|
||||||
|
/// </summary>
|
||||||
|
public class JsonConverter : IValueConverter
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return JsonConvert.SerializeObject(value, Formatting.Indented);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
string? json = value?.ToString();
|
||||||
|
return json == null ? null : JsonConvert.DeserializeObject(json, targetType);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/Artemis.VisualScripting/Converters/NumericConverter.cs
Normal file
27
src/Artemis.VisualScripting/Converters/NumericConverter.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Artemis.Core;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
|
||||||
|
namespace Artemis.VisualScripting.Converters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts input into <see cref="Numeric" />.
|
||||||
|
/// </summary>
|
||||||
|
public class NumericConverter : IValueConverter
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
if (value is not Numeric numeric)
|
||||||
|
return value;
|
||||||
|
|
||||||
|
object result = Numeric.IsTypeCompatible(targetType) ? numeric.ToType(targetType, NumberFormatInfo.InvariantInfo) : value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return new Numeric(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs
Normal file
41
src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using DryIoc;
|
||||||
|
using Microsoft.Extensions.ObjectPool;
|
||||||
|
using NoStringEvaluating;
|
||||||
|
using NoStringEvaluating.Contract;
|
||||||
|
using NoStringEvaluating.Models.Values;
|
||||||
|
using NoStringEvaluating.Services.Cache;
|
||||||
|
using NoStringEvaluating.Services.Checking;
|
||||||
|
using NoStringEvaluating.Services.Parsing;
|
||||||
|
using NoStringEvaluating.Services.Parsing.NodeReaders;
|
||||||
|
|
||||||
|
namespace Artemis.VisualScripting.DryIoc;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides an extension method to register services onto a DryIoc <see cref="IContainer"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static class ContainerExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Registers NoStringEvaluating services into the container.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container">The builder building the current container</param>
|
||||||
|
public static void RegisterNoStringEvaluating(this IContainer container)
|
||||||
|
{
|
||||||
|
// Pooling
|
||||||
|
container.RegisterInstance(ObjectPool.Create<Stack<InternalEvaluatorValue>>());
|
||||||
|
container.RegisterInstance(ObjectPool.Create<List<InternalEvaluatorValue>>());
|
||||||
|
container.RegisterInstance(ObjectPool.Create<ValueKeeperContainer>());
|
||||||
|
|
||||||
|
// Parser
|
||||||
|
container.Register<IFormulaCache, FormulaCache>(Reuse.Singleton);
|
||||||
|
container.Register<IFunctionReader, FunctionReader>(Reuse.Singleton);
|
||||||
|
container.Register<IFormulaParser, FormulaParser>(Reuse.Singleton);
|
||||||
|
|
||||||
|
// Checker
|
||||||
|
container.Register<IFormulaChecker, FormulaChecker>(Reuse.Singleton);
|
||||||
|
|
||||||
|
// Evaluator
|
||||||
|
container.Register<INoStringEvaluator, NoStringEvaluator>(Reuse.Singleton);
|
||||||
|
container.Register<INoStringEvaluatorNullable, NoStringEvaluatorNullable>(Reuse.Singleton);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Core.Events;
|
||||||
|
|
||||||
|
namespace Artemis.VisualScripting.Nodes.Branching;
|
||||||
|
|
||||||
|
[Node("Branch", "Forwards one of two values depending on an input boolean", "Branching", InputType = typeof(object), OutputType = typeof(object))]
|
||||||
|
public class BooleanBranchNode : Node
|
||||||
|
{
|
||||||
|
public BooleanBranchNode()
|
||||||
|
{
|
||||||
|
BooleanInput = CreateInputPin<bool>();
|
||||||
|
TrueInput = CreateInputPin(typeof(object), "True");
|
||||||
|
FalseInput = CreateInputPin(typeof(object), "False");
|
||||||
|
|
||||||
|
Output = CreateOutputPin(typeof(object));
|
||||||
|
|
||||||
|
TrueInput.PinConnected += InputPinConnected;
|
||||||
|
FalseInput.PinConnected += InputPinConnected;
|
||||||
|
TrueInput.PinDisconnected += InputPinDisconnected;
|
||||||
|
FalseInput.PinDisconnected += InputPinDisconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputPin<bool> BooleanInput { get; set; }
|
||||||
|
public InputPin TrueInput { get; set; }
|
||||||
|
public InputPin FalseInput { get; set; }
|
||||||
|
|
||||||
|
public OutputPin Output { get; set; }
|
||||||
|
|
||||||
|
#region Overrides of Node
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Evaluate()
|
||||||
|
{
|
||||||
|
Output.Value = BooleanInput.Value ? TrueInput.Value : FalseInput.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void InputPinConnected(object? sender, SingleValueEventArgs<IPin> e)
|
||||||
|
{
|
||||||
|
if (TrueInput.ConnectedTo.Any())
|
||||||
|
ChangeType(TrueInput.ConnectedTo.First().Type);
|
||||||
|
else if (FalseInput.ConnectedTo.Any())
|
||||||
|
ChangeType(FalseInput.ConnectedTo.First().Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InputPinDisconnected(object? sender, SingleValueEventArgs<IPin> e)
|
||||||
|
{
|
||||||
|
if (!TrueInput.ConnectedTo.Any() && !FalseInput.ConnectedTo.Any())
|
||||||
|
ChangeType(typeof(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChangeType(Type type)
|
||||||
|
{
|
||||||
|
TrueInput.ChangeType(type);
|
||||||
|
FalseInput.ChangeType(type);
|
||||||
|
Output.ChangeType(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user