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

Nodes - Added event value cycle node

This commit is contained in:
Robert 2021-09-20 22:55:10 +02:00
parent 02f4609eae
commit 8413b8d6db
13 changed files with 195 additions and 74 deletions

View File

@ -130,8 +130,11 @@ namespace Artemis.Core
/// at all /// at all
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static int ScoreCastability(this Type to, Type from) public static int ScoreCastability(this Type to, Type? from)
{ {
if (from == null)
return 0;
if (to == from) if (to == from)
return 5; return 5;
if (to.TypeIsNumber() && from.TypeIsNumber()) if (to.TypeIsNumber() && from.TypeIsNumber())

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -31,4 +32,38 @@ namespace Artemis.Core
#endregion #endregion
} }
public sealed class InputPinCollection : PinCollection
{
#region Properties & Fields
public override PinDirection Direction => PinDirection.Input;
public override Type Type { get; }
public new IEnumerable<InputPin> Pins => base.Pins.Cast<InputPin>();
public IEnumerable Values => Pins.Select(p => p.Value);
#endregion
#region Constructors
internal InputPinCollection(INode node, Type type, string name, int initialCount)
: base(node, name, 0)
{
this.Type = type;
// Can't do this in the base constructor because the type won't be set yet
for (int i = 0; i < initialCount; i++)
AddPin();
}
#endregion
#region Methods
protected override IPin CreatePin() => new InputPin(Node, Type, string.Empty);
#endregion
}
} }

View File

@ -22,5 +22,6 @@ namespace Artemis.Core
void ConnectTo(IPin pin); void ConnectTo(IPin pin);
void DisconnectFrom(IPin pin); void DisconnectFrom(IPin pin);
void DisconnectAll();
} }
} }

View File

@ -130,6 +130,14 @@ namespace Artemis.Core
return pin; return pin;
} }
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;
}
protected OutputPinCollection<T> CreateOutputPinCollection<T>(string name = "", int initialCount = 1) protected OutputPinCollection<T> CreateOutputPinCollection<T>(string name = "", int initialCount = 1)
{ {
OutputPinCollection<T> pin = new(this, name, initialCount); OutputPinCollection<T> pin = new(this, name, initialCount);
@ -138,6 +146,19 @@ namespace Artemis.Core
return pin; return pin;
} }
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 virtual void Initialize(INodeScript script)
{ } { }

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Collections;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
@ -7,7 +6,6 @@ using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Shapes; using System.Windows.Shapes;
using Artemis.Core;
using Artemis.UI.Shared; using Artemis.UI.Shared;
using Artemis.VisualScripting.Editor.Controls.Wrapper; using Artemis.VisualScripting.Editor.Controls.Wrapper;
@ -95,13 +93,15 @@ namespace Artemis.VisualScripting.Editor.Controls
private void OnPathMouseDown(object sender, MouseButtonEventArgs args) private void OnPathMouseDown(object sender, MouseButtonEventArgs args)
{ {
if ((args.ChangedButton == MouseButton.Left) && (args.LeftButton == MouseButtonState.Pressed) && (args.ClickCount == 2)) if (args.ChangedButton == MouseButton.Left && args.LeftButton == MouseButtonState.Pressed && args.ClickCount == 2)
{ {
//TODO DarthAffe 17.06.2021: Should we add rerouting? //TODO DarthAffe 17.06.2021: Should we add rerouting?
//AddRerouteNode(); //AddRerouteNode();
} }
else if (args.ChangedButton == MouseButton.Middle) else if (args.ChangedButton == MouseButton.Middle)
{
Cable.Disconnect(); Cable.Disconnect();
}
} }
private static void CableChanged(DependencyObject d, DependencyPropertyChangedEventArgs args) private static void CableChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
@ -167,8 +167,8 @@ namespace Artemis.VisualScripting.Editor.Controls
return; return;
ValuePosition = new Point( ValuePosition = new Point(
Cable.From.AbsolutePosition.X + ((Cable.To.AbsolutePosition.X - Cable.From.AbsolutePosition.X) / 2), Cable.From.AbsolutePosition.X + (Cable.To.AbsolutePosition.X - Cable.From.AbsolutePosition.X) / 2,
Cable.From.AbsolutePosition.Y + ((Cable.To.AbsolutePosition.Y - Cable.From.AbsolutePosition.Y) / 2) Cable.From.AbsolutePosition.Y + (Cable.To.AbsolutePosition.Y - Cable.From.AbsolutePosition.Y) / 2
); );
} }

View File

@ -7,6 +7,7 @@
xmlns:skiaSharp="clr-namespace:SkiaSharp;assembly=SkiaSharp" xmlns:skiaSharp="clr-namespace:SkiaSharp;assembly=SkiaSharp"
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"> xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared">
<converters:CenterTranslateConverter x:Key="CenterTranslateConverter" /> <converters:CenterTranslateConverter x:Key="CenterTranslateConverter" />
<shared:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
<ControlTemplate x:Key="TemplateVisualScriptCablePresenter" <ControlTemplate x:Key="TemplateVisualScriptCablePresenter"
TargetType="{x:Type controls:VisualScriptCablePresenter}"> TargetType="{x:Type controls:VisualScriptCablePresenter}">
@ -74,14 +75,16 @@
</Border> </Border>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
<!-- <DataTemplate DataType=""> -->
<!-- <TextBlock></TextBlock> -->
<!-- </DataTemplate> -->
</Border.Resources> </Border.Resources>
<ContentControl Content="{Binding Cable.From.Pin.PinValue, RelativeSource={RelativeSource TemplatedParent}}" /> <Grid>
<!-- <TextBlock Text="{Binding Cable.From.Pin.PinValue, TargetNullValue=-, RelativeSource={RelativeSource TemplatedParent}}" /> --> <ContentControl Content="{Binding Cable.From.Pin.PinValue, RelativeSource={RelativeSource TemplatedParent}}"
Visibility="{Binding Cable.From.Pin.PinValue, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource NullToVisibilityConverter}}" />
<TextBlock Text="null"
FontStyle="Italic"
Visibility="{Binding Cable.From.Pin.PinValue, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted}" />
</Grid>
</Border> </Border>
</Canvas> </Canvas>

View File

@ -3,9 +3,10 @@ using System.ComponentModel;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Modules; using Artemis.Core.Modules;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.VisualScripting.Nodes.CustomViewModels;
using Stylet; using Stylet;
namespace Artemis.VisualScripting.Nodes.CustomViewModels namespace Artemis.VisualScripting.Nodes.DataModel.CustomViewModels
{ {
public class DataModelEventNodeCustomViewModel : CustomNodeViewModel public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
{ {
@ -22,7 +23,7 @@ namespace Artemis.VisualScripting.Nodes.CustomViewModels
public PluginSetting<bool> ShowFullPaths { get; } public PluginSetting<bool> ShowFullPaths { get; }
public PluginSetting<bool> ShowDataModelValues { get; } public PluginSetting<bool> ShowDataModelValues { get; }
public BindableCollection<Type> FilterTypes { get; } = new() { typeof(DataModelEvent) }; public BindableCollection<Type> FilterTypes { get; } = new() { typeof(IDataModelEvent) };
public BindableCollection<Module> Modules public BindableCollection<Module> Modules
{ {

View File

@ -2,9 +2,10 @@
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Modules; using Artemis.Core.Modules;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.VisualScripting.Nodes.CustomViewModels;
using Stylet; using Stylet;
namespace Artemis.VisualScripting.Nodes.CustomViewModels namespace Artemis.VisualScripting.Nodes.DataModel.CustomViewModels
{ {
public class DataModelNodeCustomViewModel : CustomNodeViewModel public class DataModelNodeCustomViewModel : CustomNodeViewModel
{ {

View File

@ -1,4 +1,4 @@
<UserControl x:Class="Artemis.VisualScripting.Nodes.CustomViews.DataModelEventNodeCustomView" <UserControl x:Class="Artemis.VisualScripting.Nodes.DataModel.CustomViews.DataModelEventNodeCustomView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@ -15,8 +15,7 @@
ShowFullPath="{Binding ShowFullPaths.Value}" ShowFullPath="{Binding ShowFullPaths.Value}"
ShowDataModelValues="{Binding ShowDataModelValues.Value}" ShowDataModelValues="{Binding ShowDataModelValues.Value}"
FilterTypes="{Binding FilterTypes}" FilterTypes="{Binding FilterTypes}"
ButtonBrush="#434343"/> ButtonBrush="DarkGoldenrod"/>
<editor:VisualScriptPresenter Script="{Binding ChildScript}" IsEnabled="False" ></editor:VisualScriptPresenter>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@ -1,4 +1,4 @@
<UserControl x:Class="Artemis.VisualScripting.Nodes.CustomViews.DataModelNodeCustomView" <UserControl x:Class="Artemis.VisualScripting.Nodes.DataModel.CustomViews.DataModelNodeCustomView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

View File

@ -0,0 +1,109 @@
using System;
using System.Linq;
using Artemis.Core;
using Artemis.Core.Events;
using Artemis.Storage.Entities.Profile;
using Artemis.VisualScripting.Nodes.DataModel.CustomViewModels;
namespace Artemis.VisualScripting.Nodes.DataModel
{
[Node("Data Model-Event", "Responds to a data model event trigger", "External", OutputType = typeof(bool))]
public class DataModelEventNode : Node<DataModelEventNodeCustomViewModel>, IDisposable
{
private DataModelPath _dataModelPath;
private DateTime _lastTrigger;
private int _currentIndex;
public DataModelEventNode() : base("Data Model-Event", "Responds to a data model event trigger")
{
Input = CreateInputPin<object>();
Input.PinConnected += InputOnPinConnected;
}
public InputPin<object> Input { get; }
public InputPinCollection CycleValues { get; set; }
public OutputPin Output { get; set; }
public INodeScript Script { get; set; }
public DataModelPath DataModelPath
{
get => _dataModelPath;
set => SetAndNotify(ref _dataModelPath, value);
}
public override void Initialize(INodeScript script)
{
Script = script;
CreateCycleValues();
CreateOutput();
if (Storage is not DataModelPathEntity pathEntity)
return;
DataModelPath = new DataModelPath(pathEntity);
}
public override void Evaluate()
{
object outputValue = null;
if (DataModelPath?.GetValue() is DataModelEvent dataModelEvent)
{
if (dataModelEvent.LastTrigger > _lastTrigger)
{
_lastTrigger = dataModelEvent.LastTrigger;
_currentIndex++;
if (_currentIndex > CycleValues.Count())
_currentIndex = 0;
}
outputValue = _currentIndex == 0
? Input.Value
: CycleValues.ElementAt(_currentIndex - 1).PinValue;
}
Output.Value = outputValue ?? Output.Type.GetDefault();
}
private void InputOnPinConnected(object sender, SingleValueEventArgs<IPin> e)
{
CreateCycleValues();
CreateOutput();
}
private void CreateCycleValues()
{
int pinCount = CycleValues?.Count() ?? 1;
Type inputType = Input.ConnectedTo.FirstOrDefault()?.Type ?? typeof(object);
if (CycleValues != null)
{
if (inputType == CycleValues.Type)
return;
RemovePinCollection(CycleValues);
}
CycleValues = CreateInputPinCollection(inputType, "", pinCount);
}
private void CreateOutput()
{
Type inputType = Input.ConnectedTo.FirstOrDefault()?.Type ?? typeof(object);
if (Output != null)
{
if (inputType == Output.Type)
return;
RemovePin(Output);
}
Output = CreateOutputPin(inputType);
}
/// <inheritdoc />
public void Dispose()
{
}
}
}

View File

@ -1,11 +1,10 @@
using System; using System;
using System.Linq;
using Artemis.Core; using Artemis.Core;
using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile;
using Artemis.VisualScripting.Nodes.CustomViewModels; using Artemis.VisualScripting.Nodes.DataModel.CustomViewModels;
using Stylet; using Stylet;
namespace Artemis.VisualScripting.Nodes namespace Artemis.VisualScripting.Nodes.DataModel
{ {
[Node("Data Model-Value", "Outputs a selectable data model value.", "External")] [Node("Data Model-Value", "Outputs a selectable data model value.", "External")]
public class DataModelNode : Node<DataModelNodeCustomViewModel>, IDisposable public class DataModelNode : Node<DataModelNodeCustomViewModel>, IDisposable

View File

@ -1,51 +0,0 @@
using System;
using Artemis.Core;
using Artemis.Storage.Entities.Profile;
using Artemis.VisualScripting.Nodes.CustomViewModels;
namespace Artemis.VisualScripting.Nodes
{
[Node("Data Model-Event", "Responds to a data model event trigger", "External", OutputType = typeof(bool))]
public class DataModelEventNode : Node<DataModelEventNodeCustomViewModel>, IDisposable
{
private DataModelPath _dataModelPath;
public DataModelEventNode() : base("Data Model-Event", "Responds to a data model event trigger")
{
Output = CreateOutputPin<bool>();
}
public OutputPin<bool> Output { get; }
public INodeScript Script { get; set; }
public DataModelPath DataModelPath
{
get => _dataModelPath;
set => SetAndNotify(ref _dataModelPath, value);
}
public override void Initialize(INodeScript script)
{
Script = script;
if (Storage is not DataModelPathEntity pathEntity)
return;
DataModelPath = new DataModelPath(pathEntity);
DataModelPath.PathValidated += DataModelPathOnPathValidated;
}
public override void Evaluate()
{
}
private void DataModelPathOnPathValidated(object sender, EventArgs e)
{
}
/// <inheritdoc />
public void Dispose()
{
}
}
}