using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Ninject;
using Ninject.Parameters;
namespace Artemis.Core
{
///
/// Represents a kind of node inside a
///
public abstract class Node : CorePropertyChanged, INode
{
///
public event EventHandler? Resetting;
#region Properties & Fields
private string _name;
///
public string Name
{
get => _name;
protected set => SetAndNotify(ref _name, value);
}
private string _description;
///
public string Description
{
get => _description;
protected set => SetAndNotify(ref _description, value);
}
private double _x;
///
public double X
{
get => _x;
set => SetAndNotify(ref _x, value);
}
private double _y;
///
public double Y
{
get => _y;
set => SetAndNotify(ref _y, value);
}
///
public virtual bool IsExitNode => false;
///
public virtual bool IsDefaultNode => false;
private readonly List _pins = new();
///
public IReadOnlyCollection Pins => new ReadOnlyCollection(_pins);
private readonly List _pinCollections = new();
///
public IReadOnlyCollection PinCollections => new ReadOnlyCollection(_pinCollections);
#endregion
#region Construtors
///
/// Creates a new instance of the class with an empty name and description
///
protected Node()
{
_name = string.Empty;
_description = string.Empty;
}
///
/// Creates a new instance of the class with the provided name and description
///
protected Node(string name, string description)
{
_name = name;
_description = description;
}
#endregion
#region Methods
///
/// Creates a new input pin and adds it to the collection
///
/// The name of the pin
/// The type of value the pin will hold
/// The newly created pin
protected InputPin CreateInputPin(string name = "")
{
InputPin pin = new(this, name);
_pins.Add(pin);
OnPropertyChanged(nameof(Pins));
return pin;
}
///
/// Creates a new input pin and adds it to the collection
///
/// The type of value the pin will hold
/// The name of the pin
/// The newly created pin
protected InputPin CreateInputPin(Type type, string name = "")
{
InputPin pin = new(this, type, name);
_pins.Add(pin);
OnPropertyChanged(nameof(Pins));
return pin;
}
///
/// Creates a new output pin and adds it to the collection
///
/// The name of the pin
/// The type of value the pin will hold
/// The newly created pin
protected OutputPin CreateOutputPin(string name = "")
{
OutputPin pin = new(this, name);
_pins.Add(pin);
OnPropertyChanged(nameof(Pins));
return pin;
}
///
/// Creates a new output pin and adds it to the collection
///
/// The type of value the pin will hold
/// The name of the pin
/// The newly created pin
protected OutputPin CreateOutputPin(Type type, string name = "")
{
OutputPin pin = new(this, type, name);
_pins.Add(pin);
OnPropertyChanged(nameof(Pins));
return pin;
}
///
/// Removes the provided from the node and it's collection
///
/// The pin to remove
/// if the pin was removed; otherwise .
protected bool RemovePin(Pin pin)
{
bool isRemoved = _pins.Remove(pin);
if (isRemoved)
{
pin.DisconnectAll();
OnPropertyChanged(nameof(Pins));
}
return isRemoved;
}
///
/// Creates a new input pin collection and adds it to the collection
///
/// The type of value the pins of this collection will hold
/// The name of the pin collection
/// The amount of pins to initially add to the collection
/// The resulting input pin collection
protected InputPinCollection CreateInputPinCollection(string name = "", int initialCount = 1)
{
InputPinCollection pin = new(this, name, initialCount);
_pinCollections.Add(pin);
OnPropertyChanged(nameof(PinCollections));
return pin;
}
///
/// Creates a new input pin collection and adds it to the collection
///
/// The type of value the pins of this collection will hold
/// The name of the pin collection
/// The amount of pins to initially add to the collection
/// The resulting input pin collection
protected InputPinCollection CreateInputPinCollection(Type type, string name = "", int initialCount = 1)
{
InputPinCollection pin = new(this, type, name, initialCount);
_pinCollections.Add(pin);
OnPropertyChanged(nameof(PinCollections));
return pin;
}
///
/// Creates a new output pin collection and adds it to the collection
///
/// The type of value the pins of this collection will hold
/// The name of the pin collection
/// The amount of pins to initially add to the collection
/// The resulting output pin collection
protected OutputPinCollection CreateOutputPinCollection(string name = "", int initialCount = 1)
{
OutputPinCollection pin = new(this, name, initialCount);
_pinCollections.Add(pin);
OnPropertyChanged(nameof(PinCollections));
return pin;
}
///
/// Removes the provided from the node and it's
/// collection
///
/// The pin collection to remove
/// if the pin collection was removed; otherwise .
protected bool RemovePinCollection(PinCollection pinCollection)
{
bool isRemoved = _pinCollections.Remove(pinCollection);
if (isRemoved)
{
foreach (IPin pin in pinCollection)
pin.DisconnectAll();
OnPropertyChanged(nameof(PinCollections));
}
return isRemoved;
}
///
public virtual void Initialize(INodeScript script)
{
}
///
public abstract void Evaluate();
///
public virtual void Reset()
{
Resetting?.Invoke(this, EventArgs.Empty);
}
///
/// Called whenever the node must show it's custom view model, if , no custom view model is used
///
/// The custom view model, if , no custom view model is used
public virtual ICustomNodeViewModel? GetCustomViewModel()
{
return null;
}
///
/// Serializes the object into a string
///
/// The serialized object
internal virtual string SerializeStorage()
{
return string.Empty;
}
///
/// Deserializes the object and sets it
///
/// The serialized object
internal virtual void DeserializeStorage(string serialized)
{
}
#endregion
}
///
/// Represents a kind of node inside a containing storage value of type
/// .
///
/// The type of value the node stores
public abstract class Node : Node
{
private TStorage? _storage;
///
protected Node()
{
}
///
protected Node(string name, string description) : base(name, description)
{
}
///
/// Gets or sets the storage object of this node, this is saved across sessions
///
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(serialized) ?? default(TStorage);
}
}
///
/// Represents a kind of node inside a containing storage value of type
/// and a view model of type .
///
/// The type of value the node stores
/// The type of view model the node uses
public abstract class Node : Node where TViewModel : ICustomNodeViewModel
{
///
protected Node()
{
}
///
protected Node(string name, string description) : base(name, description)
{
}
[Inject]
internal IKernel Kernel { get; set; } = null!;
///
/// Called when a view model is required
///
public virtual TViewModel GetViewModel()
{
return Kernel.Get(new ConstructorArgument("node", this));
}
///
public override ICustomNodeViewModel GetCustomViewModel()
{
return GetViewModel();
}
}
}