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

Node system - Added numeric struct and utilized it in nodes

This commit is contained in:
Robert 2021-09-30 23:28:01 +02:00
parent 4f5d76de88
commit 50b4c71142
16 changed files with 460 additions and 223 deletions

View File

@ -0,0 +1,289 @@
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Artemis.Core
{
/// <summary>
/// Represents a number, either decimal or not, with arbitrary precision.
/// <para>
/// Note: This struct is intended to be used by the node system when implementing your own <see cref="Node" />.
/// Usage outside that context is not recommended due to conversion overhead.
/// </para>
/// </summary>
public readonly struct Numeric : IComparable<Numeric>
{
private readonly float _value;
#region Constructors
/// <summary>
/// Creates a new instance of <see cref="Numeric" /> from a <see cref="float" />
/// </summary>
public Numeric(float value)
{
_value = value;
}
/// <summary>
/// Creates a new instance of <see cref="Numeric" /> from an <see cref="int" />
/// </summary>
public Numeric(int value)
{
_value = value;
}
/// <summary>
/// Creates a new instance of <see cref="Numeric" /> from a <see cref="double" />
/// </summary>
public Numeric(double value)
{
_value = (float) value;
}
/// <summary>
/// Creates a new instance of <see cref="Numeric" /> from a <see cref="byte" />
/// </summary>
public Numeric(byte value)
{
_value = value;
}
/// <summary>
/// Creates a new instance of <see cref="Numeric" /> from an <see cref="object" />
/// </summary>
public Numeric(object? pathValue)
{
_value = pathValue switch
{
float value => value,
int value => value,
double value => (float) value,
byte value => value,
_ => ParseFloatOrDefault(pathValue?.ToString())
};
}
private static float ParseFloatOrDefault(string? pathValue)
{
float.TryParse(pathValue, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out float parsedFloat);
return parsedFloat;
}
#endregion
#region Relational members
/// <inheritdoc />
public int CompareTo(Numeric other)
{
return _value.CompareTo(other._value);
}
#endregion
#region Equality members
/// <summary>
/// Indicates whether this instance and a specified numeric are equal
/// </summary>
/// <param name="other">The numeric to compare with the current instance</param>
/// <returns>
/// <see langword="true" /> if this numeric and the provided <paramref name="other" /> are equal; otherwise,
/// <see langword="false" />.
/// </returns>
public bool Equals(Numeric other)
{
return _value.Equals(other._value);
}
/// <inheritdoc />
public override bool Equals(object? obj)
{
return obj is Numeric other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return _value.GetHashCode();
}
#endregion
#region Formatting members
/// <inheritdoc />
public override string ToString()
{
return _value.ToString(CultureInfo.InvariantCulture);
}
#endregion
#region Operators
#pragma warning disable 1591
public static implicit operator float(Numeric p)
{
return p._value;
}
public static implicit operator int(Numeric p)
{
return (int) MathF.Round(p._value, MidpointRounding.AwayFromZero);
}
public static implicit operator double(Numeric p)
{
return p._value;
}
public static implicit operator byte(Numeric p)
{
return (byte) Math.Clamp(p._value, 0, 255);
}
public static bool operator >(Numeric a, Numeric b)
{
return a._value > b._value;
}
public static bool operator <(Numeric a, Numeric b)
{
return a._value < b._value;
}
public static bool operator ==(Numeric left, Numeric right)
{
return left.Equals(right);
}
public static bool operator !=(Numeric left, Numeric right)
{
return !(left == right);
}
public static bool operator <=(Numeric left, Numeric right)
{
return left.CompareTo(right) <= 0;
}
public static bool operator >=(Numeric left, Numeric right)
{
return left.CompareTo(right) >= 0;
}
public static Numeric operator +(Numeric a)
{
return new Numeric(+a._value);
}
public static Numeric operator -(Numeric a)
{
return new Numeric(-a._value);
}
public static Numeric operator ++(Numeric a)
{
return new Numeric(a._value + 1);
}
public static Numeric operator --(Numeric a)
{
return new Numeric(a._value - 1);
}
public static Numeric operator +(Numeric a, Numeric b)
{
return new Numeric(a._value + b._value);
}
public static Numeric operator -(Numeric a, Numeric b)
{
return new Numeric(a._value - b._value);
}
public static Numeric operator *(Numeric a, Numeric b)
{
return new Numeric(a._value * b._value);
}
public static Numeric operator %(Numeric a, Numeric b)
{
return new Numeric(a._value % b._value);
}
public static Numeric operator /(Numeric a, Numeric b)
{
if (b._value == 0)
throw new DivideByZeroException();
return new Numeric(a._value / b._value);
}
#pragma warning restore 1591
#endregion
/// <summary>
/// Converts the string representation of a number into a numeric. A return value indicates whether the conversion
/// succeeded or failed.
/// </summary>
/// <param name="s">A string representing a number to convert.</param>
/// <param name="result">
/// When this method returns, contains numeric equivalent to the numeric value or symbol contained in
/// <paramref name="s" />, if the conversion succeeded, or zero if the conversion failed.
/// </param>
/// <returns><see langword="true" /> if s was converted successfully; otherwise, <see langword="false" />.</returns>
public static bool TryParse(string? s, out Numeric result)
{
bool parsed = float.TryParse(s, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out float parsedFloat);
if (!parsed)
{
result = new Numeric(0);
return false;
}
result = new Numeric(parsedFloat);
return true;
}
/// <summary>
/// Returns a boolean indicating whether the provided type can be used as a <see cref="Numeric" />.
/// </summary>
public static bool IsTypeCompatible(Type type)
{
return type == typeof(Numeric) ||
type == typeof(float) ||
type == typeof(double) ||
type == typeof(int) ||
type == typeof(byte);
}
}
/// <summary>
/// Provides <see cref="Numeric" /> alternatives for common number-type extensions
/// </summary>
public static class NumericExtensions
{
#region Extensions
/// <summary>
/// Sums the numerics in the provided collection
/// </summary>
/// <returns>The sum of all numerics in the collection</returns>
/// <exception cref="ArgumentNullException"></exception>
public static Numeric Sum(this IEnumerable<Numeric> source)
{
if (source == null) throw new ArgumentNullException(nameof(source));
float sum = 0;
foreach (float v in source) sum += v;
return new Numeric(sum);
}
#endregion
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Globalization;
using System.Windows.Data;
using Artemis.Core;
namespace Artemis.UI.Shared
{
/// <summary>
/// Converts <see cref="T:System.String" /> into <see cref="Numeric" />.
/// </summary>
[ValueConversion(typeof(string), typeof(Numeric))]
public class StringToNumericConverter : IValueConverter
{
/// <inheritdoc />
public object? Convert(object? value, Type targetType, object parameter, CultureInfo culture)
{
return value?.ToString();
}
/// <inheritdoc />
public object ConvertBack(object? value, Type targetType, object parameter, CultureInfo culture)
{
Numeric.TryParse(value as string, out Numeric result);
return result;
}
}
}

View File

@ -132,7 +132,7 @@ namespace Artemis.UI.Services
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(IList), new SKColor(0xFFED3E61));
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(Enum), new SKColor(0xFF1E90FF));
foreach (Type nodeType in typeof(SumIntegersNode).Assembly.GetTypes().Where(t => typeof(INode).IsAssignableFrom(t) && t.IsPublic && !t.IsAbstract && !t.IsInterface))
foreach (Type nodeType in typeof(SumNumericsNode).Assembly.GetTypes().Where(t => typeof(INode).IsAssignableFrom(t) && t.IsPublic && !t.IsAbstract && !t.IsInterface))
_nodeService.RegisterNodeType(Constants.CorePlugin, nodeType);
}

View File

@ -65,7 +65,7 @@
<Page Update="Nodes\DataModel\CustomViews\DataModelEventNodeCustomView.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
</Page>
<Page Update="Nodes\CustomViews\StaticFloatValueNodeCustomView.xaml">
<Page Update="Nodes\CustomViews\StaticNumericValueNodeCustomView.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
</Page>
<Page Update="ResourceDictionaries\DataModelConditions.xaml">

View File

@ -2,6 +2,7 @@
using System.Collections;
using System.Linq;
using Artemis.Core;
using Artemis.VisualScripting.Nodes.CustomViewModels;
namespace Artemis.VisualScripting.Nodes
{
@ -33,6 +34,12 @@ namespace Artemis.VisualScripting.Nodes
public override void Evaluate()
{
if (Input1.Value is Numeric numeric1 && Input2.Value is Numeric numeric2)
{
Result.Value = numeric1 > numeric2;
return;
}
if (Input2.Value != null && Input1.Value != null && Input1.Value.IsNumber() && Input2.Value.IsNumber())
{
Result.Value = Convert.ToSingle(Input1.Value) > Convert.ToSingle(Input2.Value);
@ -80,6 +87,12 @@ namespace Artemis.VisualScripting.Nodes
public override void Evaluate()
{
if (Input1.Value is Numeric numeric1 && Input2.Value is Numeric numeric2)
{
Result.Value = numeric1 < numeric2;
return;
}
if (Input2.Value != null && Input1.Value != null && Input1.Value.IsNumber() && Input2.Value.IsNumber())
{
Result.Value = Convert.ToSingle(Input1.Value) < Convert.ToSingle(Input2.Value);
@ -263,4 +276,27 @@ namespace Artemis.VisualScripting.Nodes
#endregion
}
[Node("Enum Equals", "Determines the equality between an input and a selected enum value", "Operators", InputType = typeof(Enum), OutputType = typeof(bool))]
public class EnumEqualsNode : Node<Enum, EnumEqualsNodeCustomViewModel>
{
public EnumEqualsNode() : base("Enum Equals", "Determines the equality between an input and a selected enum value")
{
InputPin = CreateInputPin<Enum>();
OutputPin = CreateOutputPin<bool>();
}
public InputPin<Enum> InputPin { get; }
public OutputPin<bool> OutputPin { get; }
#region Overrides of Node
/// <inheritdoc />
public override void Evaluate()
{
OutputPin.Value = InputPin.Value != null && InputPin.Value.Equals(Storage);
}
#endregion
}
}

View File

@ -3,20 +3,20 @@ using SkiaSharp;
namespace Artemis.VisualScripting.Nodes.Color
{
[Node("HSL Color", "Creates a color from hue, saturation and lightness values", "Color", InputType = typeof(float), OutputType = typeof(SKColor))]
[Node("HSL Color", "Creates a color from hue, saturation and lightness values", "Color", InputType = typeof(Numeric), OutputType = typeof(SKColor))]
public class HslSKColorNode : Node
{
public HslSKColorNode() : base("HSL Color", "Creates a color from hue, saturation and lightness values")
{
H = CreateInputPin<float>("H");
S = CreateInputPin<float>("S");
L = CreateInputPin<float>("L");
H = CreateInputPin<Numeric>("H");
S = CreateInputPin<Numeric>("S");
L = CreateInputPin<Numeric>("L");
Output = CreateOutputPin<SKColor>();
}
public InputPin<float> H { get; set; }
public InputPin<float> S { get; set; }
public InputPin<float> L { get; set; }
public InputPin<Numeric> H { get; set; }
public InputPin<Numeric> S { get; set; }
public InputPin<Numeric> L { get; set; }
public OutputPin<SKColor> Output { get; }
#region Overrides of Node

View File

@ -34,24 +34,24 @@ namespace Artemis.VisualScripting.Nodes
#endregion
}
[Node("To Integer", "Converts the input to an integer.", "Conversion", InputType = typeof(object), OutputType = typeof(int))]
public class ConvertToIntegerNode : Node
[Node("To Numeric", "Converts the input to a numeric.", "Conversion", InputType = typeof(object), OutputType = typeof(Numeric))]
public class ConvertToNumericNode : Node
{
#region Properties & Fields
public InputPin<object> Input { get; }
public OutputPin<int> Integer { get; }
public OutputPin<Numeric> Output { get; }
#endregion
#region Constructors
public ConvertToIntegerNode()
: base("To Integer", "Converts the input to an integer.")
public ConvertToNumericNode()
: base("To Numeric", "Converts the input to a numeric.")
{
Input = CreateInputPin<object>();
Integer = CreateOutputPin<int>();
Output = CreateOutputPin<Numeric>();
}
#endregion
@ -60,66 +60,19 @@ namespace Artemis.VisualScripting.Nodes
public override void Evaluate()
{
Integer.Value = Input.Value switch
Output.Value = Input.Value switch
{
int input => input,
double input => (int) input,
float input => (int) input,
int input => new Numeric(input),
double input => new Numeric(input),
float input => new Numeric(input),
byte input => new Numeric(input),
_ => TryParse(Input.Value)
};
}
private int TryParse(object input)
private Numeric TryParse(object input)
{
if (!int.TryParse(input?.ToString(), out int value))
value = 0;
return value;
}
#endregion
}
[Node("To Float", "Converts the input to a float.", "Conversion", InputType = typeof(object), OutputType = typeof(float))]
public class ConvertToFloatNode : Node
{
#region Properties & Fields
public InputPin<object> Input { get; }
public OutputPin<float> Float { get; }
#endregion
#region Constructors
public ConvertToFloatNode()
: base("To Float", "Converts the input to a float.")
{
Input = CreateInputPin<object>();
Float = CreateOutputPin<float>();
}
#endregion
#region Methods
public override void Evaluate()
{
Float.Value = Input.Value switch
{
int input => input,
double input => (float) input,
float input => input,
_ => TryParse(Input.Value)
};
}
private float TryParse(object input)
{
if (!float.TryParse(input?.ToString(), out float value))
value = 0.0f;
Numeric.TryParse(input?.ToString(), out Numeric value);
return value;
}

View File

@ -2,23 +2,9 @@
namespace Artemis.VisualScripting.Nodes.CustomViewModels
{
public class StaticDoubleValueNodeCustomViewModel : CustomNodeViewModel
public class StaticNumericValueNodeCustomViewModel : CustomNodeViewModel
{
public StaticDoubleValueNodeCustomViewModel(INode node) : base(node)
{
}
}
public class StaticFloatValueNodeCustomViewModel : CustomNodeViewModel
{
public StaticFloatValueNodeCustomViewModel(INode node) : base(node)
{
}
}
public class StaticIntegerValueNodeCustomViewModel : CustomNodeViewModel
{
public StaticIntegerValueNodeCustomViewModel(INode node) : base(node)
public StaticNumericValueNodeCustomViewModel(INode node) : base(node)
{
}
}

View File

@ -1,12 +1,15 @@
<UserControl x:Class="Artemis.VisualScripting.Nodes.CustomViews.StaticFloatValueNodeCustomView"
<UserControl x:Class="Artemis.VisualScripting.Nodes.CustomViews.StaticNumericValueNodeCustomView"
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.CustomViewModels"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<shared:StringToNumericConverter x:Key="StringToNumericConverter"/>
</UserControl.Resources>
<TextBox VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Text="{Binding Node.Storage}" />
Text="{Binding Node.Storage, Converter={StaticResource StringToNumericConverter}}" />
</UserControl>

View File

@ -53,8 +53,8 @@ namespace Artemis.VisualScripting.Nodes.DataModel
}
else
{
if (pathValue is double doublePathValue)
Output.Value = (float) doublePathValue;
if (Output.Type == typeof(Numeric))
Output.Value = new Numeric(pathValue);
else
Output.Value = pathValue;
}
@ -64,8 +64,8 @@ namespace Artemis.VisualScripting.Nodes.DataModel
public void UpdateOutputPin(bool loadConnections)
{
Type type = DataModelPath?.GetPropertyType();
if (type == typeof(double))
type = typeof(float);
if (Numeric.IsTypeCompatible(type))
type = typeof(Numeric);
if (Output != null && Output.Type == type)
return;
@ -76,7 +76,7 @@ namespace Artemis.VisualScripting.Nodes.DataModel
Output = null;
}
if (type != null)
if (type != null)
Output = CreateOutputPin(type);
if (loadConnections && Script is NodeScript nodeScript)

View File

@ -3,8 +3,8 @@ using Artemis.Core;
namespace Artemis.VisualScripting.Nodes.Easing
{
[Node("Float Easing", "Outputs an eased float value", "Easing", InputType = typeof(float), OutputType = typeof(float))]
public class FloatEasingNode : Node
[Node("Numeric Easing", "Outputs an eased numeric value", "Easing", InputType = typeof(Numeric), OutputType = typeof(Numeric))]
public class NumericEasingNode : Node
{
private DateTime _lastEvaluate = DateTime.MinValue;
private float _progress;
@ -12,20 +12,20 @@ namespace Artemis.VisualScripting.Nodes.Easing
private float _sourceValue;
private float _targetValue;
public FloatEasingNode() : base("Float Easing", "Outputs an eased float value")
public NumericEasingNode() : base("Numeric Easing", "Outputs an eased numeric value")
{
Input = CreateInputPin<float>();
EasingTime = CreateInputPin<float>("delay");
Input = CreateInputPin<Numeric>();
EasingTime = CreateInputPin<Numeric>("delay");
EasingFunction = CreateInputPin<Easings.Functions>("function");
Output = CreateOutputPin<float>();
Output = CreateOutputPin<Numeric>();
}
public InputPin<float> Input { get; set; }
public InputPin<float> EasingTime { get; set; }
public InputPin<Numeric> Input { get; set; }
public InputPin<Numeric> EasingTime { get; set; }
public InputPin<Easings.Functions> EasingFunction { get; set; }
public OutputPin<float> Output { get; set; }
public OutputPin<Numeric> Output { get; set; }
public override void Evaluate()
{
@ -43,12 +43,12 @@ namespace Artemis.VisualScripting.Nodes.Easing
if (_progress < 1f)
{
Update();
Output.Value = _currentValue;
Output.Value = new Numeric(_currentValue);
}
// Stop updating past 1 and use the target value
else
{
Output.Value = _targetValue;
Output.Value = new Numeric(_targetValue);
}
_lastEvaluate = now;

View File

@ -1,29 +0,0 @@
using System;
using Artemis.Core;
using Artemis.VisualScripting.Nodes.CustomViewModels;
namespace Artemis.VisualScripting.Nodes
{
[Node("Enum Equals", "Determines the equality between an input and a selected enum value", InputType = typeof(Enum), OutputType = typeof(bool))]
public class EnumEqualsNode : Node<Enum, EnumEqualsNodeCustomViewModel>
{
public EnumEqualsNode() : base("Enum Equals", "Determines the equality between an input and a selected enum value")
{
InputPin = CreateInputPin<Enum>();
OutputPin = CreateOutputPin<bool>();
}
public InputPin<Enum> InputPin { get; }
public OutputPin<bool> OutputPin { get; }
#region Overrides of Node
/// <inheritdoc />
public override void Evaluate()
{
OutputPin.Value = InputPin.Value != null && InputPin.Value.Equals(Storage);
}
#endregion
}
}

View File

@ -8,7 +8,7 @@ using NoStringEvaluating.Models.Values;
namespace Artemis.VisualScripting.Nodes.Maths
{
[Node("Math Expression", "Outputs the result of a math expression.", "Mathematics", InputType = typeof(float), OutputType = typeof(float))]
[Node("Math Expression", "Outputs the result of a math expression.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))]
public class MathExpressionNode : Node<string, MathExpressionNodeCustomViewModel>
{
private readonly INoStringEvaluator _evaluator;
@ -20,8 +20,8 @@ namespace Artemis.VisualScripting.Nodes.Maths
: base("Math Expression", "Outputs the result of a math expression.")
{
_evaluator = evaluator;
Output = CreateOutputPin<float>();
Values = CreateInputPinCollection<float>("Values", 2);
Output = CreateOutputPin<Numeric>();
Values = CreateInputPinCollection<Numeric>("Values", 2);
Values.PinAdded += (_, _) => SetPinNames();
Values.PinRemoved += (_, _) => SetPinNames();
_variables = new PinsVariablesContainer(Values);
@ -33,8 +33,8 @@ namespace Artemis.VisualScripting.Nodes.Maths
#region Properties & Fields
public OutputPin<float> Output { get; }
public InputPinCollection<float> Values { get; }
public OutputPin<Numeric> Output { get; }
public InputPinCollection<Numeric> Values { get; }
#endregion
@ -43,7 +43,7 @@ namespace Artemis.VisualScripting.Nodes.Maths
public override void Evaluate()
{
if (Storage != null)
Output.Value = (float) _evaluator.CalcNumber(Storage, _variables);
Output.Value = new Numeric(_evaluator.CalcNumber(Storage, _variables));
}
private void SetPinNames()
@ -76,9 +76,9 @@ namespace Artemis.VisualScripting.Nodes.Maths
public class PinsVariablesContainer : IVariablesContainer
{
private readonly InputPinCollection<float> _values;
private readonly InputPinCollection<Numeric> _values;
public PinsVariablesContainer(InputPinCollection<float> values)
public PinsVariablesContainer(InputPinCollection<Numeric> values)
{
_values = values;
}
@ -95,17 +95,23 @@ namespace Artemis.VisualScripting.Nodes.Maths
public EvaluatorValue GetValue(string name)
{
IPin pin = _values.FirstOrDefault(v => v.Name == name);
return pin == null ? new EvaluatorValue(0) : new EvaluatorValue((double) pin.PinValue);
if (pin?.PinValue is Numeric numeric)
return new EvaluatorValue(numeric);
return new EvaluatorValue(0);
}
/// <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);
if (pin?.PinValue is Numeric numeric)
{
value = new EvaluatorValue(numeric);
return true;
}
return pin != null;
value = new EvaluatorValue(0);
return false;
}
#endregion

View File

@ -0,0 +1,28 @@
using System;
using Artemis.Core;
namespace Artemis.VisualScripting.Nodes.Maths
{
[Node("Round", "Outputs a rounded numeric value.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))]
public class RoundNode : Node
{
public RoundNode() : base("Round", "Outputs a rounded numeric value.")
{
Input = CreateInputPin<Numeric>();
Output = CreateOutputPin<Numeric>();
}
public OutputPin<Numeric> Output { get; set; }
public InputPin<Numeric> Input { get; set; }
#region Overrides of Node
/// <inheritdoc />
public override void Evaluate()
{
Output.Value = new Numeric(MathF.Round(Input.Value, MidpointRounding.AwayFromZero));
}
#endregion
}
}

View File

@ -3,50 +3,21 @@ using Artemis.VisualScripting.Nodes.CustomViewModels;
namespace Artemis.VisualScripting.Nodes
{
[Node("Integer-Value", "Outputs a configurable static integer value.", "Static", OutputType = typeof(int))]
public class StaticIntegerValueNode : Node<int, StaticIntegerValueNodeCustomViewModel>
[Node("Numeric-Value", "Outputs a configurable static numeric value.", "Static", OutputType = typeof(Numeric))]
public class StaticNumericValueNode : Node<Numeric, StaticNumericValueNodeCustomViewModel>
{
#region Properties & Fields
public OutputPin<int> Output { get; }
public OutputPin<Numeric> Output { get; }
#endregion
#region Constructors
public StaticIntegerValueNode()
: base("Integer", "Outputs an configurable integer value.")
public StaticNumericValueNode()
: base("Numeric", "Outputs a configurable numeric value.")
{
Output = CreateOutputPin<int>();
}
#endregion
#region Methods
public override void Evaluate()
{
Output.Value = Storage;
}
#endregion
}
[Node("Float-Value", "Outputs a configurable static float value.", "Static", OutputType = typeof(float))]
public class StaticFloatValueNode : Node<float, StaticFloatValueNodeCustomViewModel>
{
#region Properties & Fields
public OutputPin<float> Output { get; }
#endregion
#region Constructors
public StaticFloatValueNode()
: base("Float", "Outputs a configurable float value.")
{
Output = CreateOutputPin<float>();
Output = CreateOutputPin<Numeric>();
}
#endregion

View File

@ -1,26 +1,17 @@
using System.Linq;
using Artemis.Core;
using Artemis.Core;
namespace Artemis.VisualScripting.Nodes
{
[Node("Sum (Integer)", "Sums the connected integer values.", "Mathematics", InputType = typeof(int), OutputType = typeof(int))]
public class SumIntegersNode : Node
[Node("Sum", "Sums the connected numeric values.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))]
public class SumNumericsNode : Node
{
#region Properties & Fields
public InputPinCollection<int> Values { get; }
public OutputPin<int> Sum { get; }
#endregion
#region Constructors
public SumIntegersNode()
: base("Sum", "Sums the connected integer values.")
public SumNumericsNode()
: base("Sum", "Sums the connected numeric values.")
{
Values = CreateInputPinCollection<int>("Values", 2);
Sum = CreateOutputPin<int>("Sum");
Values = CreateInputPinCollection<Numeric>("Values", 2);
Sum = CreateOutputPin<Numeric>("Sum");
}
#endregion
@ -33,37 +24,13 @@ namespace Artemis.VisualScripting.Nodes
}
#endregion
}
[Node("Sum (Float)", "Sums the connected float values.", "Mathematics", InputType = typeof(float), OutputType = typeof(float))]
public class SumFloatsNode : Node
{
#region Properties & Fields
public InputPinCollection<float> Values { get; }
public InputPinCollection<Numeric> Values { get; }
public OutputPin<float> Sum { get; }
#endregion
#region Constructors
public SumFloatsNode()
: base("Sum", "Sums the connected float values.")
{
Values = CreateInputPinCollection<float>("Values", 2);
Sum = CreateOutputPin<float>("Sum");
}
#endregion
#region Methods
public override void Evaluate()
{
Sum.Value = Values.Values.Sum();
}
public OutputPin<Numeric> Sum { get; }
#endregion
}
}
}