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(); } } }