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:
parent
4f5d76de88
commit
50b4c71142
289
src/Artemis.Core/Utilities/Numeric.cs
Normal file
289
src/Artemis.Core/Utilities/Numeric.cs
Normal 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
|
||||
}
|
||||
}
|
||||
27
src/Artemis.UI.Shared/Converters/StringToNumericConverter.cs
Normal file
27
src/Artemis.UI.Shared/Converters/StringToNumericConverter.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
28
src/Artemis.VisualScripting/Nodes/Maths/RoundNode.cs
Normal file
28
src/Artemis.VisualScripting/Nodes/Maths/RoundNode.cs
Normal 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
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user