mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Nodes - Added XML docs for remaining types
Nodes - Fully implemented nullable reference types
This commit is contained in:
parent
c1dab91c16
commit
c21acf87a7
@ -93,6 +93,13 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the index of the provided element inside the read only collection
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of element to find</typeparam>
|
||||||
|
/// <param name="self">The collection to search in</param>
|
||||||
|
/// <param name="elementToFind">The element to find</param>
|
||||||
|
/// <returns>If found, the index of the element to find; otherwise -1</returns>
|
||||||
public static int IndexOf<T>(this IReadOnlyCollection<T> self, T elementToFind)
|
public static int IndexOf<T>(this IReadOnlyCollection<T> self, T elementToFind)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -102,6 +109,7 @@ namespace Artemis.Core
|
|||||||
return i;
|
return i;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,9 @@ using Artemis.Storage.Entities.Profile.Conditions;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a condition that is based on a <see cref="DataModelEvent" />
|
||||||
|
/// </summary>
|
||||||
public class EventCondition : CorePropertyChanged, INodeScriptCondition
|
public class EventCondition : CorePropertyChanged, INodeScriptCondition
|
||||||
{
|
{
|
||||||
private readonly string _displayName;
|
private readonly string _displayName;
|
||||||
@ -78,7 +81,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_eventNode = new EventDefaultNode() {X = -300};
|
_eventNode = new EventDefaultNode {X = -300};
|
||||||
_eventNode.UpdateDataModelEvent(dataModelEvent);
|
_eventNode.UpdateDataModelEvent(dataModelEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,11 +3,17 @@ using Artemis.Storage.Entities.Profile.Conditions;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a condition that is based on a data model value
|
||||||
|
/// </summary>
|
||||||
public class StaticCondition : CorePropertyChanged, INodeScriptCondition
|
public class StaticCondition : CorePropertyChanged, INodeScriptCondition
|
||||||
{
|
{
|
||||||
private readonly StaticConditionEntity _entity;
|
|
||||||
private readonly string _displayName;
|
private readonly string _displayName;
|
||||||
|
private readonly StaticConditionEntity _entity;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="StaticCondition" /> class
|
||||||
|
/// </summary>
|
||||||
public StaticCondition(ProfileElement profileElement)
|
public StaticCondition(ProfileElement profileElement)
|
||||||
{
|
{
|
||||||
_entity = new StaticConditionEntity();
|
_entity = new StaticConditionEntity();
|
||||||
|
|||||||
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a data model event that can trigger <see cref="DataModelConditionEvent" />s.
|
/// Represents an event that is part of a data model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IDataModelEvent
|
public interface IDataModelEvent
|
||||||
{
|
{
|
||||||
|
|||||||
@ -82,7 +82,6 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private TimeSpan _position;
|
private TimeSpan _position;
|
||||||
private TimeSpan _lastDelta;
|
private TimeSpan _lastDelta;
|
||||||
private TimeLineEventOverlapMode _eventOverlapMode;
|
|
||||||
private TimelinePlayMode _playMode;
|
private TimelinePlayMode _playMode;
|
||||||
private TimelineStopMode _stopMode;
|
private TimelineStopMode _stopMode;
|
||||||
private readonly List<Timeline> _extraTimelines;
|
private readonly List<Timeline> _extraTimelines;
|
||||||
|
|||||||
@ -114,17 +114,20 @@ namespace Artemis.Core.Modules
|
|||||||
private readonly List<(DefaultCategoryName, string)> _defaultProfilePaths = new();
|
private readonly List<(DefaultCategoryName, string)> _defaultProfilePaths = new();
|
||||||
private readonly List<(DefaultCategoryName, string)> _pendingDefaultProfilePaths = new();
|
private readonly List<(DefaultCategoryName, string)> _pendingDefaultProfilePaths = new();
|
||||||
|
|
||||||
protected Module()
|
|
||||||
{
|
|
||||||
DefaultProfilePaths = new ReadOnlyCollection<(DefaultCategoryName, string)>(_defaultProfilePaths);
|
|
||||||
HiddenProperties = new(HiddenPropertiesList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
|
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected internal readonly List<PropertyInfo> HiddenPropertiesList = new();
|
protected internal readonly List<PropertyInfo> HiddenPropertiesList = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The base constructor of the <see cref="Module" /> class.
|
||||||
|
/// </summary>
|
||||||
|
protected Module()
|
||||||
|
{
|
||||||
|
DefaultProfilePaths = new ReadOnlyCollection<(DefaultCategoryName, string)>(_defaultProfilePaths);
|
||||||
|
HiddenProperties = new ReadOnlyCollection<PropertyInfo>(HiddenPropertiesList);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read only collection of default profile paths
|
/// Gets a read only collection of default profile paths
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -237,7 +240,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual DataModelPropertyAttribute GetDataModelDescription()
|
public virtual DataModelPropertyAttribute GetDataModelDescription()
|
||||||
{
|
{
|
||||||
return new() {Name = Plugin.Info.Name, Description = Plugin.Info.Description};
|
return new DataModelPropertyAttribute {Name = Plugin.Info.Name, Description = Plugin.Info.Description};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -44,9 +44,12 @@ namespace Artemis.Core.ScriptingProviders
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ScriptingProvider : PluginFeature
|
public abstract class ScriptingProvider : PluginFeature
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The base constructor of the <see cref="ScriptingProvider" /> class
|
||||||
|
/// </summary>
|
||||||
protected ScriptingProvider()
|
protected ScriptingProvider()
|
||||||
{
|
{
|
||||||
Scripts = new(InternalScripts);
|
Scripts = new ReadOnlyCollection<Script>(InternalScripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -2,21 +2,28 @@
|
|||||||
|
|
||||||
namespace Artemis.Core.Events
|
namespace Artemis.Core.Events
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an event argument containing a single value of type <typeparamref name="T" />
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of value the argument contains</typeparam>
|
||||||
public class SingleValueEventArgs<T> : EventArgs
|
public class SingleValueEventArgs<T> : EventArgs
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
|
||||||
|
|
||||||
public T Value { get; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
public SingleValueEventArgs(T value)
|
internal SingleValueEventArgs(T value)
|
||||||
{
|
{
|
||||||
this.Value = value;
|
Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value of the argument
|
||||||
|
/// </summary>
|
||||||
|
public T Value { get; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,42 +3,18 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an input pin containing a value of type <typeparamref name="T" /> on a <see cref="INode" />
|
||||||
|
/// </summary>
|
||||||
public sealed class InputPin<T> : Pin
|
public sealed class InputPin<T> : Pin
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
|
||||||
|
|
||||||
public override Type Type { get; } = typeof(T);
|
|
||||||
public override object PinValue => Value;
|
|
||||||
public override PinDirection Direction => PinDirection.Input;
|
|
||||||
|
|
||||||
private T _value;
|
|
||||||
|
|
||||||
public T Value
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!IsEvaluated)
|
|
||||||
Evaluate();
|
|
||||||
|
|
||||||
return _value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_value = value;
|
|
||||||
IsEvaluated = true;
|
|
||||||
OnPropertyChanged(nameof(PinValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
internal InputPin(INode node, string name)
|
internal InputPin(INode node, string name)
|
||||||
: base(node, name)
|
: base(node, name)
|
||||||
{
|
{
|
||||||
|
Value = default;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -47,25 +23,29 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void Evaluate()
|
private void Evaluate()
|
||||||
{
|
{
|
||||||
if (ConnectedTo.Count > 0)
|
if (ConnectedTo.Count > 0 && ConnectedTo[0].PinValue is T value)
|
||||||
if (ConnectedTo[0].PinValue is T value)
|
Value = value;
|
||||||
Value = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class InputPin : Pin
|
|
||||||
{
|
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
public override Type Type { get; }
|
/// <inheritdoc />
|
||||||
public override object PinValue => Value;
|
public override Type Type { get; } = typeof(T);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override object? PinValue => Value;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override PinDirection Direction => PinDirection.Input;
|
public override PinDirection Direction => PinDirection.Input;
|
||||||
|
|
||||||
private object _value;
|
private T? _value;
|
||||||
|
|
||||||
public object Value
|
/// <summary>
|
||||||
|
/// Gets or sets the value of the input pin
|
||||||
|
/// </summary>
|
||||||
|
public T? Value
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -77,8 +57,6 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
if (!Type.IsInstanceOfType(value)) throw new ArgumentException($"Value of type '{value?.GetType().Name ?? "null"}' can't be assigned to a pin of type {Type.Name}.");
|
|
||||||
|
|
||||||
_value = value;
|
_value = value;
|
||||||
IsEvaluated = true;
|
IsEvaluated = true;
|
||||||
OnPropertyChanged(nameof(PinValue));
|
OnPropertyChanged(nameof(PinValue));
|
||||||
@ -86,13 +64,20 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an input pin on a <see cref="INode" />
|
||||||
|
/// </summary>
|
||||||
|
public sealed class InputPin : Pin
|
||||||
|
{
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
internal InputPin(INode node, Type type, string name)
|
internal InputPin(INode node, Type type, string name)
|
||||||
: base(node, name)
|
: base(node, name)
|
||||||
{
|
{
|
||||||
this.Type = type;
|
Type = type;
|
||||||
|
_value = type.GetDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -115,5 +100,54 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Type Type { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override object? PinValue => Value;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override PinDirection Direction => PinDirection.Input;
|
||||||
|
|
||||||
|
private object? _value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the value of the input pin
|
||||||
|
/// </summary>
|
||||||
|
public object? Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!IsEvaluated)
|
||||||
|
Evaluate();
|
||||||
|
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (Type.IsValueType && value == null)
|
||||||
|
{
|
||||||
|
// We can't take null for value types so set it to the default value for that type
|
||||||
|
_value = Type.GetDefault();
|
||||||
|
}
|
||||||
|
else if (value != null)
|
||||||
|
{
|
||||||
|
// If a value was given make sure it matches
|
||||||
|
if (!Type.IsInstanceOfType(value))
|
||||||
|
throw new ArgumentException($"Value of type '{value.GetType().Name}' can't be assigned to a pin of type {Type.Name}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise we're good and we can put a null here if it happens to be that
|
||||||
|
_value = value;
|
||||||
|
IsEvaluated = true;
|
||||||
|
OnPropertyChanged(nameof(PinValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,53 +5,63 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a collection of input pins containing values of type <typeparamref name="T" />
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of value the pins in this collection hold</typeparam>
|
||||||
public sealed class InputPinCollection<T> : PinCollection
|
public sealed class InputPinCollection<T> : PinCollection
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
|
||||||
|
|
||||||
public override PinDirection Direction => PinDirection.Input;
|
|
||||||
public override Type Type => typeof(T);
|
|
||||||
|
|
||||||
public new IEnumerable<InputPin<T>> Pins => base.Pins.Cast<InputPin<T>>();
|
|
||||||
|
|
||||||
public IEnumerable<T> Values => Pins.Select(p => p.Value);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
internal InputPinCollection(INode node, string name, int initialCount)
|
internal InputPinCollection(INode node, string name, int initialCount)
|
||||||
: base(node, name, initialCount)
|
: base(node, name, initialCount)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
protected override IPin CreatePin() => new InputPin<T>(Node, string.Empty);
|
/// <inheritdoc />
|
||||||
|
protected override IPin CreatePin()
|
||||||
|
{
|
||||||
|
return new InputPin<T>(Node, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override PinDirection Direction => PinDirection.Input;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Type Type => typeof(T);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an enumerable of the pins in this collection
|
||||||
|
/// </summary>
|
||||||
|
public new IEnumerable<InputPin<T>> Pins => base.Pins.Cast<InputPin<T>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an enumerable of the values of the pins in this collection
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<T> Values => Pins.Where(p => p.Value != null).Select(p => p.Value!);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a collection of input pins
|
||||||
|
/// </summary>
|
||||||
public sealed class InputPinCollection : PinCollection
|
public sealed class InputPinCollection : PinCollection
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
|
||||||
|
|
||||||
public override PinDirection Direction => PinDirection.Input;
|
|
||||||
public override Type Type { get; }
|
|
||||||
|
|
||||||
public new IEnumerable<InputPin> Pins => base.Pins.Cast<InputPin>();
|
|
||||||
|
|
||||||
public IEnumerable Values => Pins.Select(p => p.Value);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
internal InputPinCollection(INode node, Type type, string name, int initialCount)
|
internal InputPinCollection(INode node, Type type, string name, int initialCount)
|
||||||
: base(node, name, 0)
|
: base(node, name, 0)
|
||||||
{
|
{
|
||||||
this.Type = type;
|
Type = type;
|
||||||
|
|
||||||
// Can't do this in the base constructor because the type won't be set yet
|
// Can't do this in the base constructor because the type won't be set yet
|
||||||
for (int i = 0; i < initialCount; i++)
|
for (int i = 0; i < initialCount; i++)
|
||||||
@ -62,8 +72,32 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
protected override IPin CreatePin() => new InputPin(Node, Type, string.Empty);
|
/// <inheritdoc />
|
||||||
|
protected override IPin CreatePin()
|
||||||
|
{
|
||||||
|
return new InputPin(Node, Type, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override PinDirection Direction => PinDirection.Input;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Type Type { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an enumerable of the pins in this collection
|
||||||
|
/// </summary>
|
||||||
|
public new IEnumerable<InputPin> Pins => base.Pins.Cast<InputPin>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an enumerable of the values of the pins in this collection
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable Values => Pins.Where(p => p.Value != null).Select(p => p.Value);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a node script with a result value of type <paramref name="T" />
|
/// Represents a node script with a result value of type <typeparamref name="T" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of result value</typeparam>
|
/// <typeparam name="T">The type of result value</typeparam>
|
||||||
public interface INodeScript<out T> : INodeScript
|
public interface INodeScript<out T> : INodeScript
|
||||||
@ -73,6 +73,6 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the result of the script
|
/// Gets the result of the script
|
||||||
/// </summary>
|
/// </summary>
|
||||||
T Result { get; }
|
T? Result { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,24 +4,76 @@ using Artemis.Core.Events;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a pin containing a value on a <see cref="INode" />
|
||||||
|
/// </summary>
|
||||||
public interface IPin
|
public interface IPin
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the node the pin belongs to
|
||||||
|
/// </summary>
|
||||||
INode Node { get; }
|
INode Node { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the name of the pin
|
||||||
|
/// </summary>
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
PinDirection Direction { get; }
|
|
||||||
Type Type { get; }
|
|
||||||
object PinValue { get; }
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the direction of the pin
|
||||||
|
/// </summary>
|
||||||
|
PinDirection Direction { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of value the pin holds
|
||||||
|
/// </summary>
|
||||||
|
Type Type { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value the pin holds
|
||||||
|
/// </summary>
|
||||||
|
object? PinValue { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a read only list of pins this pin is connected to
|
||||||
|
/// </summary>
|
||||||
IReadOnlyList<IPin> ConnectedTo { get; }
|
IReadOnlyList<IPin> ConnectedTo { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a boolean indicating whether this pin is evaluated or not
|
||||||
|
/// </summary>
|
||||||
bool IsEvaluated { get; set; }
|
bool IsEvaluated { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the pin connects to another pin
|
||||||
|
/// </summary>
|
||||||
event EventHandler<SingleValueEventArgs<IPin>> PinConnected;
|
event EventHandler<SingleValueEventArgs<IPin>> PinConnected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the pin disconnects from another pin
|
||||||
|
/// </summary>
|
||||||
event EventHandler<SingleValueEventArgs<IPin>> PinDisconnected;
|
event EventHandler<SingleValueEventArgs<IPin>> PinDisconnected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets the pin, causing it to re-evaluate the next time its value is requested
|
||||||
|
/// </summary>
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connects the pin to the provided <paramref name="pin"></paramref>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pin">The pin to connect this pin to</param>
|
||||||
void ConnectTo(IPin pin);
|
void ConnectTo(IPin pin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disconnects the pin to the provided <paramref name="pin"></paramref>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pin">The pin to disconnect this pin to</param>
|
||||||
void DisconnectFrom(IPin pin);
|
void DisconnectFrom(IPin pin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disconnects all pins this pin is connected to
|
||||||
|
/// </summary>
|
||||||
void DisconnectAll();
|
void DisconnectAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,16 +4,56 @@ using Artemis.Core.Events;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a collection of <see cref="IPin" />s on a <see cref="INode" />
|
||||||
|
/// </summary>
|
||||||
public interface IPinCollection : IEnumerable<IPin>
|
public interface IPinCollection : IEnumerable<IPin>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the node the pin collection belongs to
|
||||||
|
/// </summary>
|
||||||
|
INode Node { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the pin collection
|
||||||
|
/// </summary>
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the direction of the pin collection and all its pins
|
||||||
|
/// </summary>
|
||||||
PinDirection Direction { get; }
|
PinDirection Direction { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of values the pin collection and all its pins holds
|
||||||
|
/// </summary>
|
||||||
Type Type { get; }
|
Type Type { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a pin was added to the collection
|
||||||
|
/// </summary>
|
||||||
event EventHandler<SingleValueEventArgs<IPin>> PinAdded;
|
event EventHandler<SingleValueEventArgs<IPin>> PinAdded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a pin was removed from the collection
|
||||||
|
/// </summary>
|
||||||
event EventHandler<SingleValueEventArgs<IPin>> PinRemoved;
|
event EventHandler<SingleValueEventArgs<IPin>> PinRemoved;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new pin and adds it to the collection
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The newly added pin</returns>
|
||||||
IPin AddPin();
|
IPin AddPin();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the provided <paramref name="pin" /> from the collection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pin">The pin to remove</param>
|
||||||
bool Remove(IPin pin);
|
bool Remove(IPin pin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resets the pin collection, causing its pins to re-evaluate the next time its value is requested
|
||||||
|
/// </summary>
|
||||||
|
void Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ namespace Artemis.Core.Internal
|
|||||||
foreach (var (property, inputPin) in _propertyPins)
|
foreach (var (property, inputPin) in _propertyPins)
|
||||||
{
|
{
|
||||||
if (inputPin.ConnectedTo.Any())
|
if (inputPin.ConnectedTo.Any())
|
||||||
_propertyValues[property] = inputPin.Value;
|
_propertyValues[property] = inputPin.Value!;
|
||||||
else
|
else
|
||||||
_propertyValues.Remove(property);
|
_propertyValues.Remove(property);
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ namespace Artemis.Core.Internal
|
|||||||
foreach (IDataBindingProperty property in DataBinding.Properties)
|
foreach (IDataBindingProperty property in DataBinding.Properties)
|
||||||
_propertyPins.Add(property, CreateInputPin(property.ValueType, property.DisplayName));
|
_propertyPins.Add(property, CreateInputPin(property.ValueType, property.DisplayName));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
|
|
||||||
private void DataBindingOnDataBindingPropertyRegistered(object? sender, DataBindingEventArgs e)
|
private void DataBindingOnDataBindingPropertyRegistered(object? sender, DataBindingEventArgs e)
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
public InputPin<T> Input { get; }
|
public InputPin<T> Input { get; }
|
||||||
|
|
||||||
public T Value { get; private set; }
|
public T? Value { get; private set; }
|
||||||
|
|
||||||
public override bool IsExitNode => true;
|
public override bool IsExitNode => true;
|
||||||
|
|
||||||
|
|||||||
@ -239,10 +239,14 @@ namespace Artemis.Core
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public abstract void Evaluate();
|
public abstract void Evaluate();
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual void Reset()
|
public virtual void Reset()
|
||||||
{
|
{
|
||||||
|
foreach (IPin pin in _pins)
|
||||||
|
pin.Reset();
|
||||||
|
foreach (IPinCollection pinCollection in _pinCollections)
|
||||||
|
pinCollection.Reset();
|
||||||
|
|
||||||
Resetting?.Invoke(this, EventArgs.Empty);
|
Resetting?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,38 +2,69 @@
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an attribute that can be used to provide metadata on a node
|
||||||
|
/// </summary>
|
||||||
public class NodeAttribute : Attribute
|
public class NodeAttribute : Attribute
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the node
|
||||||
|
/// </summary>
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public string Description { get; set; }
|
|
||||||
public string Category { get; set; }
|
/// <summary>
|
||||||
public Type InputType { get; set; }
|
/// Gets the description of the node
|
||||||
public Type OutputType { get; set; }
|
/// </summary>
|
||||||
|
public string Description { get; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the category of the node
|
||||||
|
/// </summary>
|
||||||
|
public string Category { get; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the primary input type of the node
|
||||||
|
/// </summary>
|
||||||
|
public Type? InputType { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the primary output type of the node
|
||||||
|
/// </summary>
|
||||||
|
public Type? OutputType { get; init; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="NodeAttribute" /> class
|
||||||
|
/// </summary>
|
||||||
public NodeAttribute(string name)
|
public NodeAttribute(string name)
|
||||||
{
|
{
|
||||||
this.Name = name;
|
Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="NodeAttribute" /> class
|
||||||
|
/// </summary>
|
||||||
public NodeAttribute(string name, string description)
|
public NodeAttribute(string name, string description)
|
||||||
{
|
{
|
||||||
this.Name = name;
|
Name = name;
|
||||||
this.Description = description;
|
Description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="NodeAttribute" /> class
|
||||||
|
/// </summary>
|
||||||
public NodeAttribute(string name, string description, string category)
|
public NodeAttribute(string name, string description, string category)
|
||||||
{
|
{
|
||||||
this.Name = name;
|
Name = name;
|
||||||
this.Description = description;
|
Description = description;
|
||||||
this.Category = category;
|
Category = category;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,43 +3,81 @@ using Artemis.Storage.Entities.Profile.Nodes;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents node data describing a certain <see cref="INode" />
|
||||||
|
/// </summary>
|
||||||
public class NodeData
|
public class NodeData
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
|
||||||
|
|
||||||
public Plugin Plugin { get; }
|
|
||||||
|
|
||||||
public Type Type { get; }
|
|
||||||
public string Name { get; }
|
|
||||||
public string Description { get; }
|
|
||||||
public string Category { get; }
|
|
||||||
public Type? InputType { get; }
|
|
||||||
public Type? OutputType { get; }
|
|
||||||
|
|
||||||
private Func<INodeScript, NodeEntity?, INode> _create;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
internal NodeData(Plugin plugin, Type type, string name, string description, string category, Type? inputType, Type? outputType, Func<INodeScript, NodeEntity?, INode>? create)
|
internal NodeData(Plugin plugin, Type type, string name, string description, string category, Type? inputType, Type? outputType, Func<INodeScript, NodeEntity?, INode> create)
|
||||||
{
|
{
|
||||||
this.Plugin = plugin;
|
Plugin = plugin;
|
||||||
this.Type = type;
|
Type = type;
|
||||||
this.Name = name;
|
Name = name;
|
||||||
this.Description = description;
|
Description = description;
|
||||||
this.Category = category;
|
Category = category;
|
||||||
this.InputType = inputType;
|
InputType = inputType;
|
||||||
this.OutputType = outputType;
|
OutputType = outputType;
|
||||||
this._create = create;
|
_create = create;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
public INode CreateNode(INodeScript script, NodeEntity? entity) => _create(script, entity);
|
/// <summary>
|
||||||
|
/// Creates a new instance of the node this data represents
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="script">The script to create the node for</param>
|
||||||
|
/// <param name="entity">An optional storage entity to apply to the node</param>
|
||||||
|
/// <returns>The returning node of type <see cref="Type" /></returns>
|
||||||
|
public INode CreateNode(INodeScript script, NodeEntity? entity)
|
||||||
|
{
|
||||||
|
return _create(script, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the plugin that provided this node data
|
||||||
|
/// </summary>
|
||||||
|
public Plugin Plugin { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of <see cref="INode" /> this data represents
|
||||||
|
/// </summary>
|
||||||
|
public Type Type { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the node this data represents
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the description of the node this data represents
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the category of the node this data represents
|
||||||
|
/// </summary>
|
||||||
|
public string Category { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the primary input type of the node this data represents
|
||||||
|
/// </summary>
|
||||||
|
public Type? InputType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the primary output of the node this data represents
|
||||||
|
/// </summary>
|
||||||
|
public Type? OutputType { get; }
|
||||||
|
|
||||||
|
private readonly Func<INodeScript, NodeEntity?, INode> _create;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,12 +60,19 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
public NodeScript(string name, string description, object? context = null)
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="NodeScript"/> class with a name, description and optional context
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name of the node script</param>
|
||||||
|
/// <param name="description">The description of the node script</param>
|
||||||
|
/// <param name="context">The context of the node script, usually a <see cref="Profile" /> or <see cref="ProfileConfiguration" /></param>
|
||||||
|
protected NodeScript(string name, string description, object? context = null)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Description = description;
|
Description = description;
|
||||||
Context = context;
|
Context = context;
|
||||||
Entity = new NodeScriptEntity();
|
Entity = new NodeScriptEntity();
|
||||||
|
ExitNode = null!;
|
||||||
|
|
||||||
NodeTypeStore.NodeTypeAdded += NodeTypeStoreOnNodeTypeChanged;
|
NodeTypeStore.NodeTypeAdded += NodeTypeStoreOnNodeTypeChanged;
|
||||||
NodeTypeStore.NodeTypeRemoved += NodeTypeStoreOnNodeTypeChanged;
|
NodeTypeStore.NodeTypeRemoved += NodeTypeStoreOnNodeTypeChanged;
|
||||||
@ -77,6 +84,7 @@ namespace Artemis.Core
|
|||||||
Description = description;
|
Description = description;
|
||||||
Entity = entity;
|
Entity = entity;
|
||||||
Context = context;
|
Context = context;
|
||||||
|
ExitNode = null!;
|
||||||
|
|
||||||
NodeTypeStore.NodeTypeAdded += NodeTypeStoreOnNodeTypeChanged;
|
NodeTypeStore.NodeTypeAdded += NodeTypeStoreOnNodeTypeChanged;
|
||||||
NodeTypeStore.NodeTypeRemoved += NodeTypeStoreOnNodeTypeChanged;
|
NodeTypeStore.NodeTypeRemoved += NodeTypeStoreOnNodeTypeChanged;
|
||||||
@ -176,6 +184,8 @@ namespace Artemis.Core
|
|||||||
if (collection == null)
|
if (collection == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
while (collection.Count() > entityNodePinCollection.Amount)
|
||||||
|
collection.Remove(collection.Last());
|
||||||
while (collection.Count() < entityNodePinCollection.Amount)
|
while (collection.Count() < entityNodePinCollection.Amount)
|
||||||
collection.AddPin();
|
collection.AddPin();
|
||||||
}
|
}
|
||||||
@ -333,7 +343,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a node script with a result value of type <paramref name="T" />
|
/// Represents a node script with a result value of type <typeparamref name="T" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of result value</typeparam>
|
/// <typeparam name="T">The type of result value</typeparam>
|
||||||
public class NodeScript<T> : NodeScript, INodeScript<T>
|
public class NodeScript<T> : NodeScript, INodeScript<T>
|
||||||
@ -341,7 +351,7 @@ namespace Artemis.Core
|
|||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public T Result => ((ExitNode<T>) ExitNode).Value;
|
public T? Result => ((ExitNode<T>) ExitNode).Value;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool ExitNodeConnected => ((ExitNode<T>) ExitNode).Input.ConnectedTo.Any();
|
public override bool ExitNodeConnected => ((ExitNode<T>) ExitNode).Input.ConnectedTo.Any();
|
||||||
@ -362,6 +372,7 @@ namespace Artemis.Core
|
|||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public NodeScript(string name, string description, object? context = null)
|
public NodeScript(string name, string description, object? context = null)
|
||||||
: base(name, description, context)
|
: base(name, description, context)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,55 +3,39 @@ using Newtonsoft.Json;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an output pin containing a value of type <typeparamref name="T" /> on a <see cref="INode" />
|
||||||
|
/// </summary>
|
||||||
public sealed class OutputPin<T> : Pin
|
public sealed class OutputPin<T> : Pin
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
|
||||||
|
|
||||||
public override Type Type { get; } = typeof(T);
|
|
||||||
public override object PinValue => Value;
|
|
||||||
public override PinDirection Direction => PinDirection.Output;
|
|
||||||
|
|
||||||
private T _value;
|
|
||||||
public T Value
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!IsEvaluated)
|
|
||||||
Node?.Evaluate();
|
|
||||||
|
|
||||||
return _value;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_value = value;
|
|
||||||
IsEvaluated = true;
|
|
||||||
|
|
||||||
OnPropertyChanged(nameof(PinValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
internal OutputPin(INode node, string name)
|
internal OutputPin(INode node, string name)
|
||||||
: base(node, name)
|
: base(node, name)
|
||||||
{ }
|
{
|
||||||
|
_value = default;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class OutputPin : Pin
|
|
||||||
{
|
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
public override Type Type { get; }
|
/// <inheritdoc />
|
||||||
public override object PinValue => Value;
|
public override Type Type { get; } = typeof(T);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override object? PinValue => Value;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override PinDirection Direction => PinDirection.Output;
|
public override PinDirection Direction => PinDirection.Output;
|
||||||
|
|
||||||
private object _value;
|
private T? _value;
|
||||||
public object Value
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the value of the output pin
|
||||||
|
/// </summary>
|
||||||
|
public T? Value
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -62,8 +46,72 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (!Type.IsInstanceOfType(value)) throw new ArgumentException($"Value of type '{value?.GetType().Name ?? "null"}' can't be assigned to a pin of type {Type.Name}.");
|
_value = value;
|
||||||
|
IsEvaluated = true;
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(PinValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an output pin on a <see cref="INode" />
|
||||||
|
/// </summary>
|
||||||
|
public sealed class OutputPin : Pin
|
||||||
|
{
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
internal OutputPin(INode node, Type type, string name)
|
||||||
|
: base(node, name)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
_value = type.GetDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override Type Type { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override object? PinValue => Value;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override PinDirection Direction => PinDirection.Output;
|
||||||
|
|
||||||
|
private object? _value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the value of the output pin
|
||||||
|
/// </summary>
|
||||||
|
public object? Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!IsEvaluated)
|
||||||
|
Node?.Evaluate();
|
||||||
|
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Type.IsValueType && value == null)
|
||||||
|
{
|
||||||
|
// We can't take null for value types so set it to the default value for that type
|
||||||
|
_value = Type.GetDefault();
|
||||||
|
}
|
||||||
|
else if (value != null)
|
||||||
|
{
|
||||||
|
// If a value was given make sure it matches
|
||||||
|
if (!Type.IsInstanceOfType(value))
|
||||||
|
throw new ArgumentException($"Value of type '{value.GetType().Name}' can't be assigned to a pin of type {Type.Name}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise we're good and we can put a null here if it happens to be that
|
||||||
_value = value;
|
_value = value;
|
||||||
IsEvaluated = true;
|
IsEvaluated = true;
|
||||||
OnPropertyChanged(nameof(PinValue));
|
OnPropertyChanged(nameof(PinValue));
|
||||||
@ -71,15 +119,5 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
internal OutputPin(INode node, Type type, string name)
|
|
||||||
: base(node, name)
|
|
||||||
{
|
|
||||||
this.Type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,11 +2,17 @@
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a collection of output pins containing values of type <typeparamref name="T" />
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of value the pins in this collection hold</typeparam>
|
||||||
public sealed class OutputPinCollection<T> : PinCollection
|
public sealed class OutputPinCollection<T> : PinCollection
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override PinDirection Direction => PinDirection.Output;
|
public override PinDirection Direction => PinDirection.Output;
|
||||||
|
/// <inheritdoc />
|
||||||
public override Type Type => typeof(T);
|
public override Type Type => typeof(T);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -21,6 +27,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override IPin CreatePin() => new OutputPin<T>(Node, string.Empty);
|
protected override IPin CreatePin() => new OutputPin<T>(Node, string.Empty);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -5,12 +5,35 @@ using Artemis.Core.Events;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc cref="IPin" />
|
||||||
public abstract class Pin : CorePropertyChanged, IPin
|
public abstract class Pin : CorePropertyChanged, IPin
|
||||||
{
|
{
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="Pin" /> class on the provided node with the provided name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">The node the pin belongs to</param>
|
||||||
|
/// <param name="name">The name of the pin</param>
|
||||||
|
protected Pin(INode node, string name = "")
|
||||||
|
{
|
||||||
|
Node = node;
|
||||||
|
_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event EventHandler<SingleValueEventArgs<IPin>>? PinConnected;
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event EventHandler<SingleValueEventArgs<IPin>>? PinDisconnected;
|
||||||
|
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public INode Node { get; }
|
public INode Node { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get => _name;
|
get => _name;
|
||||||
@ -19,6 +42,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private bool _isEvaluated;
|
private bool _isEvaluated;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool IsEvaluated
|
public bool IsEvaluated
|
||||||
{
|
{
|
||||||
get => _isEvaluated;
|
get => _isEvaluated;
|
||||||
@ -27,36 +51,30 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private readonly List<IPin> _connectedTo = new();
|
private readonly List<IPin> _connectedTo = new();
|
||||||
private string _name;
|
private string _name;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public IReadOnlyList<IPin> ConnectedTo => new ReadOnlyCollection<IPin>(_connectedTo);
|
public IReadOnlyList<IPin> ConnectedTo => new ReadOnlyCollection<IPin>(_connectedTo);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public abstract PinDirection Direction { get; }
|
public abstract PinDirection Direction { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public abstract Type Type { get; }
|
public abstract Type Type { get; }
|
||||||
public abstract object PinValue { get; }
|
|
||||||
|
|
||||||
#endregion
|
/// <inheritdoc />
|
||||||
|
public abstract object? PinValue { get; }
|
||||||
#region Events
|
|
||||||
|
|
||||||
public event EventHandler<SingleValueEventArgs<IPin>> PinConnected;
|
|
||||||
public event EventHandler<SingleValueEventArgs<IPin>> PinDisconnected;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
protected Pin(INode node, string name = "")
|
|
||||||
{
|
|
||||||
this.Node = node;
|
|
||||||
this.Name = name;
|
|
||||||
|
|
||||||
if (Node != null)
|
|
||||||
Node.Resetting += OnNodeResetting;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
IsEvaluated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void ConnectTo(IPin pin)
|
public void ConnectTo(IPin pin)
|
||||||
{
|
{
|
||||||
_connectedTo.Add(pin);
|
_connectedTo.Add(pin);
|
||||||
@ -65,6 +83,7 @@ namespace Artemis.Core
|
|||||||
PinConnected?.Invoke(this, new SingleValueEventArgs<IPin>(pin));
|
PinConnected?.Invoke(this, new SingleValueEventArgs<IPin>(pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void DisconnectFrom(IPin pin)
|
public void DisconnectFrom(IPin pin)
|
||||||
{
|
{
|
||||||
_connectedTo.Remove(pin);
|
_connectedTo.Remove(pin);
|
||||||
@ -73,6 +92,7 @@ namespace Artemis.Core
|
|||||||
PinDisconnected?.Invoke(this, new SingleValueEventArgs<IPin>(pin));
|
PinDisconnected?.Invoke(this, new SingleValueEventArgs<IPin>(pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public void DisconnectAll()
|
public void DisconnectAll()
|
||||||
{
|
{
|
||||||
List<IPin> connectedPins = new(_connectedTo);
|
List<IPin> connectedPins = new(_connectedTo);
|
||||||
@ -84,11 +104,6 @@ namespace Artemis.Core
|
|||||||
PinDisconnected?.Invoke(this, new SingleValueEventArgs<IPin>(pin));
|
PinDisconnected?.Invoke(this, new SingleValueEventArgs<IPin>(pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnNodeResetting(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
IsEvaluated = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,34 +6,22 @@ using Artemis.Core.Events;
|
|||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc cref="IPinCollection"/>
|
||||||
public abstract class PinCollection : IPinCollection
|
public abstract class PinCollection : IPinCollection
|
||||||
{
|
{
|
||||||
#region Properties & Fields
|
|
||||||
|
|
||||||
public INode Node { get; }
|
|
||||||
public string Name { get; }
|
|
||||||
|
|
||||||
public abstract PinDirection Direction { get; }
|
|
||||||
public abstract Type Type { get; }
|
|
||||||
|
|
||||||
private readonly ObservableCollection<IPin> _pins = new();
|
|
||||||
public ReadOnlyObservableCollection<IPin> Pins => new(_pins);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Events
|
|
||||||
|
|
||||||
public event EventHandler<SingleValueEventArgs<IPin>> PinAdded;
|
|
||||||
public event EventHandler<SingleValueEventArgs<IPin>> PinRemoved;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="PinCollection" /> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="node">The node the pin collection belongs to</param>
|
||||||
|
/// <param name="name">The name of the pin collection</param>
|
||||||
|
/// <param name="initialCount">The amount of pins to initially add to the collection</param>
|
||||||
|
/// <returns>The resulting output pin collection</returns>
|
||||||
protected PinCollection(INode node, string name, int initialCount)
|
protected PinCollection(INode node, string name, int initialCount)
|
||||||
{
|
{
|
||||||
this.Node = node;
|
Node = node ?? throw new ArgumentNullException(nameof(node));
|
||||||
this.Name = name;
|
Name = name;
|
||||||
|
|
||||||
for (int i = 0; i < initialCount; i++)
|
for (int i = 0; i < initialCount; i++)
|
||||||
AddPin();
|
AddPin();
|
||||||
@ -41,9 +29,38 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event EventHandler<SingleValueEventArgs<IPin>>? PinAdded;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public event EventHandler<SingleValueEventArgs<IPin>>? PinRemoved;
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public INode Node { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract PinDirection Direction { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public abstract Type Type { get; }
|
||||||
|
|
||||||
|
private readonly ObservableCollection<IPin> _pins = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a read only observable collection of the pins
|
||||||
|
/// </summary>
|
||||||
|
public ReadOnlyObservableCollection<IPin> Pins => new(_pins);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public IPin AddPin()
|
public IPin AddPin()
|
||||||
{
|
{
|
||||||
IPin pin = CreatePin();
|
IPin pin = CreatePin();
|
||||||
@ -54,6 +71,7 @@ namespace Artemis.Core
|
|||||||
return pin;
|
return pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public bool Remove(IPin pin)
|
public bool Remove(IPin pin)
|
||||||
{
|
{
|
||||||
bool removed = _pins.Remove(pin);
|
bool removed = _pins.Remove(pin);
|
||||||
@ -64,11 +82,30 @@ namespace Artemis.Core
|
|||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
foreach (IPin pin in _pins)
|
||||||
|
pin.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new pin to be used in this collection
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The resulting pin</returns>
|
||||||
protected abstract IPin CreatePin();
|
protected abstract IPin CreatePin();
|
||||||
|
|
||||||
public IEnumerator<IPin> GetEnumerator() => Pins.GetEnumerator();
|
/// <inheritdoc />
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
public IEnumerator<IPin> GetEnumerator()
|
||||||
|
{
|
||||||
|
return Pins.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,8 +1,18 @@
|
|||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a direction in which pin data flows
|
||||||
|
/// </summary>
|
||||||
public enum PinDirection
|
public enum PinDirection
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An input direction
|
||||||
|
/// </summary>
|
||||||
Input,
|
Input,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An output direction
|
||||||
|
/// </summary>
|
||||||
Output
|
Output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DataBindingOnDataBindingToggled(object? sender, DataBindingEventArgs e)
|
private void DataBindingOnDataBindingToggled(object sender, DataBindingEventArgs e)
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(DataBindingEnabled));
|
OnPropertyChanged(nameof(DataBindingEnabled));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,8 +22,7 @@ namespace Artemis.UI.Stylet
|
|||||||
{
|
{
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
ScreenExtensions.TryDispose(_rootViewModel);
|
ScreenExtensions.TryDispose(_rootViewModel);
|
||||||
if (Kernel != null)
|
Kernel?.Dispose();
|
||||||
Kernel.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ConfigureBootstrapper()
|
protected override void ConfigureBootstrapper()
|
||||||
|
|||||||
@ -277,7 +277,7 @@ namespace Artemis.VisualScripting.Editor.Controls
|
|||||||
FitScript();
|
FitScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnVisualScriptNodeCollectionChanged(object? sender, EventArgs e)
|
private void OnVisualScriptNodeCollectionChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (AutoFitScript)
|
if (AutoFitScript)
|
||||||
FitScript();
|
FitScript();
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="Button">
|
<ControlTemplate TargetType="Button">
|
||||||
<Border Padding="{TemplateBinding Padding}"
|
<Border Padding="{TemplateBinding Padding}"
|
||||||
Background="{TemplateBinding Background}"
|
Background="{TemplateBinding Background}"
|
||||||
BorderThickness="{TemplateBinding BorderThickness}"
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
BorderBrush="{TemplateBinding BorderBrush}">
|
BorderBrush="{TemplateBinding BorderBrush}">
|
||||||
@ -103,19 +103,18 @@
|
|||||||
<Setter Property="ItemTemplate">
|
<Setter Property="ItemTemplate">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<DataTemplate DataType="{x:Type wrapper:VisualScriptPinCollection}">
|
<DataTemplate DataType="{x:Type wrapper:VisualScriptPinCollection}">
|
||||||
<StackPanel Margin="0,4" Orientation="Vertical">
|
<StackPanel Margin="0,2" Orientation="Vertical">
|
||||||
<TextBlock Text="{Binding PinCollection.Name}" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type controls:VisualScriptNodePresenter}}}" />
|
<TextBlock Text="{Binding PinCollection.Name}" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type controls:VisualScriptNodePresenter}}}" />
|
||||||
<ItemsControl Margin="0,4"
|
<ItemsControl Margin="0,5"
|
||||||
Style="{StaticResource StylePinListInput}"
|
Style="{StaticResource StylePinListInput}"
|
||||||
ItemsSource="{Binding Pins}">
|
ItemsSource="{Binding Pins}">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate DataType="{x:Type core:Pin}">
|
<DataTemplate DataType="{x:Type core:Pin}">
|
||||||
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
|
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal" Margin="0 8 0 0">
|
||||||
<controls:VisualScriptPinPresenter Margin="0,5,-3,3"
|
<controls:VisualScriptPinPresenter Pin="{Binding .}" Margin="0 0 2 0" />
|
||||||
Pin="{Binding .}" />
|
|
||||||
<Button Style="{StaticResource StyleButtonPinsModify}"
|
<Button Style="{StaticResource StyleButtonPinsModify}"
|
||||||
Command="{Binding DataContext.RemovePinCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
|
Command="{Binding DataContext.RemovePinCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
|
||||||
CommandParameter="{Binding .}"/>
|
CommandParameter="{Binding .}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
@ -139,14 +138,14 @@
|
|||||||
<StackPanel Margin="0,4" Orientation="Vertical">
|
<StackPanel Margin="0,4" Orientation="Vertical">
|
||||||
<TextBlock Text="{Binding PinCollection.Name}" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type controls:VisualScriptNodePresenter}}}" />
|
<TextBlock Text="{Binding PinCollection.Name}" Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type controls:VisualScriptNodePresenter}}}" />
|
||||||
<ItemsControl Margin="0,4"
|
<ItemsControl Margin="0,4"
|
||||||
Style="{StaticResource StylePinListOutput}"
|
Style="{StaticResource StylePinListOutput}"
|
||||||
ItemsSource="{Binding Pins}">
|
ItemsSource="{Binding Pins}">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate DataType="{x:Type core:Pin}">
|
<DataTemplate DataType="{x:Type core:Pin}">
|
||||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||||
<Button Style="{StaticResource StyleButtonPinsModify}"
|
<Button Style="{StaticResource StyleButtonPinsModify}"
|
||||||
Command="{Binding DataContext.RemovePinCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
|
Command="{Binding DataContext.RemovePinCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
|
||||||
CommandParameter="{Binding .}"/>
|
CommandParameter="{Binding .}" />
|
||||||
<controls:VisualScriptPinPresenter Margin="-3,5,0,3"
|
<controls:VisualScriptPinPresenter Margin="-3,5,0,3"
|
||||||
Pin="{Binding .}" />
|
Pin="{Binding .}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@ -182,9 +181,9 @@
|
|||||||
<!-- Placeholder -->
|
<!-- Placeholder -->
|
||||||
</Border>
|
</Border>
|
||||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center"
|
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||||
FontFamily="{TemplateBinding FontFamily}"
|
FontFamily="{TemplateBinding FontFamily}"
|
||||||
FontSize="14" FontWeight="Bold"
|
FontSize="14" FontWeight="Bold"
|
||||||
Text="{Binding Node.Node.Name, RelativeSource={RelativeSource TemplatedParent}}"/>
|
Text="{Binding Node.Node.Name, RelativeSource={RelativeSource TemplatedParent}}" />
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
@ -199,24 +198,24 @@
|
|||||||
|
|
||||||
<Border x:Name="BrdInputPins" Grid.Column="0">
|
<Border x:Name="BrdInputPins" Grid.Column="0">
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<ItemsControl Style="{StaticResource StylePinListInput}"
|
<ItemsControl Style="{StaticResource StylePinListInput}"
|
||||||
ItemsSource="{Binding Node.InputPins, RelativeSource={RelativeSource TemplatedParent}}" />
|
ItemsSource="{Binding Node.InputPins, RelativeSource={RelativeSource TemplatedParent}}" />
|
||||||
|
|
||||||
<ItemsControl Style="{StaticResource StylePinCollectionListInput}"
|
<ItemsControl Style="{StaticResource StylePinCollectionListInput}"
|
||||||
ItemsSource="{Binding Node.InputPinCollections, RelativeSource={RelativeSource TemplatedParent}}" />
|
ItemsSource="{Binding Node.InputPinCollections, RelativeSource={RelativeSource TemplatedParent}}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border x:Name="BrdCustomView" Grid.Column="1">
|
<Border x:Name="BrdCustomView" Grid.Column="1">
|
||||||
<ContentControl s:View.Model="{TemplateBinding CustomViewModel}"/>
|
<ContentControl s:View.Model="{TemplateBinding CustomViewModel}" />
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border x:Name="BrdOutputPins" Grid.Column="2">
|
<Border x:Name="BrdOutputPins" Grid.Column="2">
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<ItemsControl Style="{StaticResource StylePinListOutput}"
|
<ItemsControl Style="{StaticResource StylePinListOutput}"
|
||||||
ItemsSource="{Binding Node.OutputPins, RelativeSource={RelativeSource TemplatedParent}}" />
|
ItemsSource="{Binding Node.OutputPins, RelativeSource={RelativeSource TemplatedParent}}" />
|
||||||
|
|
||||||
<ItemsControl Style="{StaticResource StylePinCollectionListOutput}"
|
<ItemsControl Style="{StaticResource StylePinCollectionListOutput}"
|
||||||
ItemsSource="{Binding Node.OutputPinCollections, RelativeSource={RelativeSource TemplatedParent}}" />
|
ItemsSource="{Binding Node.OutputPinCollections, RelativeSource={RelativeSource TemplatedParent}}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
@ -226,12 +225,12 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
|
|
||||||
<Style x:Key="StyleVisualScriptNodePresenter"
|
<Style x:Key="StyleVisualScriptNodePresenter"
|
||||||
TargetType="{x:Type controls:VisualScriptNodePresenter}">
|
TargetType="{x:Type controls:VisualScriptNodePresenter}">
|
||||||
|
|
||||||
<Setter Property="Padding" Value="8,10" />
|
<Setter Property="Padding" Value="8,10" />
|
||||||
|
|
||||||
<Setter Property="Foreground" Value="#FFFFFFFF"/>
|
<Setter Property="Foreground" Value="#FFFFFFFF" />
|
||||||
|
|
||||||
<Setter Property="Background" Value="#80101010" />
|
<Setter Property="Background" Value="#80101010" />
|
||||||
<Setter Property="TitleBrush" Value="#FF444444" />
|
<Setter Property="TitleBrush" Value="#FF444444" />
|
||||||
|
|||||||
@ -110,7 +110,7 @@ namespace Artemis.VisualScripting.Nodes
|
|||||||
CreateOutputPin(dataBindingRegistration.ValueType, dataBindingRegistration.DisplayName);
|
CreateOutputPin(dataBindingRegistration.ValueType, dataBindingRegistration.DisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileOnChildRemoved(object? sender, EventArgs e)
|
private void ProfileOnChildRemoved(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (Script.Context is not Profile profile)
|
if (Script.Context is not Profile profile)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -8,7 +8,7 @@ using NoStringEvaluating.Models.Values;
|
|||||||
|
|
||||||
namespace Artemis.VisualScripting.Nodes.Maths
|
namespace Artemis.VisualScripting.Nodes.Maths
|
||||||
{
|
{
|
||||||
[Node("Math Expression", "Outputs the result of a math expression.", "Math", OutputType = typeof(int))]
|
[Node("Math Expression", "Outputs the result of a math expression.", "Math", InputType = typeof(float), OutputType = typeof(float))]
|
||||||
public class MathExpressionNode : Node<string, MathExpressionNodeCustomViewModel>
|
public class MathExpressionNode : Node<string, MathExpressionNodeCustomViewModel>
|
||||||
{
|
{
|
||||||
private readonly INoStringEvaluator _evaluator;
|
private readonly INoStringEvaluator _evaluator;
|
||||||
@ -42,6 +42,7 @@ namespace Artemis.VisualScripting.Nodes.Maths
|
|||||||
|
|
||||||
public override void Evaluate()
|
public override void Evaluate()
|
||||||
{
|
{
|
||||||
|
var test = _evaluator.ToString();
|
||||||
if (Storage != null)
|
if (Storage != null)
|
||||||
Output.Value = (float) _evaluator.CalcNumber(Storage, _variables);
|
Output.Value = (float) _evaluator.CalcNumber(Storage, _variables);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user