mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Nodes - Changed storage to be based on generics
Nodes - Added XML docs to most types
This commit is contained in:
1 parent
8413b8d6db
commit
c1dab91c16
28 files changed
+522
-347
No files matched your search
@@ -76,7 +76,8 @@ namespace Artemis.Core.Services
|
||||
node.Y = entity.Y;
|
||||
try
|
||||
{
|
||||
node.Storage = CoreJson.DeserializeObject(entity.Storage, true);
|
||||
if (node is Node nodeImplementation)
|
||||
nodeImplementation.DeserializeStorage(entity.Storage);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Artemis.Core
|
||||
public override PinDirection Direction => PinDirection.Input;
|
||||
|
||||
private T _value;
|
||||
|
||||
public T Value
|
||||
{
|
||||
get
|
||||
@@ -37,7 +38,8 @@ namespace Artemis.Core
|
||||
[JsonConstructor]
|
||||
internal InputPin(INode node, string name)
|
||||
: base(node, name)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -62,6 +64,7 @@ namespace Artemis.Core
|
||||
public override PinDirection Direction => PinDirection.Input;
|
||||
|
||||
private object _value;
|
||||
|
||||
public object Value
|
||||
{
|
||||
get
|
||||
@@ -98,9 +101,19 @@ namespace Artemis.Core
|
||||
|
||||
private void Evaluate()
|
||||
{
|
||||
Value = ConnectedTo.Count > 0 ? ConnectedTo[0].PinValue : Type.GetDefault();
|
||||
if (Type.IsValueType)
|
||||
{
|
||||
if (ConnectedTo.Count > 0 && ConnectedTo[0].PinValue != null)
|
||||
Value = ConnectedTo[0].PinValue;
|
||||
else
|
||||
Value = Type.GetDefault()!;
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = ConnectedTo[0].PinValue;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using Artemis.Storage.Entities.Profile.Nodes;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a kind of node inside a <see cref="INodeScript" />
|
||||
/// </summary>
|
||||
public interface INode : INotifyPropertyChanged
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the node
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description of the node
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the node is the exit node of the script
|
||||
/// </summary>
|
||||
bool IsExitNode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the node is a default node that connot be removed
|
||||
/// </summary>
|
||||
bool IsDefaultNode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the X-position of the node
|
||||
/// </summary>
|
||||
public double X { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y-position of the node
|
||||
/// </summary>
|
||||
public double Y { get; set; }
|
||||
public object? Storage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a read-only collection of the pins on this node
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<IPin> Pins { get; }
|
||||
public IReadOnlyCollection<IPinCollection> PinCollections { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a read-only collection of the pin collections on this node
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<IPinCollection> PinCollections { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the node resets
|
||||
/// </summary>
|
||||
event EventHandler Resetting;
|
||||
|
||||
/// <summary>
|
||||
/// Called when the node was loaded from storage or newly created
|
||||
/// </summary>
|
||||
/// <param name="script">The script the node is contained in</param>
|
||||
void Initialize(INodeScript script);
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the value of the output pins of this node
|
||||
/// </summary>
|
||||
void Evaluate();
|
||||
|
||||
/// <summary>
|
||||
/// Resets the node causing all pins to re-evaluate the next time <see cref="Evaluate"/> is called
|
||||
/// </summary>
|
||||
void Reset();
|
||||
}
|
||||
}
|
||||
@@ -5,27 +5,74 @@ using Artemis.Core.Events;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a node script
|
||||
/// </summary>
|
||||
public interface INodeScript : INotifyPropertyChanged, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the node script.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description of the node script.
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets an enumerable of all the nodes on this script.
|
||||
/// </summary>
|
||||
IEnumerable<INode> Nodes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the return type of the node script.
|
||||
/// </summary>
|
||||
Type ResultType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the context of the node script, usually a <see cref="Profile" /> or
|
||||
/// <see cref="ProfileConfiguration" />.
|
||||
/// </summary>
|
||||
object? Context { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Occurs whenever a node was added to the script
|
||||
/// </summary>
|
||||
event EventHandler<SingleValueEventArgs<INode>>? NodeAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs whenever a node was removed from the script
|
||||
/// </summary>
|
||||
event EventHandler<SingleValueEventArgs<INode>>? NodeRemoved;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Runs the script, evaluating nodes where needed
|
||||
/// </summary>
|
||||
void Run();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a node to the script
|
||||
/// </summary>
|
||||
/// <param name="node">The node to add</param>
|
||||
void AddNode(INode node);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a node from the script
|
||||
/// </summary>
|
||||
/// <param name="node">The node to remove</param>
|
||||
void RemoveNode(INode node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a node script with a result value of type <paramref name="T" />
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of result value</typeparam>
|
||||
public interface INodeScript<out T> : INodeScript
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the result of the script
|
||||
/// </summary>
|
||||
T Result { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,24 @@
|
||||
using Ninject;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Ninject;
|
||||
using Ninject.Parameters;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a kind of node inside a <see cref="NodeScript" />
|
||||
/// </summary>
|
||||
public abstract class Node : CorePropertyChanged, INode
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public event EventHandler? Resetting;
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
private string _name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
@@ -18,6 +26,8 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
private string _description;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description
|
||||
{
|
||||
get => _description;
|
||||
@@ -26,6 +36,7 @@ namespace Artemis.Core
|
||||
|
||||
private double _x;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double X
|
||||
{
|
||||
get => _x;
|
||||
@@ -33,51 +44,62 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
private double _y;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double Y
|
||||
{
|
||||
get => _y;
|
||||
set => SetAndNotify(ref _y, value);
|
||||
}
|
||||
|
||||
private object? _storage;
|
||||
public object? Storage
|
||||
{
|
||||
get => _storage;
|
||||
set => SetAndNotify(ref _storage, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool IsExitNode => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool IsDefaultNode => false;
|
||||
|
||||
private readonly List<IPin> _pins = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<IPin> Pins => new ReadOnlyCollection<IPin>(_pins);
|
||||
|
||||
private readonly List<IPinCollection> _pinCollections = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyCollection<IPinCollection> PinCollections => new ReadOnlyCollection<IPinCollection>(_pinCollections);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler Resetting;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construtors
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="Node" /> class with an empty name and description
|
||||
/// </summary>
|
||||
protected Node()
|
||||
{ }
|
||||
{
|
||||
_name = string.Empty;
|
||||
_description = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="Node" /> class with the provided name and description
|
||||
/// </summary>
|
||||
protected Node(string name, string description)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
_name = name;
|
||||
_description = description;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new input pin and adds it to the <see cref="Pins" /> collection
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the pin</param>
|
||||
/// <typeparam name="T">The type of value the pin will hold</typeparam>
|
||||
/// <returns>The newly created pin</returns>
|
||||
protected InputPin<T> CreateInputPin<T>(string name = "")
|
||||
{
|
||||
InputPin<T> pin = new(this, name);
|
||||
@@ -86,6 +108,12 @@ namespace Artemis.Core
|
||||
return pin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new input pin and adds it to the <see cref="Pins" /> collection
|
||||
/// </summary>
|
||||
/// <param name="type">The type of value the pin will hold</param>
|
||||
/// <param name="name">The name of the pin</param>
|
||||
/// <returns>The newly created pin</returns>
|
||||
protected InputPin CreateInputPin(Type type, string name = "")
|
||||
{
|
||||
InputPin pin = new(this, type, name);
|
||||
@@ -94,6 +122,12 @@ namespace Artemis.Core
|
||||
return pin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new output pin and adds it to the <see cref="Pins" /> collection
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the pin</param>
|
||||
/// <typeparam name="T">The type of value the pin will hold</typeparam>
|
||||
/// <returns>The newly created pin</returns>
|
||||
protected OutputPin<T> CreateOutputPin<T>(string name = "")
|
||||
{
|
||||
OutputPin<T> pin = new(this, name);
|
||||
@@ -102,6 +136,12 @@ namespace Artemis.Core
|
||||
return pin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new output pin and adds it to the <see cref="Pins" /> collection
|
||||
/// </summary>
|
||||
/// <param name="type">The type of value the pin will hold</param>
|
||||
/// <param name="name">The name of the pin</param>
|
||||
/// <returns>The newly created pin</returns>
|
||||
protected OutputPin CreateOutputPin(Type type, string name = "")
|
||||
{
|
||||
OutputPin pin = new(this, type, name);
|
||||
@@ -109,7 +149,12 @@ namespace Artemis.Core
|
||||
OnPropertyChanged(nameof(Pins));
|
||||
return pin;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Removes the provided <paramref name="pin" /> from the node and it's <see cref="Pins" /> collection
|
||||
/// </summary>
|
||||
/// <param name="pin">The pin to remove</param>
|
||||
/// <returns><see langword="true" /> if the pin was removed; otherwise <see langword="false" />.</returns>
|
||||
protected bool RemovePin(Pin pin)
|
||||
{
|
||||
bool isRemoved = _pins.Remove(pin);
|
||||
@@ -122,6 +167,13 @@ namespace Artemis.Core
|
||||
return isRemoved;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new input pin collection and adds it to the <see cref="PinCollections" /> collection
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of value the pins of this collection will hold</typeparam>
|
||||
/// <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 input pin collection</returns>
|
||||
protected InputPinCollection<T> CreateInputPinCollection<T>(string name = "", int initialCount = 1)
|
||||
{
|
||||
InputPinCollection<T> pin = new(this, name, initialCount);
|
||||
@@ -130,6 +182,13 @@ namespace Artemis.Core
|
||||
return pin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new input pin collection and adds it to the <see cref="PinCollections" /> collection
|
||||
/// </summary>
|
||||
/// <param name="type">The type of value the pins of this collection will hold</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 input pin collection</returns>
|
||||
protected InputPinCollection CreateInputPinCollection(Type type, string name = "", int initialCount = 1)
|
||||
{
|
||||
InputPinCollection pin = new(this, type, name, initialCount);
|
||||
@@ -138,6 +197,13 @@ namespace Artemis.Core
|
||||
return pin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new output pin collection and adds it to the <see cref="PinCollections" /> collection
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of value the pins of this collection will hold</typeparam>
|
||||
/// <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 OutputPinCollection<T> CreateOutputPinCollection<T>(string name = "", int initialCount = 1)
|
||||
{
|
||||
OutputPinCollection<T> pin = new(this, name, initialCount);
|
||||
@@ -146,12 +212,18 @@ namespace Artemis.Core
|
||||
return pin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the provided <paramref name="pinCollection" /> from the node and it's <see cref="PinCollections" />
|
||||
/// collection
|
||||
/// </summary>
|
||||
/// <param name="pinCollection">The pin collection to remove</param>
|
||||
/// <returns><see langword="true" /> if the pin collection was removed; otherwise <see langword="false" />.</returns>
|
||||
protected bool RemovePinCollection(PinCollection pinCollection)
|
||||
{
|
||||
bool isRemoved = _pinCollections.Remove(pinCollection);
|
||||
if (isRemoved)
|
||||
{
|
||||
foreach (IPin pin in pinCollection)
|
||||
foreach (IPin pin in pinCollection)
|
||||
pin.DisconnectAll();
|
||||
OnPropertyChanged(nameof(PinCollections));
|
||||
}
|
||||
@@ -159,51 +231,122 @@ namespace Artemis.Core
|
||||
return isRemoved;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void Initialize(INodeScript script)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void Evaluate();
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void Reset()
|
||||
{
|
||||
Resetting?.Invoke(this, new EventArgs());
|
||||
Resetting?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called whenever the node must show it's custom view model, if <see langword="null" />, no custom view model is used
|
||||
/// </summary>
|
||||
/// <returns>The custom view model, if <see langword="null" />, no custom view model is used</returns>
|
||||
public virtual ICustomNodeViewModel? GetCustomViewModel()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the <see cref="Storage" /> object into a string
|
||||
/// </summary>
|
||||
/// <returns>The serialized object</returns>
|
||||
internal virtual string SerializeStorage()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the <see cref="Storage" /> object and sets it
|
||||
/// </summary>
|
||||
/// <param name="serialized">The serialized object</param>
|
||||
internal virtual void DeserializeStorage(string serialized)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public abstract class Node<T> : CustomViewModelNode where T : ICustomNodeViewModel
|
||||
/// <summary>
|
||||
/// Represents a kind of node inside a <see cref="NodeScript" /> containing storage value of type
|
||||
/// <typeparamref name="TStorage" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="TStorage">The type of value the node stores</typeparam>
|
||||
public abstract class Node<TStorage> : Node
|
||||
{
|
||||
private TStorage? _storage;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected Node()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected Node(string name, string description) : base(name, description)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the storage object of this node, this is saved across sessions
|
||||
/// </summary>
|
||||
public TStorage? Storage
|
||||
{
|
||||
get => _storage;
|
||||
set => SetAndNotify(ref _storage, value);
|
||||
}
|
||||
|
||||
internal override string SerializeStorage()
|
||||
{
|
||||
return CoreJson.SerializeObject(Storage, true);
|
||||
}
|
||||
|
||||
internal override void DeserializeStorage(string serialized)
|
||||
{
|
||||
Storage = CoreJson.DeserializeObject<TStorage>(serialized) ?? default(TStorage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a kind of node inside a <see cref="NodeScript" /> containing storage value of type
|
||||
/// <typeparamref name="TStorage" /> and a view model of type <typeparamref name="TViewModel" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="TStorage">The type of value the node stores</typeparam>
|
||||
/// <typeparam name="TViewModel">The type of view model the node uses</typeparam>
|
||||
public abstract class Node<TStorage, TViewModel> : Node<TStorage> where TViewModel : ICustomNodeViewModel
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected Node()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected Node(string name, string description) : base(name, description)
|
||||
{
|
||||
}
|
||||
|
||||
[Inject]
|
||||
internal IKernel Kernel { get; set; } = null!;
|
||||
|
||||
protected Node()
|
||||
{ }
|
||||
|
||||
protected Node(string name, string description) : base(name, description)
|
||||
{ }
|
||||
|
||||
public virtual T GetViewModel()
|
||||
/// <summary>
|
||||
/// Called when a view model is required
|
||||
/// </summary>
|
||||
public virtual TViewModel GetViewModel()
|
||||
{
|
||||
return Kernel.Get<T>(new ConstructorArgument("node", this));
|
||||
return Kernel.Get<TViewModel>(new ConstructorArgument("node", this));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ICustomNodeViewModel GetCustomViewModel()
|
||||
{
|
||||
return GetViewModel();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class CustomViewModelNode : Node
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected CustomViewModelNode()
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected CustomViewModelNode(string name, string description) : base(name, description)
|
||||
{ }
|
||||
|
||||
public abstract ICustomNodeViewModel GetCustomViewModel();
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,9 @@ using Artemis.Storage.Entities.Profile.Nodes;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a node script
|
||||
/// </summary>
|
||||
public abstract class NodeScript : CorePropertyChanged, INodeScript, IStorageModel
|
||||
{
|
||||
private void NodeTypeStoreOnNodeTypeChanged(object? sender, NodeTypeStoreEvent e)
|
||||
@@ -16,23 +19,41 @@ namespace Artemis.Core
|
||||
Load();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<SingleValueEventArgs<INode>>? NodeAdded;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<SingleValueEventArgs<INode>>? NodeRemoved;
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
internal NodeScriptEntity Entity { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description { get; }
|
||||
|
||||
private readonly List<INode> _nodes = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<INode> Nodes => new ReadOnlyCollection<INode>(_nodes);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exit node of the script
|
||||
/// </summary>
|
||||
protected INode ExitNode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the exit node is connected to any other nodes
|
||||
/// </summary>
|
||||
public abstract bool ExitNodeConnected { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract Type ResultType { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public object? Context { get; set; }
|
||||
|
||||
#endregion
|
||||
@@ -65,6 +86,7 @@ namespace Artemis.Core
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Run()
|
||||
{
|
||||
foreach (INode node in Nodes)
|
||||
@@ -73,6 +95,7 @@ namespace Artemis.Core
|
||||
ExitNode.Evaluate();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void AddNode(INode node)
|
||||
{
|
||||
_nodes.Add(node);
|
||||
@@ -80,6 +103,7 @@ namespace Artemis.Core
|
||||
NodeAdded?.Invoke(this, new SingleValueEventArgs<INode>(node));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RemoveNode(INode node)
|
||||
{
|
||||
_nodes.Remove(node);
|
||||
@@ -90,6 +114,7 @@ namespace Artemis.Core
|
||||
NodeRemoved?.Invoke(this, new SingleValueEventArgs<INode>(node));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
NodeTypeStore.NodeTypeAdded -= NodeTypeStoreOnNodeTypeChanged;
|
||||
@@ -147,9 +172,7 @@ namespace Artemis.Core
|
||||
// Restore pin collections
|
||||
foreach (NodePinCollectionEntity entityNodePinCollection in nodeEntity.PinCollections)
|
||||
{
|
||||
IPinCollection? collection = node.PinCollections.FirstOrDefault(c => c.Name == entityNodePinCollection.Name &&
|
||||
c.Type.Name == entityNodePinCollection.Type &&
|
||||
(int) c.Direction == entityNodePinCollection.Direction);
|
||||
IPinCollection? collection = node.PinCollections.ElementAtOrDefault(entityNodePinCollection.Id);
|
||||
if (collection == null)
|
||||
continue;
|
||||
|
||||
@@ -161,12 +184,12 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads missing connections between the nodes of this node script from the <see cref="Entity"/>
|
||||
/// Loads missing connections between the nodes of this node script from the <see cref="Entity" />
|
||||
/// </summary>
|
||||
public void LoadConnections()
|
||||
{
|
||||
List<INode> nodes = Nodes.ToList();
|
||||
foreach (NodeConnectionEntity nodeConnectionEntity in Entity.Connections)
|
||||
foreach (NodeConnectionEntity nodeConnectionEntity in Entity.Connections.OrderBy(p => p.SourcePinCollectionId))
|
||||
{
|
||||
INode? source = nodes.ElementAtOrDefault(nodeConnectionEntity.SourceNode);
|
||||
if (source == null)
|
||||
@@ -191,15 +214,12 @@ namespace Artemis.Core
|
||||
|
||||
// Clear existing connections on input pins, we don't want none of that now
|
||||
if (targetPin.Direction == PinDirection.Input)
|
||||
{
|
||||
while (targetPin.ConnectedTo.Any())
|
||||
targetPin.DisconnectFrom(targetPin.ConnectedTo[0]);
|
||||
}
|
||||
|
||||
if (sourcePin.Direction == PinDirection.Input)
|
||||
{
|
||||
while (sourcePin.ConnectedTo.Any())
|
||||
while (sourcePin.ConnectedTo.Any())
|
||||
sourcePin.DisconnectFrom(sourcePin.ConnectedTo[0]);
|
||||
}
|
||||
|
||||
// Only connect the nodes if they aren't already connected (LoadConnections may be called twice or more)
|
||||
if (!targetPin.ConnectedTo.Contains(sourcePin))
|
||||
@@ -231,21 +251,24 @@ namespace Artemis.Core
|
||||
Type = node.GetType().Name,
|
||||
X = node.X,
|
||||
Y = node.Y,
|
||||
Storage = CoreJson.SerializeObject(node.Storage, true),
|
||||
Name = node.Name,
|
||||
Description = node.Description,
|
||||
IsExitNode = node.IsExitNode
|
||||
};
|
||||
|
||||
if (node is Node nodeImplementation)
|
||||
nodeEntity.Storage = nodeImplementation.SerializeStorage();
|
||||
|
||||
int collectionId = 0;
|
||||
foreach (IPinCollection nodePinCollection in node.PinCollections)
|
||||
{
|
||||
nodeEntity.PinCollections.Add(new NodePinCollectionEntity
|
||||
{
|
||||
Name = nodePinCollection.Name,
|
||||
Type = nodePinCollection.Type.Name,
|
||||
Id = collectionId,
|
||||
Direction = (int) nodePinCollection.Direction,
|
||||
Amount = nodePinCollection.Count()
|
||||
});
|
||||
collectionId++;
|
||||
}
|
||||
|
||||
Entity.Nodes.Add(nodeEntity);
|
||||
@@ -309,13 +332,21 @@ namespace Artemis.Core
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a node script with a result value of type <paramref name="T" />
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of result value</typeparam>
|
||||
public class NodeScript<T> : NodeScript, INodeScript<T>
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <inheritdoc />
|
||||
public T Result => ((ExitNode<T>) ExitNode).Value;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool ExitNodeConnected => ((ExitNode<T>) ExitNode).Input.ConnectedTo.Any();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Type ResultType => typeof(T);
|
||||
|
||||
#endregion
|
||||
|
||||
Reference in new issue
Block a user