1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00
2023-06-22 23:16:49 +02:00

119 lines
3.2 KiB
C#

using Artemis.Core;
using Artemis.VisualScripting.Nodes.Mathematics.Screens;
using NoStringEvaluating.Contract;
using NoStringEvaluating.Models.FormulaChecker;
namespace Artemis.VisualScripting.Nodes.Mathematics;
[Node("Math Expression", "Outputs the result of a math expression.", "Mathematics", "https://wiki.artemis-rgb.com/en/guides/user/profiles/nodes/mathematics/math-expression?mtm_campaign=artemis&mtm_kwd=node-help", InputType = typeof(Numeric), OutputType = typeof(Numeric))]
public class MathExpressionNode : Node<string, MathExpressionNodeCustomViewModel>
{
private readonly IFormulaChecker _checker;
private readonly INoStringEvaluator _evaluator;
private readonly PinsVariablesContainer _variables;
#region Constructors
public MathExpressionNode(INoStringEvaluator evaluator, IFormulaChecker checker)
{
_evaluator = evaluator;
_checker = checker;
Output = CreateOutputPin<Numeric>();
Values = CreateInputPinCollection<Numeric>("Values", 2);
Values.PinAdded += (_, _) => SetPinNames();
Values.PinRemoved += (_, _) => SetPinNames();
_variables = new PinsVariablesContainer(Values);
SetPinNames();
}
#endregion
public bool IsSyntaxValid(string? s)
{
if (s == null)
return true;
if (!_checker.CheckSyntax(s).Ok)
return false;
try
{
_evaluator.CalcNumber(s, _variables);
return true;
}
catch
{
return false;
}
}
public string GetSyntaxErrors(string? s)
{
if (s == null)
return "";
CheckFormulaResult? syntaxCheck = _checker.CheckSyntax(s);
if (!syntaxCheck.Ok)
return string.Join(",", syntaxCheck.Mistakes);
try
{
_evaluator.CalcNumber(s, _variables);
return "";
}
catch (Exception e)
{
return e.Message;
}
}
#region Properties & Fields
public OutputPin<Numeric> Output { get; }
public InputPinCollection<Numeric> Values { get; }
#endregion
#region Methods
public override void Evaluate()
{
try
{
if (Storage != null)
Output.Value = new Numeric(Math.Round(_evaluator.CalcNumber(Storage, _variables), 4, MidpointRounding.AwayFromZero));
}
catch
{
Output.Value = new Numeric(0);
}
}
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
}