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

Nodes - Added math expression node

Node - Fix visual script cable present event unregister
This commit is contained in:
Robert 2021-08-31 21:37:31 +02:00
parent ecdca26cd3
commit e356d59daa
14 changed files with 290 additions and 22 deletions

View File

@ -8,7 +8,7 @@ namespace Artemis.Core
{
INode Node { get; }
string Name { get; }
string Name { get; set; }
PinDirection Direction { get; }
Type Type { get; }
object PinValue { get; }

View File

@ -10,9 +10,15 @@ namespace Artemis.Core
#region Properties & Fields
public INode Node { get; }
public string Name { get; }
public string Name
{
get => _name;
set => SetAndNotify(ref _name, value);
}
private bool _isEvaluated;
public bool IsEvaluated
{
get => _isEvaluated;
@ -20,6 +26,7 @@ namespace Artemis.Core
}
private readonly List<IPin> _connectedTo = new();
private string _name;
public IReadOnlyList<IPin> ConnectedTo => new ReadOnlyCollection<IPin>(_connectedTo);
public abstract PinDirection Direction { get; }

View File

@ -28,6 +28,7 @@ namespace Artemis.UI.Shared
{
_gradientConverter = new ColorGradientToGradientStopsConverter();
InitializeComponent();
Unloaded += OnUnloaded;
}
/// <summary>
@ -121,7 +122,7 @@ namespace Artemis.UI.Shared
private void UpdateGradientStops()
{
GradientPreview.GradientStops = (GradientStopCollection)_gradientConverter.Convert(ColorGradient, null!, null!, null!);
GradientPreview.GradientStops = (GradientStopCollection) _gradientConverter.Convert(ColorGradient, null!, null!, null!);
}
private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
@ -137,6 +138,11 @@ namespace Artemis.UI.Shared
});
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
ColorGradient.CollectionChanged -= GradientChanged;
}
/// <inheritdoc />
public event PropertyChangedEventHandler? PropertyChanged;

View File

@ -17,6 +17,7 @@ using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using Artemis.UI.Stylet;
using Artemis.UI.Utilities;
using Artemis.VisualScripting.Ninject;
using Ninject;
using Serilog;
using Stylet;
@ -127,6 +128,8 @@ namespace Artemis.UI
kernel.Load<SharedUIModule>();
// Load the core assembly's module
kernel.Load<CoreModule>();
// Load the nodes module
kernel.Load<NoStringNinjectModule>();
base.ConfigureIoC(kernel);
}

View File

@ -289,13 +289,6 @@
</TextBlock>
</StackPanel>
<TextBlock Style="{StaticResource MaterialDesignBody1TextBlock}" LineHeight="25" Margin="10 0 0 0">
- Ben.Demystifier
<Hyperlink Style="{StaticResource ArtemisHyperlink}"
RequestNavigate="{s:Action OpenHyperlink}"
NavigateUri="https://github.com/benaadams/Ben.Demystifier">
https://github.com/benaadams/Ben.Demystifier
</Hyperlink>
<LineBreak />
- EmbedIO
<Hyperlink Style="{StaticResource ArtemisHyperlink}"
RequestNavigate="{s:Action OpenHyperlink}"
@ -380,6 +373,13 @@
http://www.ninject.org/
</Hyperlink>
<LineBreak />
- NoStringEvaluating
<Hyperlink Style="{StaticResource ArtemisHyperlink}"
RequestNavigate="{s:Action OpenHyperlink}"
NavigateUri="https://github.com/KovtunV/NoStringEvaluating">
https://github.com/KovtunV/NoStringEvaluating
</Hyperlink>
<LineBreak />
- Ookii.Dialogs.Wpf
<Hyperlink Style="{StaticResource ArtemisHyperlink}"
RequestNavigate="{s:Action OpenHyperlink}"

View File

@ -281,6 +281,11 @@
"resolved": "5.0.0",
"contentHash": "umBECCoMC+sOUgm083yFr8SxTobUOcPFH4AXigdO2xJiszCHAnmeDl4qPphJt+oaJ/XIfV1wOjIts2nRnki61Q=="
},
"Microsoft.Extensions.ObjectPool": {
"type": "Transitive",
"resolved": "5.0.9",
"contentHash": "grj0e6Me0EQsgaurV0fxP0xd8sz8eZVK+Jb816DPzNADHaqXaXJD3xZX9SFjyDl3ykAYvD0y77o5vRd9Hzsk9g=="
},
"Microsoft.NETCore.Platforms": {
"type": "Transitive",
"resolved": "5.0.0",
@ -382,6 +387,14 @@
"Ninject": "3.3.3"
}
},
"NoStringEvaluating": {
"type": "Transitive",
"resolved": "2.2.1",
"contentHash": "dYvWeDdSXrfWreWu17XUNCZD1QAbeMuyOLwVxNBBy+mbs1O/QjsYr1uQPCJWqYRF2Rd5nQBLFbFWybz4Ndh68g==",
"dependencies": {
"Microsoft.Extensions.ObjectPool": "5.0.9"
}
},
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
@ -1479,6 +1492,8 @@
"Artemis.Core": "1.0.0",
"Artemis.UI.Shared": "2.0.0",
"JetBrains.Annotations": "2021.1.0",
"Ninject": "3.3.4",
"NoStringEvaluating": "2.2.1",
"SkiaSharp": "2.80.3",
"Stylet": "1.3.6"
}

View File

@ -37,6 +37,8 @@
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2021.1.0" />
<PackageReference Include="Ninject" Version="3.3.4" />
<PackageReference Include="NoStringEvaluating" Version="2.2.1" />
<PackageReference Include="SkiaSharp" Version="2.80.3" />
<PackageReference Include="Stylet" Version="1.3.6" />
</ItemGroup>

View File

@ -88,9 +88,9 @@ namespace Artemis.VisualScripting.Editor.Controls
private void OnUnloaded(object sender, RoutedEventArgs e)
{
if (Cable?.From != null)
Cable.From.PropertyChanged += OnPinPropertyChanged;
Cable.From.PropertyChanged -= OnPinPropertyChanged;
if (Cable?.To != null)
Cable.To.PropertyChanged += OnPinPropertyChanged;
Cable.To.PropertyChanged -= OnPinPropertyChanged;
}
private void OnPathMouseDown(object sender, MouseButtonEventArgs args)

View File

@ -71,6 +71,9 @@ namespace Artemis.VisualScripting.Editor.Controls
private void OnUnloaded(object sender, RoutedEventArgs e)
{
LayoutUpdated -= OnLayoutUpdated;
if (Pin != null)
Pin.Node.Node.PropertyChanged -= OnNodePropertyChanged;
_nodePresenter = null;
}

View File

@ -0,0 +1,56 @@
using System.Collections.Generic;
using Microsoft.Extensions.ObjectPool;
using Ninject.Modules;
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.Ninject
{
public class NoStringNinjectModule : NinjectModule
{
public override void Load()
{
// Pooling
Bind<ObjectPool<Stack<InternalEvaluatorValue>>>()
.ToConstant(ObjectPool.Create<Stack<InternalEvaluatorValue>>())
.InSingletonScope();
Bind<ObjectPool<List<InternalEvaluatorValue>>>()
.ToConstant(ObjectPool.Create<List<InternalEvaluatorValue>>())
.InSingletonScope();
Bind<ObjectPool<ExtraTypeIdContainer>>()
.ToConstant(ObjectPool.Create<ExtraTypeIdContainer>())
.InSingletonScope();
// Parser
Bind<IFormulaCache>().To<FormulaCache>().InSingletonScope();
Bind<IFunctionReader>().To<FunctionReader>().InSingletonScope();
Bind<IFormulaParser>().To<FormulaParser>().InSingletonScope();
// Checker
Bind<IFormulaChecker>().To<FormulaChecker>().InSingletonScope();
// Evaluator
Bind<INoStringEvaluator>().To<NoStringEvaluator>().InSingletonScope();
// Options
NoStringEvaluatorOptions opt = new NoStringEvaluatorOptions().SetWordQuotationMark("!");
opt.UpdateConstants();
// If needed
InjectUserDefinedFunctions();
}
private void InjectUserDefinedFunctions()
{
IFunctionReader functionReader = (IFunctionReader) Kernel!.GetService(typeof(IFunctionReader));
NoStringFunctionsInitializer.InitializeFunctions(functionReader, typeof(NoStringNinjectModule));
}
}
}

View File

@ -0,0 +1,37 @@
using System.ComponentModel;
using Artemis.VisualScripting.Nodes.CustomViewModels;
namespace Artemis.VisualScripting.Nodes.Maths.CustomViewModels
{
public class MathExpressionNodeCustomViewModel : CustomNodeViewModel
{
private readonly MathExpressionNode _node;
public MathExpressionNodeCustomViewModel(MathExpressionNode node) : base(node)
{
_node = node;
}
public string Input
{
get => (string)_node.Storage;
set => _node.Storage = value;
}
public override void OnActivate()
{
_node.PropertyChanged += NodeOnPropertyChanged;
}
public override void OnDeactivate()
{
_node.PropertyChanged -= NodeOnPropertyChanged;
}
private void NodeOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Node.Storage))
OnPropertyChanged(nameof(Input));
}
}
}

View File

@ -0,0 +1,12 @@
<UserControl x:Class="Artemis.VisualScripting.Nodes.Maths.CustomViews.MathExpressionNodeCustomView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.VisualScripting.Nodes.Maths.CustomViews"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<TextBox VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"
Text="{Binding Input}" />
</UserControl>

View File

@ -0,0 +1,112 @@
using System;
using System.Linq;
using Artemis.Core;
using Artemis.VisualScripting.Nodes.Maths.CustomViewModels;
using NoStringEvaluating.Contract;
using NoStringEvaluating.Contract.Variables;
using NoStringEvaluating.Models.Values;
namespace Artemis.VisualScripting.Nodes.Maths
{
[Node("Math Expression", "Outputs the result of a math expression.", "Math", OutputType = typeof(int))]
public class MathExpressionNode : Node<MathExpressionNodeCustomViewModel>
{
private readonly INoStringEvaluator _evaluator;
private readonly PinsVariablesContainer _variables;
#region Constructors
public MathExpressionNode(INoStringEvaluator evaluator)
: base("Math Expression", "Outputs the result of a math expression.")
{
_evaluator = evaluator;
Output = CreateOutputPin<float>();
Values = CreateInputPinCollection<float>("Values", 2);
Values.PinAdded += (_, _) => SetPinNames();
Values.PinRemoved += (_, _) => SetPinNames();
_variables = new PinsVariablesContainer(Values);
SetPinNames();
}
#endregion
#region Properties & Fields
public OutputPin<float> Output { get; }
public InputPinCollection<float> Values { get; }
#endregion
#region Methods
public override void Evaluate()
{
if (Storage is string formula)
Output.Value = (float) _evaluator.CalcNumber(formula, _variables);
}
private void SetPinNames()
{
int index = 1;
foreach (IPin value in Values)
{
value.Name = ExcelColumnFromNumber(index).ToLower();
index++;
}
}
public static string ExcelColumnFromNumber(int column)
{
string columnString = "";
decimal columnNumber = column;
while (columnNumber > 0)
{
decimal currentLetterNumber = (columnNumber - 1) % 26;
char currentLetter = (char) (currentLetterNumber + 65);
columnString = currentLetter + columnString;
columnNumber = (columnNumber - (currentLetterNumber + 1)) / 26;
}
return columnString;
}
#endregion
}
public class PinsVariablesContainer : IVariablesContainer
{
private readonly InputPinCollection<float> _values;
public PinsVariablesContainer(InputPinCollection<float> values)
{
_values = values;
}
#region Implementation of IVariablesContainer
/// <inheritdoc />
public IVariable AddOrUpdate(string name, double value)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public EvaluatorValue GetValue(string name)
{
IPin pin = _values.FirstOrDefault(v => v.Name == name);
return pin == null ? new EvaluatorValue(0) : new EvaluatorValue((double) pin.PinValue);
}
/// <inheritdoc />
public bool TryGetValue(string name, out EvaluatorValue value)
{
IPin pin = _values.FirstOrDefault(v => v.Name == name);
double unboxed = (float) pin.PinValue;
value = pin == null ? new EvaluatorValue(0) : new EvaluatorValue(unboxed);
return pin != null;
}
#endregion
}
}

View File

@ -8,6 +8,25 @@
"resolved": "2021.1.0",
"contentHash": "n9JSw5Z+F+6gp9vSv4aLH6p/bx3GAYA6FZVq1wJq/TJySv/kPgFKLGFeS7A8Xa5X4/GWorh5gd43yjamUgnBNA=="
},
"Ninject": {
"type": "Direct",
"requested": "[3.3.4, )",
"resolved": "3.3.4",
"contentHash": "CmbWW97FfJuh4LEOVZM/spqXl4KAulRUjqeMwRd5J9rDMQArmIYaDMU3pyzXXHT062tbF0OPIMwI7tSOtprPfg==",
"dependencies": {
"System.Reflection.Emit.ILGeneration": "4.3.0",
"System.Reflection.Emit.Lightweight": "4.3.0"
}
},
"NoStringEvaluating": {
"type": "Direct",
"requested": "[2.2.1, )",
"resolved": "2.2.1",
"contentHash": "dYvWeDdSXrfWreWu17XUNCZD1QAbeMuyOLwVxNBBy+mbs1O/QjsYr1uQPCJWqYRF2Rd5nQBLFbFWybz4Ndh68g==",
"dependencies": {
"Microsoft.Extensions.ObjectPool": "5.0.9"
}
},
"SkiaSharp": {
"type": "Direct",
"requested": "[2.80.3, )",
@ -107,6 +126,11 @@
"resolved": "5.0.0",
"contentHash": "umBECCoMC+sOUgm083yFr8SxTobUOcPFH4AXigdO2xJiszCHAnmeDl4qPphJt+oaJ/XIfV1wOjIts2nRnki61Q=="
},
"Microsoft.Extensions.ObjectPool": {
"type": "Transitive",
"resolved": "5.0.9",
"contentHash": "grj0e6Me0EQsgaurV0fxP0xd8sz8eZVK+Jb816DPzNADHaqXaXJD3xZX9SFjyDl3ykAYvD0y77o5vRd9Hzsk9g=="
},
"Microsoft.NETCore.Platforms": {
"type": "Transitive",
"resolved": "5.0.0",
@ -196,15 +220,6 @@
"resolved": "13.0.1",
"contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A=="
},
"Ninject": {
"type": "Transitive",
"resolved": "3.3.4",
"contentHash": "CmbWW97FfJuh4LEOVZM/spqXl4KAulRUjqeMwRd5J9rDMQArmIYaDMU3pyzXXHT062tbF0OPIMwI7tSOtprPfg==",
"dependencies": {
"System.Reflection.Emit.ILGeneration": "4.3.0",
"System.Reflection.Emit.Lightweight": "4.3.0"
}
},
"Ninject.Extensions.ChildKernel": {
"type": "Transitive",
"resolved": "3.3.0",