1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Added methods to remove pins at runtime

This commit is contained in:
Darth Affe 2021-07-15 17:38:35 +02:00
parent a45dd094a0
commit e3a0323383
5 changed files with 205 additions and 16 deletions

View File

@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using Artemis.Core.VisualScripting;
using Artemis.VisualScripting.Events;
using Artemis.VisualScripting.Internal;
@ -97,29 +100,109 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
this.Script = script;
this.Node = node;
Node.PropertyChanged += OnNodePropertyChanged;
_locationOffset = script.SurfaceSize / 2.0;
foreach (IPin pin in node.Pins)
{
if (pin.Direction == PinDirection.Input)
InputPins.Add(new VisualScriptPin(this, pin));
else
OutputPins.Add(new VisualScriptPin(this, pin));
}
foreach (IPinCollection pinCollection in node.PinCollections)
{
if (pinCollection.Direction == PinDirection.Input)
InputPinCollections.Add(new VisualScriptPinCollection(this, pinCollection));
else
OutputPinCollections.Add(new VisualScriptPinCollection(this, pinCollection));
}
ValidatePins();
}
#endregion
#region Methods
private void OnNodePropertyChanged(object sender, PropertyChangedEventArgs args)
{
if (string.Equals(args.PropertyName, nameof(Node.Pins), StringComparison.OrdinalIgnoreCase)
|| string.Equals(args.PropertyName, nameof(Node.PinCollections), StringComparison.OrdinalIgnoreCase))
ValidatePins();
}
private void ValidatePins()
{
if (Node == null)
{
InputPins.Clear();
OutputPins.Clear();
InputPinCollections.Clear();
OutputPinCollections.Clear();
return;
}
#region Remove Excessive
HashSet<IPin> pins = new(Node.Pins);
HashSet<IPinCollection> pinCollections = new(Node.PinCollections);
void ValidatePinList(ObservableCollection<VisualScriptPin> list)
{
List<VisualScriptPin> pinsToRemove = new();
foreach (VisualScriptPin pin in list)
if ((pin.Pin == null) || !pins.Contains(pin.Pin))
pinsToRemove.Add(pin);
foreach (VisualScriptPin pin in pinsToRemove)
{
pin.DisconnectAll();
list.Remove(pin);
}
}
void ValidatePinCollectionList(ObservableCollection<VisualScriptPinCollection> list)
{
List<VisualScriptPinCollection> pinCollectionsToRemove = new();
foreach (VisualScriptPinCollection pinCollection in list)
if ((pinCollection.PinCollection == null) || !pinCollections.Contains(pinCollection.PinCollection))
pinCollectionsToRemove.Add(pinCollection);
foreach (VisualScriptPinCollection pinCollection in pinCollectionsToRemove)
{
pinCollection.RemoveAll();
list.Remove(pinCollection);
}
}
ValidatePinList(InputPins);
ValidatePinList(OutputPins);
ValidatePinCollectionList(InputPinCollections);
ValidatePinCollectionList(OutputPinCollections);
#endregion
#region Add Missing
HashSet<IPin> existingPins = new(InputPins.Concat(OutputPins).Select(x => x.Pin));
HashSet<IPinCollection> existingPinCollections = new(InputPinCollections.Concat(OutputPinCollections).Select(x => x.PinCollection));
foreach (IPin pin in Node.Pins)
{
if (pin.Direction == PinDirection.Input)
{
if (!existingPins.Contains(pin))
InputPins.Add(new VisualScriptPin(this, pin));
}
else
{
if (!existingPins.Contains(pin))
OutputPins.Add(new VisualScriptPin(this, pin));
}
}
foreach (IPinCollection pinCollection in Node.PinCollections)
{
if (pinCollection.Direction == PinDirection.Input)
{
if (!existingPinCollections.Contains(pinCollection))
InputPinCollections.Add(new VisualScriptPinCollection(this, pinCollection));
}
else
{
if (!existingPinCollections.Contains(pinCollection))
OutputPinCollections.Add(new VisualScriptPinCollection(this, pinCollection));
}
}
#endregion
}
public void SnapNodeToGrid()
{
X -= X % Script.GridSize;

View File

@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Artemis.Core.VisualScripting;
using Artemis.VisualScripting.ViewModel;
@ -53,6 +54,13 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
Pins.Remove(pin);
}
public void RemoveAll()
{
List<VisualScriptPin> pins = new(Pins);
foreach (VisualScriptPin pin in pins)
RemovePin(pin);
}
#endregion
}
}

View File

@ -48,4 +48,54 @@ namespace Artemis.VisualScripting.Model
#endregion
}
public sealed class InputPin : Pin
{
#region Properties & Fields
public override Type Type { get; }
public override object PinValue => Value;
public override PinDirection Direction => PinDirection.Input;
private object _value;
public object Value
{
get
{
if (!IsEvaluated)
Evaluate();
return _value;
}
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;
IsEvaluated = true;
}
}
#endregion
#region Constructors
internal InputPin(INode node, Type type, string name)
: base(node, name)
{
this.Type = type;
}
#endregion
#region Methods
private void Evaluate()
{
Value = ConnectedTo.Count > 0 ? ConnectedTo[0].PinValue : default;
}
#endregion
}
}

View File

@ -38,4 +38,44 @@ namespace Artemis.VisualScripting.Model
#endregion
}
public sealed class OutputPin : Pin
{
#region Properties & Fields
public override Type Type { get; }
public override object PinValue => Value;
public override PinDirection Direction => PinDirection.Output;
private object _value;
public object Value
{
get
{
if (!IsEvaluated)
Node?.Evaluate();
return _value;
}
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;
}
}
#endregion
#region Constructors
internal OutputPin(INode node, Type type, string name)
: base(node, name)
{
this.Type = type;
}
#endregion
}
}

View File

@ -47,11 +47,19 @@ namespace Artemis.VisualScripting.Model
public void ConnectTo(IPin pin)
{
_connectedTo.Add(pin);
OnPropertyChanged(nameof(ConnectedTo));
}
public void DisconnectFrom(IPin pin)
{
_connectedTo.Remove(pin);
OnPropertyChanged(nameof(ConnectedTo));
}
public void DisconnectAll()
{
_connectedTo.Clear();
OnPropertyChanged(nameof(ConnectedTo));
}
private void OnNodeResetting(object sender, EventArgs e)