mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
Nodes - Added node type registration system
Nodes - Moved models and node logic into core Nodes - Added node service that leverages DI
This commit is contained in:
1 parent
51541b4e6e
commit
7eadc58bee
57 files changed
+481
-259
No files matched your search
@@ -37,6 +37,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.1.0" />
|
||||
<PackageReference Include="Stylet" Version="1.3.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.VisualScripting.Attributes
|
||||
{
|
||||
public class UIAttribute : Attribute
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public string Name { get; }
|
||||
public string Description { get; set; }
|
||||
public string Category { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public UIAttribute(string name)
|
||||
{
|
||||
this.Name = name;
|
||||
}
|
||||
|
||||
public UIAttribute(string name, string description)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Description = description;
|
||||
}
|
||||
|
||||
public UIAttribute(string name, string description, string category)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Description = description;
|
||||
this.Category = category;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Editor.Controls
|
||||
{
|
||||
@@ -15,11 +14,11 @@ namespace Artemis.VisualScripting.Editor.Controls
|
||||
#region Dependency Properties
|
||||
|
||||
public static readonly DependencyProperty ScriptProperty = DependencyProperty.Register(
|
||||
"Script", typeof(IScript), typeof(VisualScriptEditor), new PropertyMetadata(default(IScript)));
|
||||
"Script", typeof(INodeScript), typeof(VisualScriptEditor), new PropertyMetadata(default(INodeScript)));
|
||||
|
||||
public IScript Script
|
||||
public INodeScript Script
|
||||
{
|
||||
get => (IScript)GetValue(ScriptProperty);
|
||||
get => (INodeScript)GetValue(ScriptProperty);
|
||||
set => SetValue(ScriptProperty, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Editor.Controls
|
||||
{
|
||||
|
||||
@@ -4,8 +4,8 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.Editor.Controls.Wrapper;
|
||||
using Artemis.VisualScripting.Model;
|
||||
|
||||
namespace Artemis.VisualScripting.Editor.Controls
|
||||
{
|
||||
|
||||
@@ -6,10 +6,10 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.Editor.Controls.Wrapper;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.VisualScripting.ViewModel;
|
||||
using VisualScript = Artemis.VisualScripting.Editor.Controls.Wrapper.VisualScript;
|
||||
|
||||
namespace Artemis.VisualScripting.Editor.Controls
|
||||
{
|
||||
@@ -58,11 +58,11 @@ namespace Artemis.VisualScripting.Editor.Controls
|
||||
#region Dependency Properties
|
||||
|
||||
public static readonly DependencyProperty ScriptProperty = DependencyProperty.Register(
|
||||
"Script", typeof(IScript), typeof(VisualScriptPresenter), new PropertyMetadata(default(IScript), ScriptChanged));
|
||||
"Script", typeof(INodeScript), typeof(VisualScriptPresenter), new PropertyMetadata(default(INodeScript), ScriptChanged));
|
||||
|
||||
public IScript Script
|
||||
public INodeScript Script
|
||||
{
|
||||
get => (IScript)GetValue(ScriptProperty);
|
||||
get => (INodeScript)GetValue(ScriptProperty);
|
||||
set => SetValue(ScriptProperty, value);
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ namespace Artemis.VisualScripting.Editor.Controls
|
||||
{
|
||||
if (d is not VisualScriptPresenter scriptPresenter) return;
|
||||
|
||||
scriptPresenter.ScriptChanged(args.NewValue is not Script script ? null : new VisualScript(script, scriptPresenter.SurfaceSize, scriptPresenter.GridSize));
|
||||
scriptPresenter.ScriptChanged(args.NewValue is not NodeScript script ? null : new VisualScript(script, scriptPresenter.SurfaceSize, scriptPresenter.GridSize));
|
||||
}
|
||||
|
||||
private void ScriptChanged(VisualScript newScript)
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.Events;
|
||||
using Artemis.VisualScripting.ViewModel;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
|
||||
private double _nodeDragAccumulationX;
|
||||
private double _nodeDragAccumulationY;
|
||||
|
||||
public IScript Script { get; }
|
||||
public INodeScript Script { get; }
|
||||
|
||||
public int SurfaceSize { get; }
|
||||
public int GridSize { get; }
|
||||
@@ -56,7 +56,7 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
|
||||
|
||||
#region Constructors
|
||||
|
||||
public VisualScript(IScript script, int surfaceSize, int gridSize)
|
||||
public VisualScript(INodeScript script, int surfaceSize, int gridSize)
|
||||
{
|
||||
this.Script = script;
|
||||
this.SurfaceSize = surfaceSize;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.ViewModel;
|
||||
|
||||
namespace Artemis.VisualScripting.Editor.Controls.Wrapper
|
||||
|
||||
@@ -3,10 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.Events;
|
||||
using Artemis.VisualScripting.Internal;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.VisualScripting.ViewModel;
|
||||
|
||||
namespace Artemis.VisualScripting.Editor.Controls.Wrapper
|
||||
@@ -255,7 +253,7 @@ namespace Artemis.VisualScripting.Editor.Controls.Wrapper
|
||||
Script.RemoveNode(this);
|
||||
}
|
||||
|
||||
private bool RemoveCanExecute() => Node is not IExitNode;
|
||||
private bool RemoveCanExecute() => !Node.IsExitNode;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.Events;
|
||||
using Artemis.VisualScripting.Internal;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.VisualScripting.ViewModel;
|
||||
|
||||
namespace Artemis.VisualScripting.Editor.Controls.Wrapper
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.ViewModel;
|
||||
|
||||
namespace Artemis.VisualScripting.Editor.Controls.Wrapper
|
||||
|
||||
@@ -6,8 +6,5 @@
|
||||
<ResourceDictionary Source="Styles/VisualScriptNodePresenter.xaml" />
|
||||
<ResourceDictionary Source="Styles/VisualScriptPinPresenter.xaml" />
|
||||
<ResourceDictionary Source="Styles/VisualScriptPresenter.xaml" />
|
||||
|
||||
<!-- TODO: Load external -->
|
||||
<ResourceDictionary Source="../Nodes/Styles/StaticValueNodes.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
@@ -1,10 +1,10 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls"
|
||||
xmlns:model="clr-namespace:Artemis.VisualScripting.Model">
|
||||
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core">
|
||||
|
||||
<DataTemplate x:Key="TemplateNodeItem"
|
||||
DataType="{x:Type model:NodeData}">
|
||||
DataType="{x:Type core:NodeData}">
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
</DataTemplate>
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls"
|
||||
xmlns:wrapper="clr-namespace:Artemis.VisualScripting.Editor.Controls.Wrapper"
|
||||
xmlns:model="clr-namespace:Artemis.VisualScripting.Model">
|
||||
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"
|
||||
xmlns:s="https://github.com/canton7/Stylet">
|
||||
|
||||
<Style x:Key="StyleButtonPinsModify"
|
||||
TargetType="Button">
|
||||
@@ -73,7 +74,7 @@
|
||||
|
||||
<Setter Property="ItemTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate DataType="{x:Type model:Pin}">
|
||||
<DataTemplate DataType="{x:Type core:Pin}">
|
||||
<controls:VisualScriptPinPresenter Margin="0,5,0,3"
|
||||
Pin="{Binding .}" />
|
||||
</DataTemplate>
|
||||
@@ -88,7 +89,7 @@
|
||||
|
||||
<Setter Property="ItemTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate DataType="{x:Type model:Pin}">
|
||||
<DataTemplate DataType="{x:Type core:Pin}">
|
||||
<controls:VisualScriptPinPresenter Margin="0,5,0,3"
|
||||
Pin="{Binding .}" />
|
||||
</DataTemplate>
|
||||
@@ -108,7 +109,7 @@
|
||||
Style="{StaticResource StylePinListInput}"
|
||||
ItemsSource="{Binding Pins}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type model:Pin}">
|
||||
<DataTemplate DataType="{x:Type core:Pin}">
|
||||
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<controls:VisualScriptPinPresenter Margin="0,5,-3,3"
|
||||
Pin="{Binding .}" />
|
||||
@@ -141,7 +142,7 @@
|
||||
Style="{StaticResource StylePinListOutput}"
|
||||
ItemsSource="{Binding Pins}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type model:Pin}">
|
||||
<DataTemplate DataType="{x:Type core:Pin}">
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Button Style="{StaticResource StyleButtonPinsModify}"
|
||||
Command="{Binding DataContext.RemovePinCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
|
||||
@@ -207,8 +208,7 @@
|
||||
</Border>
|
||||
|
||||
<Border x:Name="BrdCustomView" Grid.Column="1">
|
||||
<ContentControl Content="{Binding Node.Node.CustomViewModel, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
ContentTemplate="{Binding Node.Node.CustomView, RelativeSource={RelativeSource TemplatedParent}}"/>
|
||||
<ContentControl s:View.Model="{Binding Node.CustomViewModel}"/>
|
||||
</Border>
|
||||
|
||||
<Border x:Name="BrdOutputPins" Grid.Column="2">
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
||||
xmlns:controls="clr-namespace:Artemis.VisualScripting.Editor.Controls"
|
||||
xmlns:model="clr-namespace:Artemis.VisualScripting.Model;assembly=Artemis.Core">
|
||||
xmlns:model="clr-namespace:Artemis.VisualScripting.Model;assembly=Artemis.Core"
|
||||
xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core">
|
||||
|
||||
<ControlTemplate x:Key="TemplateVisualScriptPinPresenterInput"
|
||||
TargetType="{x:Type controls:VisualScriptPinPresenter}">
|
||||
@@ -75,7 +76,7 @@
|
||||
<Setter Property="Template" Value="{StaticResource TemplateVisualScriptPinPresenterInput}" />
|
||||
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Pin.Pin.Direction, RelativeSource={RelativeSource Self}}" Value="{x:Static model:PinDirection.Output}">
|
||||
<DataTrigger Binding="{Binding Pin.Pin.Direction, RelativeSource={RelativeSource Self}}" Value="{x:Static core:PinDirection.Output}">
|
||||
<Setter Property="Padding" Value="6,0,0,0" />
|
||||
<Setter Property="Template" Value="{StaticResource TemplateVisualScriptPinPresenterOutput}" />
|
||||
</DataTrigger>
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.VisualScripting.Model;
|
||||
|
||||
namespace Artemis.VisualScripting.Internal
|
||||
{
|
||||
internal interface IExitNode : INode
|
||||
{ }
|
||||
|
||||
internal class ExitNode<T> : Node, IExitNode
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public InputPin<T> Input { get; }
|
||||
|
||||
public T Value { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public ExitNode(string name, string description = "")
|
||||
{
|
||||
this.Name = name;
|
||||
this.Description = description;
|
||||
|
||||
Input = CreateInputPin<T>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
Value = Input.Value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Internal
|
||||
{
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
using System;
|
||||
using Artemis.Core.VisualScripting;
|
||||
|
||||
namespace Artemis.VisualScripting.Model
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal InputPin(INode node, string name)
|
||||
: base(node, name)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
private void Evaluate()
|
||||
{
|
||||
Value = ConnectedTo.Count > 0 ? (T)ConnectedTo[0].PinValue : default;
|
||||
}
|
||||
|
||||
#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
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core.VisualScripting;
|
||||
|
||||
namespace Artemis.VisualScripting.Model
|
||||
{
|
||||
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
|
||||
|
||||
internal InputPinCollection(INode node, string name, int initialCount)
|
||||
: base(node, name, initialCount)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override IPin CreatePin() => new InputPin<T>(Node, string.Empty);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.VisualScripting.ViewModel;
|
||||
|
||||
namespace Artemis.VisualScripting.Model
|
||||
{
|
||||
public abstract class Node : AbstractBindable, INode
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private string _name;
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
protected set => SetProperty(ref _name, value);
|
||||
}
|
||||
|
||||
private string _description;
|
||||
public string Description
|
||||
{
|
||||
get => _description;
|
||||
protected set => SetProperty(ref _description, value);
|
||||
}
|
||||
|
||||
private double _x;
|
||||
public double X
|
||||
{
|
||||
get => _x;
|
||||
set => SetProperty(ref _x, value);
|
||||
}
|
||||
|
||||
private double _y;
|
||||
public double Y
|
||||
{
|
||||
get => _y;
|
||||
set => SetProperty(ref _y, value);
|
||||
}
|
||||
|
||||
private readonly List<IPin> _pins = new();
|
||||
public IReadOnlyCollection<IPin> Pins => new ReadOnlyCollection<IPin>(_pins);
|
||||
|
||||
private readonly List<IPinCollection> _pinCollections = new();
|
||||
public IReadOnlyCollection<IPinCollection> PinCollections => new ReadOnlyCollection<IPinCollection>(_pinCollections);
|
||||
|
||||
public object CustomView { get; private set; }
|
||||
public object CustomViewModel { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler Resetting;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construtors
|
||||
|
||||
protected Node()
|
||||
{ }
|
||||
|
||||
protected Node(string name, string description)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Description = description;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected InputPin<T> CreateInputPin<T>(string name = "")
|
||||
{
|
||||
InputPin<T> pin = new(this, name);
|
||||
_pins.Add(pin);
|
||||
OnPropertyChanged(nameof(Pins));
|
||||
return pin;
|
||||
}
|
||||
|
||||
protected InputPin CreateInputPin(Type type, string name = "")
|
||||
{
|
||||
InputPin pin = new(this, type, name);
|
||||
_pins.Add(pin);
|
||||
OnPropertyChanged(nameof(Pins));
|
||||
return pin;
|
||||
}
|
||||
|
||||
protected OutputPin<T> CreateOutputPin<T>(string name = "")
|
||||
{
|
||||
OutputPin<T> pin = new(this, name);
|
||||
_pins.Add(pin);
|
||||
OnPropertyChanged(nameof(Pins));
|
||||
return pin;
|
||||
}
|
||||
|
||||
protected OutputPin CreateOutputPin(Type type, string name = "")
|
||||
{
|
||||
OutputPin pin = new(this, type, name);
|
||||
_pins.Add(pin);
|
||||
OnPropertyChanged(nameof(Pins));
|
||||
return pin;
|
||||
}
|
||||
|
||||
protected bool RemovePin(Pin pin)
|
||||
{
|
||||
bool isRemoved = _pins.Remove(pin);
|
||||
if (isRemoved)
|
||||
{
|
||||
pin.DisconnectAll();
|
||||
OnPropertyChanged(nameof(Pins));
|
||||
}
|
||||
return isRemoved;
|
||||
}
|
||||
|
||||
protected InputPinCollection<T> CreateInputPinCollection<T>(string name = "", int initialCount = 1)
|
||||
{
|
||||
InputPinCollection<T> pin = new(this, name, initialCount);
|
||||
_pinCollections.Add(pin);
|
||||
OnPropertyChanged(nameof(PinCollections));
|
||||
return pin;
|
||||
}
|
||||
|
||||
protected OutputPinCollection<T> CreateOutputPinCollection<T>(string name = "", int initialCount = 1)
|
||||
{
|
||||
OutputPinCollection<T> pin = new(this, name, initialCount);
|
||||
_pinCollections.Add(pin);
|
||||
OnPropertyChanged(nameof(PinCollections));
|
||||
return pin;
|
||||
}
|
||||
|
||||
protected void RegisterCustomView(DataTemplate view, object viewModel)
|
||||
{
|
||||
CustomView = view;
|
||||
CustomViewModel = viewModel;
|
||||
}
|
||||
|
||||
public abstract void Evaluate();
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
Resetting?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
using System;
|
||||
using Artemis.Core.VisualScripting;
|
||||
|
||||
namespace Artemis.VisualScripting.Model
|
||||
{
|
||||
public class NodeData
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public Type Type { get; }
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
public string Category { get; }
|
||||
|
||||
private Func<INode> _create;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public NodeData(Type type, string name, string description, string category, Func<INode> create)
|
||||
{
|
||||
this.Type = type;
|
||||
this.Name = name;
|
||||
this.Description = description;
|
||||
this.Category = category;
|
||||
this._create = create;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public INode CreateNode() => _create();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
using System;
|
||||
using Artemis.Core.VisualScripting;
|
||||
|
||||
namespace Artemis.VisualScripting.Model
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal OutputPin(INode node, string name)
|
||||
: base(node, name)
|
||||
{ }
|
||||
|
||||
#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
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using Artemis.Core.VisualScripting;
|
||||
|
||||
namespace Artemis.VisualScripting.Model
|
||||
{
|
||||
public sealed class OutputPinCollection<T> : PinCollection
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public override PinDirection Direction => PinDirection.Output;
|
||||
public override Type Type => typeof(T);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal OutputPinCollection(INode node, string name, int initialCount)
|
||||
: base(node, name, initialCount)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override IPin CreatePin() => new OutputPin<T>(Node, string.Empty);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.VisualScripting.ViewModel;
|
||||
|
||||
namespace Artemis.VisualScripting.Model
|
||||
{
|
||||
public abstract class Pin : AbstractBindable, IPin
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public INode Node { get; }
|
||||
public string Name { get; }
|
||||
|
||||
private bool _isEvaluated;
|
||||
public bool IsEvaluated
|
||||
{
|
||||
get => _isEvaluated;
|
||||
set => SetProperty(ref _isEvaluated, value);
|
||||
}
|
||||
|
||||
private readonly List<IPin> _connectedTo = new();
|
||||
public IReadOnlyList<IPin> ConnectedTo => new ReadOnlyCollection<IPin>(_connectedTo);
|
||||
|
||||
public abstract PinDirection Direction { get; }
|
||||
public abstract Type Type { get; }
|
||||
public abstract object PinValue { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
protected Pin(INode node, string name = "")
|
||||
{
|
||||
this.Node = node;
|
||||
this.Name = name;
|
||||
|
||||
if (Node != null)
|
||||
Node.Resetting += OnNodeResetting;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
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)
|
||||
{
|
||||
IsEvaluated = false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Artemis.Core.VisualScripting;
|
||||
|
||||
namespace Artemis.VisualScripting.Model
|
||||
{
|
||||
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 Constructors
|
||||
|
||||
protected PinCollection(INode node, string name, int initialCount)
|
||||
{
|
||||
this.Node = node;
|
||||
this.Name = name;
|
||||
|
||||
for (int i = 0; i < initialCount; i++)
|
||||
AddPin();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public IPin AddPin()
|
||||
{
|
||||
IPin pin = CreatePin();
|
||||
_pins.Add(pin);
|
||||
return pin;
|
||||
}
|
||||
|
||||
public bool Remove(IPin pin) => _pins.Remove(pin);
|
||||
|
||||
protected abstract IPin CreatePin();
|
||||
|
||||
public IEnumerator<IPin> GetEnumerator() => Pins.GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.VisualScripting.Internal;
|
||||
using Artemis.VisualScripting.ViewModel;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Artemis.VisualScripting.Model
|
||||
{
|
||||
public abstract class Script : AbstractBindable, IScript
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
|
||||
private readonly List<INode> _nodes = new();
|
||||
public IEnumerable<INode> Nodes => new ReadOnlyCollection<INode>(_nodes);
|
||||
|
||||
protected INode ExitNode { get; set; }
|
||||
public abstract Type ResultType { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public Script(string name, string description)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Description = description;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Run()
|
||||
{
|
||||
foreach (INode node in Nodes)
|
||||
node.Reset();
|
||||
|
||||
ExitNode.Evaluate();
|
||||
}
|
||||
|
||||
public void AddNode(INode node)
|
||||
{
|
||||
_nodes.Add(node);
|
||||
}
|
||||
|
||||
public void RemoveNode(INode node)
|
||||
{
|
||||
_nodes.Remove(node);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class Script<T> : Script, IScript<T>
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public T Result => ((ExitNode<T>)ExitNode).Value;
|
||||
|
||||
public override Type ResultType => typeof(T);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public Script(string name, string description)
|
||||
: base(name, description)
|
||||
{
|
||||
ExitNode = new ExitNode<T>(name, description);
|
||||
AddNode(ExitNode);
|
||||
}
|
||||
|
||||
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)]
|
||||
private Script(string name, string description, INode exitNode)
|
||||
: base(name, description)
|
||||
{
|
||||
ExitNode = exitNode;
|
||||
AddNode(ExitNode);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Collections;
|
||||
using Artemis.VisualScripting.Attributes;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes
|
||||
{
|
||||
[UI("Greater than", "Checks if the first input is greater than the second.")]
|
||||
[Node("Greater than", "Checks if the first input is greater than the second.")]
|
||||
public class GreaterThanNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
@@ -45,7 +44,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
#endregion
|
||||
}
|
||||
|
||||
[UI("Less than", "Checks if the first input is less than the second.")]
|
||||
[Node("Less than", "Checks if the first input is less than the second.")]
|
||||
public class LessThanNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
@@ -86,7 +85,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
#endregion
|
||||
}
|
||||
|
||||
[UI("Equals", "Checks if the two inputs are equals.")]
|
||||
[Node("Equals", "Checks if the two inputs are equals.")]
|
||||
public class EqualsNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
@@ -127,7 +126,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
#endregion
|
||||
}
|
||||
|
||||
[UI("Negate", "Negates the boolean.")]
|
||||
[Node("Negate", "Negates the boolean.")]
|
||||
public class NegateNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
using Artemis.VisualScripting.Attributes;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes
|
||||
{
|
||||
[UI("To String", "Converts the input to a string.")]
|
||||
[Node("To String", "Converts the input to a string.")]
|
||||
public class ConvertToStringNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
@@ -35,7 +34,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
#endregion
|
||||
}
|
||||
|
||||
[UI("To Integer", "Converts the input to an integer.")]
|
||||
[Node("To Integer", "Converts the input to an integer.")]
|
||||
public class ConvertToIntegerNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
@@ -70,7 +69,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
#endregion
|
||||
}
|
||||
|
||||
[UI("To Double", "Converts the input to a double.")]
|
||||
[Node("To Double", "Converts the input to a double.")]
|
||||
public class ConvertToDoubleNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.CustomViewModels
|
||||
{
|
||||
public class StaticDoubleValueNodeCustomViewModel : PropertyChangedBase
|
||||
{
|
||||
private double _input;
|
||||
|
||||
public double Input
|
||||
{
|
||||
get => _input;
|
||||
set => SetAndNotify(ref _input, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.CustomViewModels
|
||||
{
|
||||
public class StaticIntegerValueNodeCustomViewModel : PropertyChangedBase
|
||||
{
|
||||
private int _input;
|
||||
|
||||
public int Input
|
||||
{
|
||||
get => _input;
|
||||
set => SetAndNotify(ref _input, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.CustomViewModels
|
||||
{
|
||||
public class StaticStringValueNodeCustomViewModel : PropertyChangedBase
|
||||
{
|
||||
private string _input;
|
||||
|
||||
public string Input
|
||||
{
|
||||
get => _input;
|
||||
set => SetAndNotify(ref _input, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="Artemis.VisualScripting.Nodes.CustomViews.StaticDoubleValueNodeCustomView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.VisualScripting.Nodes.CustomViewModels"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<TextBox VerticalAlignment="Center"
|
||||
HorizontalAlignment="Stretch"
|
||||
Text="{Binding Input}" />
|
||||
</UserControl>
|
||||
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="Artemis.VisualScripting.Nodes.CustomViews.StaticIntegerValueNodeCustomView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.VisualScripting.Nodes.CustomViewModels"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<TextBox VerticalAlignment="Center"
|
||||
HorizontalAlignment="Stretch"
|
||||
Text="{Binding Input}" />
|
||||
</UserControl>
|
||||
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="Artemis.VisualScripting.Nodes.CustomViews.StaticStringValueNodeCustomView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Artemis.VisualScripting.Nodes.CustomViewModels"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<TextBox VerticalAlignment="Center"
|
||||
HorizontalAlignment="Stretch"
|
||||
Text="{Binding Input}" />
|
||||
</UserControl>
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Windows;
|
||||
using Artemis.VisualScripting.Attributes;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.Core;
|
||||
using Artemis.VisualScripting.Nodes.CustomViewModels;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes
|
||||
{
|
||||
[UI("Integer-Value", "Outputs an configurable integer value.")]
|
||||
[Node("Integer-Value", "Outputs an configurable integer value.")]
|
||||
public class StaticIntegerValueNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
@@ -21,7 +20,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
: base("Integer", "Outputs an configurable integer value.")
|
||||
{
|
||||
Output = CreateOutputPin<int>();
|
||||
RegisterCustomView(Application.Current.FindResource("StaticValueCustomViewTemplate") as DataTemplate, _customViewModel);
|
||||
RegisterCustomViewModel<StaticIntegerValueNodeCustomViewModel>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -36,7 +35,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
#endregion
|
||||
}
|
||||
|
||||
[UI("Double-Value", "Outputs a configurable double value.")]
|
||||
[Node("Double-Value", "Outputs a configurable double value.")]
|
||||
public class StaticDoubleValueNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
@@ -53,7 +52,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
: base("Double", "Outputs a configurable double value.")
|
||||
{
|
||||
Output = CreateOutputPin<double>();
|
||||
RegisterCustomView(Application.Current.FindResource("StaticValueCustomViewTemplate") as DataTemplate, _customViewModel);
|
||||
RegisterCustomViewModel<StaticDoubleValueNodeCustomViewModel>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -68,7 +67,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
#endregion
|
||||
}
|
||||
|
||||
[UI("String-Value", "Outputs a configurable string value.")]
|
||||
[Node("String-Value", "Outputs a configurable string value.")]
|
||||
public class StaticStringValueNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
@@ -85,7 +84,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
: base("String", "Outputs a configurable string value.")
|
||||
{
|
||||
Output = CreateOutputPin<string>();
|
||||
RegisterCustomView(Application.Current.FindResource("StaticValueCustomViewTemplate") as DataTemplate, _customViewModel);
|
||||
RegisterCustomViewModel<StaticStringValueNodeCustomViewModel>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -102,20 +101,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
|
||||
#region CustomViewModels
|
||||
|
||||
public class StaticIntegerValueNodeCustomViewModel
|
||||
{
|
||||
public int Input { get; set; }
|
||||
}
|
||||
|
||||
public class StaticDoubleValueNodeCustomViewModel
|
||||
{
|
||||
public double Input { get; set; }
|
||||
}
|
||||
|
||||
public class StaticStringValueNodeCustomViewModel
|
||||
{
|
||||
public string Input { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Linq;
|
||||
using Artemis.VisualScripting.Attributes;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes
|
||||
{
|
||||
[UI("Format", "Formats the input string.")]
|
||||
[Node("Format", "Formats the input string.")]
|
||||
public class StringFormatNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:nodes="clr-namespace:Artemis.VisualScripting.Nodes">
|
||||
|
||||
<DataTemplate x:Key="StaticValueCustomViewTemplate"
|
||||
DataType="{x:Type nodes:StaticIntegerValueNodeCustomViewModel}">
|
||||
<TextBox VerticalAlignment="Center"
|
||||
HorizontalAlignment="Stretch"
|
||||
Text="{Binding Input}" />
|
||||
</DataTemplate>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Linq;
|
||||
using Artemis.VisualScripting.Attributes;
|
||||
using Artemis.VisualScripting.Model;
|
||||
using Artemis.Core;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes
|
||||
{
|
||||
[UI("Sum (Integer)", "Sums the connected integer values.")]
|
||||
[Node("Sum (Integer)", "Sums the connected integer values.")]
|
||||
public class SumIntegersNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
@@ -36,7 +35,7 @@ namespace Artemis.VisualScripting.Nodes
|
||||
#endregion
|
||||
}
|
||||
|
||||
[UI("Sum (Double)", "Sums the connected double values.")]
|
||||
[Node("Sum (Double)", "Sums the connected double values.")]
|
||||
public class SumDoublesNode : Node
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Artemis.Core.VisualScripting;
|
||||
using Artemis.VisualScripting.Attributes;
|
||||
using Artemis.VisualScripting.Model;
|
||||
|
||||
namespace Artemis.VisualScripting.Services
|
||||
{
|
||||
//TODO DarthAffe 09.07.2021: Make this Static?
|
||||
public class NodeService
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private static readonly Type TYPE_NODE = typeof(INode);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties & Fields
|
||||
|
||||
private Dictionary<Type, NodeData> _nodeData { get; } = new();
|
||||
public IReadOnlyDictionary<Type, NodeData> NodeData => new ReadOnlyDictionary<Type, NodeData>(_nodeData);
|
||||
public IEnumerable<NodeData> AvailableNodes => _nodeData.Values;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void InitializeNodes()
|
||||
{
|
||||
foreach (Type nodeType in typeof(NodeService).Assembly.GetTypes().Where(t => typeof(INode).IsAssignableFrom(t) && t.IsPublic && !t.IsAbstract && !t.IsInterface))
|
||||
InitializeNode(nodeType);
|
||||
}
|
||||
|
||||
public void InitializeNode<T>()
|
||||
where T : INode
|
||||
=> InitializeNode(typeof(T));
|
||||
|
||||
public void InitializeNode(Type nodeType)
|
||||
{
|
||||
if (!TYPE_NODE.IsAssignableFrom(nodeType)) throw new ArgumentException("Node has to be a base type of the Node-Type.", nameof(nodeType));
|
||||
if (_nodeData.ContainsKey(nodeType)) return;
|
||||
|
||||
UIAttribute uiAttribute = nodeType.GetCustomAttribute<UIAttribute>();
|
||||
string name = uiAttribute?.Name ?? nodeType.Name;
|
||||
string description = uiAttribute?.Description ?? string.Empty;
|
||||
string category = uiAttribute?.Category ?? string.Empty;
|
||||
|
||||
NodeData nodeData = new(nodeType, name, description, category, () => CreateNode(nodeType));
|
||||
_nodeData.Add(nodeType, nodeData);
|
||||
}
|
||||
|
||||
private INode CreateNode(Type nodeType) => Activator.CreateInstance(nodeType) as INode;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,15 @@
|
||||
"resolved": "2021.1.0",
|
||||
"contentHash": "n9JSw5Z+F+6gp9vSv4aLH6p/bx3GAYA6FZVq1wJq/TJySv/kPgFKLGFeS7A8Xa5X4/GWorh5gd43yjamUgnBNA=="
|
||||
},
|
||||
"Stylet": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.3.6, )",
|
||||
"resolved": "1.3.6",
|
||||
"contentHash": "SISR+DsPrgBww3AI5FtHx1tD9VkEfJWZYu+ykq5EFM2o7Se9zxNR6FAa2g5QadQa90NKMYxn/VZEQRDo7/pdkw==",
|
||||
"dependencies": {
|
||||
"System.Drawing.Common": "4.6.0"
|
||||
}
|
||||
},
|
||||
"Castle.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.2.0",
|
||||
@@ -87,6 +96,14 @@
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.6.0",
|
||||
"contentHash": "Edg+pFW5C8WJb680Za2kTV8TqUi6Ahl/WldRVoOVJ23UQLpDHFspa+umgFjkWZw24ETsU99Cg+ErZz683M4chg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "3.0.0"
|
||||
}
|
||||
},
|
||||
"NETStandard.Library": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.6.1",
|
||||
@@ -504,6 +521,15 @@
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Drawing.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.6.0",
|
||||
"contentHash": "2A3spjjoPZnvpVh/sDTzd+0H8ZqTdr+hH/6obB8MMfG81EJ85PmxCKDBxhBVQiA25PliKAZ1sKogDcq9mSnFEA==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "3.0.0",
|
||||
"Microsoft.Win32.SystemEvents": "4.6.0"
|
||||
}
|
||||
},
|
||||
"System.Dynamic.Runtime": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
|
||||
Reference in new issue
Block a user