diff --git a/src/Artemis.Core/Artemis.Core.csproj.DotSettings b/src/Artemis.Core/Artemis.Core.csproj.DotSettings index 31cbebcb3..224b124a9 100644 --- a/src/Artemis.Core/Artemis.Core.csproj.DotSettings +++ b/src/Artemis.Core/Artemis.Core.csproj.DotSettings @@ -1,5 +1,6 @@  True + True True True True @@ -49,6 +50,8 @@ True True True + True + True True True True @@ -83,4 +86,6 @@ True True True - True \ No newline at end of file + True + True + True \ No newline at end of file diff --git a/src/Artemis.Core/Events/Stores/NodeTypeStoreEvent.cs b/src/Artemis.Core/Events/Stores/NodeTypeStoreEvent.cs new file mode 100644 index 000000000..e91d27b6a --- /dev/null +++ b/src/Artemis.Core/Events/Stores/NodeTypeStoreEvent.cs @@ -0,0 +1,12 @@ +namespace Artemis.Core +{ + internal class NodeTypeStoreEvent + { + public NodeTypeStoreEvent(NodeTypeRegistration typeRegistration) + { + TypeRegistration = typeRegistration; + } + + public NodeTypeRegistration TypeRegistration { get; } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs index bd4b4994a..091d5bc57 100644 --- a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs +++ b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs @@ -66,9 +66,9 @@ namespace Artemis.Core internal void LoadRenderElement() { - DisplayCondition = RenderElementEntity.DisplayCondition != null - ? new DataModelConditionGroup(null, RenderElementEntity.DisplayCondition) - : new DataModelConditionGroup(null); + // DisplayCondition = RenderElementEntity.DisplayCondition != null + // ? new DataModelConditionGroup(null, RenderElementEntity.DisplayCondition) + // : new DataModelConditionGroup(null); Timeline = RenderElementEntity.Timeline != null ? new Timeline(RenderElementEntity.Timeline) @@ -97,8 +97,8 @@ namespace Artemis.Core } // Conditions - RenderElementEntity.DisplayCondition = DisplayCondition?.Entity; - DisplayCondition?.Save(); + // RenderElementEntity.DisplayCondition = DisplayCondition?.Entity; + // DisplayCondition?.Save(); // Timeline RenderElementEntity.Timeline = Timeline?.Entity; @@ -125,8 +125,8 @@ namespace Artemis.Core { // The play mode dictates whether to stick to the main segment unless the display conditions contains events bool stickToMainSegment = (Timeline.PlayMode == TimelinePlayMode.Repeat || Timeline.EventOverlapMode == TimeLineEventOverlapMode.Toggle) && DisplayConditionMet; - if (DisplayCondition != null && DisplayCondition.ContainsEvents && Timeline.EventOverlapMode != TimeLineEventOverlapMode.Toggle) - stickToMainSegment = false; + // if (DisplayCondition != null && DisplayCondition.ContainsEvents && Timeline.EventOverlapMode != TimeLineEventOverlapMode.Toggle) + // stickToMainSegment = false; Timeline.Update(TimeSpan.FromSeconds(deltaTime), stickToMainSegment); } @@ -354,14 +354,14 @@ namespace Artemis.Core protected set => SetAndNotify(ref _displayConditionMet, value); } - private DataModelConditionGroup? _displayCondition; + private NodeScript? _displayCondition; private bool _displayConditionMet; private bool _toggledOnByEvent = false; /// /// Gets or sets the root display condition group /// - public DataModelConditionGroup? DisplayCondition + public NodeScript? DisplayCondition { get => _displayCondition; set => SetAndNotify(ref _displayCondition, value); @@ -387,20 +387,22 @@ namespace Artemis.Core if (Timeline.EventOverlapMode != TimeLineEventOverlapMode.Toggle) _toggledOnByEvent = false; - bool conditionMet = DisplayCondition.Evaluate(); + DisplayCondition.Run(); + bool conditionMet = DisplayCondition.Result; if (Parent is RenderProfileElement parent && !parent.DisplayConditionMet) conditionMet = false; - if (!DisplayCondition.ContainsEvents) - { - // Regular conditions reset the timeline whenever their condition is met and was not met before that - if (conditionMet && !DisplayConditionMet && Timeline.IsFinished) - Timeline.JumpToStart(); - // If regular conditions are no longer met, jump to the end segment if stop mode requires it - if (!conditionMet && Timeline.StopMode == TimelineStopMode.SkipToEnd) - Timeline.JumpToEndSegment(); - } - else if (conditionMet) + // if (!DisplayCondition.ContainsEvents) + // { + // // Regular conditions reset the timeline whenever their condition is met and was not met before that + // if (conditionMet && !DisplayConditionMet && Timeline.IsFinished) + // Timeline.JumpToStart(); + // // If regular conditions are no longer met, jump to the end segment if stop mode requires it + // if (!conditionMet && Timeline.StopMode == TimelineStopMode.SkipToEnd) + // Timeline.JumpToEndSegment(); + // } + // else if (conditionMet) + if (conditionMet) { if (Timeline.EventOverlapMode == TimeLineEventOverlapMode.Toggle) { diff --git a/src/Artemis.Core/RGB.NET/SKTexture.cs b/src/Artemis.Core/RGB.NET/SKTexture.cs index 27a9f6d5b..6bb77132a 100644 --- a/src/Artemis.Core/RGB.NET/SKTexture.cs +++ b/src/Artemis.Core/RGB.NET/SKTexture.cs @@ -107,7 +107,7 @@ namespace Artemis.Core GetRegionData(skRectI.Left, skRectI.Top, skRectI.Width, skRectI.Height, buffer); Span pixelData = stackalloc byte[DATA_PER_PIXEL]; - Sampler.SampleColor(new SamplerInfo(skRectI.Width, skRectI.Height, buffer), pixelData); + Sampler.Sample(new SamplerInfo(skRectI.Width, skRectI.Height, buffer), pixelData); return GetColor(pixelData); } @@ -119,7 +119,7 @@ namespace Artemis.Core GetRegionData(skRectI.Left, skRectI.Top, skRectI.Width, skRectI.Height, buffer); Span pixelData = stackalloc byte[DATA_PER_PIXEL]; - Sampler.SampleColor(new SamplerInfo(skRectI.Width, skRectI.Height, buffer), pixelData); + Sampler.Sample(new SamplerInfo(skRectI.Width, skRectI.Height, buffer), pixelData); ArrayPool.Shared.Return(rent); diff --git a/src/Artemis.Core/Services/Interfaces/IScriptingService.cs b/src/Artemis.Core/Services/Interfaces/IScriptingService.cs index aefd3480f..037939ce7 100644 --- a/src/Artemis.Core/Services/Interfaces/IScriptingService.cs +++ b/src/Artemis.Core/Services/Interfaces/IScriptingService.cs @@ -4,7 +4,7 @@ using Artemis.Core.ScriptingProviders; namespace Artemis.Core.Services { /// - /// A service that allows you to manage various types of instances + /// A service that allows you to manage various types of instances /// public interface IScriptingService : IArtemisService { diff --git a/src/Artemis.Core/Services/NodeService.cs b/src/Artemis.Core/Services/NodeService.cs new file mode 100644 index 000000000..faeb4bf89 --- /dev/null +++ b/src/Artemis.Core/Services/NodeService.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Ninject; + +namespace Artemis.Core.Services +{ + internal class NodeService : INodeService + { + private readonly IKernel _kernel; + + #region Constants + + private static readonly Type TYPE_NODE = typeof(INode); + + #endregion + + #region Properties & Fields + + public IEnumerable AvailableNodes => NodeTypeStore.GetAll(); + + #endregion + + #region Constructors + + public NodeService(IKernel kernel) + { + _kernel = kernel; + } + + #endregion + + #region Methods + + public NodeTypeRegistration RegisterNodeType(Plugin plugin, Type nodeType) + { + if (plugin == null) throw new ArgumentNullException(nameof(plugin)); + if (nodeType == null) throw new ArgumentNullException(nameof(nodeType)); + + if (!TYPE_NODE.IsAssignableFrom(nodeType)) throw new ArgumentException("Node has to be a base type of the Node-Type.", nameof(nodeType)); + + NodeAttribute? nodeAttribute = nodeType.GetCustomAttribute(); + string name = nodeAttribute?.Name ?? nodeType.Name; + string description = nodeAttribute?.Description ?? string.Empty; + string category = nodeAttribute?.Category ?? string.Empty; + + NodeData nodeData = new(plugin, nodeType, name, description, category, () => CreateNode(nodeType)); + return NodeTypeStore.Add(nodeData); + } + + private INode CreateNode(Type nodeType) + { + INode node = _kernel.Get(nodeType) as INode ?? throw new InvalidOperationException($"Node {nodeType} is not an INode"); + if (node.CustomViewModelType != null) + node.CustomViewModel = _kernel.Get(node.CustomViewModelType); + return node; + } + + #endregion + } + + /// + /// A service that provides access to the node system + /// + public interface INodeService : IArtemisService + { + /// + /// Gets all available nodes + /// + IEnumerable AvailableNodes { get; } + + /// + /// Initializes a node of the provided + /// + /// The plugin the node belongs to + /// The type of node to initialize + NodeTypeRegistration RegisterNodeType(Plugin plugin, Type nodeType); + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Stores/NodeTypeStore.cs b/src/Artemis.Core/Stores/NodeTypeStore.cs new file mode 100644 index 000000000..2a4b84dd9 --- /dev/null +++ b/src/Artemis.Core/Stores/NodeTypeStore.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Artemis.Core +{ + internal class NodeTypeStore + { + private static readonly List Registrations = new(); + + public static NodeTypeRegistration Add(NodeData nodeData) + { + if (nodeData.Plugin == null) + throw new ArtemisCoreException("Cannot add a data binding modifier type that is not associated with a plugin"); + + NodeTypeRegistration typeRegistration; + lock (Registrations) + { + if (Registrations.Any(r => r.NodeData == nodeData)) + throw new ArtemisCoreException($"Data binding modifier type store already contains modifier '{nodeData.Name}'"); + + typeRegistration = new NodeTypeRegistration(nodeData, nodeData.Plugin) { IsInStore = true }; + Registrations.Add(typeRegistration); + } + + OnDataBindingModifierAdded(new NodeTypeStoreEvent(typeRegistration)); + return typeRegistration; + } + + public static void Remove(NodeTypeRegistration typeRegistration) + { + lock (Registrations) + { + if (!Registrations.Contains(typeRegistration)) + throw new ArtemisCoreException($"Data binding modifier type store does not contain modifier type '{typeRegistration.NodeData.Name}'"); + + Registrations.Remove(typeRegistration); + typeRegistration.IsInStore = false; + } + + OnDataBindingModifierRemoved(new NodeTypeStoreEvent(typeRegistration)); + } + + public static IEnumerable GetAll() + { + lock (Registrations) + { + return Registrations.Select(r => r.NodeData).ToList(); + } + } + + public static NodeTypeRegistration? Get(Guid pluginGuid, string type) + { + lock (Registrations) + { + return Registrations.FirstOrDefault(r => r.Plugin.Guid == pluginGuid && r.NodeData.Type.Name == type); + } + } + + #region Events + + public static event EventHandler? DataBindingModifierAdded; + public static event EventHandler? DataBindingModifierRemoved; + + private static void OnDataBindingModifierAdded(NodeTypeStoreEvent e) + { + DataBindingModifierAdded?.Invoke(null, e); + } + + private static void OnDataBindingModifierRemoved(NodeTypeStoreEvent e) + { + DataBindingModifierRemoved?.Invoke(null, e); + } + + #endregion + } +} diff --git a/src/Artemis.Core/Stores/Registrations/NodeTypeRegistration.cs b/src/Artemis.Core/Stores/Registrations/NodeTypeRegistration.cs new file mode 100644 index 000000000..a9b8e4873 --- /dev/null +++ b/src/Artemis.Core/Stores/Registrations/NodeTypeRegistration.cs @@ -0,0 +1,37 @@ +using System; + +namespace Artemis.Core +{ + /// + /// Represents a registration for a type of + /// + public class NodeTypeRegistration + { + internal NodeTypeRegistration(NodeData nodeData, Plugin plugin) + { + NodeData = nodeData; + Plugin = plugin; + + Plugin.Disabled += OnDisabled; + } + + public NodeData NodeData { get; } + + /// + /// Gets the plugin the node is associated with + /// + public Plugin Plugin { get; } + + /// + /// Gets a boolean indicating whether the registration is in the internal Core store + /// + public bool IsInStore { get; internal set; } + + private void OnDisabled(object? sender, EventArgs e) + { + Plugin.Disabled -= OnDisabled; + if (IsInStore) + NodeTypeStore.Remove(this); + } + } +} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Model/InputPin.cs b/src/Artemis.Core/VisualScripting/InputPin.cs similarity index 96% rename from src/Artemis.VisualScripting/Model/InputPin.cs rename to src/Artemis.Core/VisualScripting/InputPin.cs index 80ea27b8b..96309db07 100644 --- a/src/Artemis.VisualScripting/Model/InputPin.cs +++ b/src/Artemis.Core/VisualScripting/InputPin.cs @@ -1,7 +1,6 @@ using System; -using Artemis.Core.VisualScripting; -namespace Artemis.VisualScripting.Model +namespace Artemis.Core { public sealed class InputPin : Pin { diff --git a/src/Artemis.VisualScripting/Model/InputPinCollection.cs b/src/Artemis.Core/VisualScripting/InputPinCollection.cs similarity index 91% rename from src/Artemis.VisualScripting/Model/InputPinCollection.cs rename to src/Artemis.Core/VisualScripting/InputPinCollection.cs index bd0a9704d..93a474e19 100644 --- a/src/Artemis.VisualScripting/Model/InputPinCollection.cs +++ b/src/Artemis.Core/VisualScripting/InputPinCollection.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; -using Artemis.Core.VisualScripting; -namespace Artemis.VisualScripting.Model +namespace Artemis.Core { public sealed class InputPinCollection : PinCollection { diff --git a/src/Artemis.Core/VisualScripting/INode.cs b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs similarity index 76% rename from src/Artemis.Core/VisualScripting/INode.cs rename to src/Artemis.Core/VisualScripting/Interfaces/INode.cs index d304f179e..49dee4ab1 100644 --- a/src/Artemis.Core/VisualScripting/INode.cs +++ b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs @@ -2,12 +2,13 @@ using System.Collections.Generic; using System.ComponentModel; -namespace Artemis.Core.VisualScripting +namespace Artemis.Core { public interface INode : INotifyPropertyChanged { string Name { get; } string Description { get; } + bool IsExitNode { get; } public double X { get; set; } public double Y { get; set; } @@ -15,8 +16,8 @@ namespace Artemis.Core.VisualScripting public IReadOnlyCollection Pins { get; } public IReadOnlyCollection PinCollections { get; } - public object CustomView { get; } - public object CustomViewModel { get; } + public Type? CustomViewModelType { get; } + public object? CustomViewModel { get; set; } event EventHandler Resetting; diff --git a/src/Artemis.Core/VisualScripting/IScript.cs b/src/Artemis.Core/VisualScripting/Interfaces/INodeScript.cs similarity index 70% rename from src/Artemis.Core/VisualScripting/IScript.cs rename to src/Artemis.Core/VisualScripting/Interfaces/INodeScript.cs index abcc13516..abfa87b75 100644 --- a/src/Artemis.Core/VisualScripting/IScript.cs +++ b/src/Artemis.Core/VisualScripting/Interfaces/INodeScript.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.ComponentModel; -namespace Artemis.Core.VisualScripting +namespace Artemis.Core { - public interface IScript : INotifyPropertyChanged, IDisposable + public interface INodeScript : INotifyPropertyChanged, IDisposable { string Name { get; } string Description { get; } @@ -18,7 +18,7 @@ namespace Artemis.Core.VisualScripting void RemoveNode(INode node); } - public interface IScript : IScript + public interface INodeScript : INodeScript { T Result { get; } } diff --git a/src/Artemis.Core/VisualScripting/IPin.cs b/src/Artemis.Core/VisualScripting/Interfaces/IPin.cs similarity index 84% rename from src/Artemis.Core/VisualScripting/IPin.cs rename to src/Artemis.Core/VisualScripting/Interfaces/IPin.cs index 69c11ed2c..aef3352cf 100644 --- a/src/Artemis.Core/VisualScripting/IPin.cs +++ b/src/Artemis.Core/VisualScripting/Interfaces/IPin.cs @@ -1,8 +1,7 @@ using System; using System.Collections.Generic; -using Artemis.VisualScripting.Model; -namespace Artemis.Core.VisualScripting +namespace Artemis.Core { public interface IPin { diff --git a/src/Artemis.Core/VisualScripting/IPinCollection.cs b/src/Artemis.Core/VisualScripting/Interfaces/IPinCollection.cs similarity index 78% rename from src/Artemis.Core/VisualScripting/IPinCollection.cs rename to src/Artemis.Core/VisualScripting/Interfaces/IPinCollection.cs index d9c2a1b33..410f269ba 100644 --- a/src/Artemis.Core/VisualScripting/IPinCollection.cs +++ b/src/Artemis.Core/VisualScripting/Interfaces/IPinCollection.cs @@ -1,8 +1,7 @@ using System; using System.Collections.Generic; -using Artemis.VisualScripting.Model; -namespace Artemis.Core.VisualScripting +namespace Artemis.Core { public interface IPinCollection : IEnumerable { diff --git a/src/Artemis.VisualScripting/Internal/ExitNode.cs b/src/Artemis.Core/VisualScripting/Internal/ExitNode.cs similarity index 84% rename from src/Artemis.VisualScripting/Internal/ExitNode.cs rename to src/Artemis.Core/VisualScripting/Internal/ExitNode.cs index 25bad56ff..62c5ebe41 100644 --- a/src/Artemis.VisualScripting/Internal/ExitNode.cs +++ b/src/Artemis.Core/VisualScripting/Internal/ExitNode.cs @@ -1,7 +1,4 @@ -using Artemis.Core.VisualScripting; -using Artemis.VisualScripting.Model; - -namespace Artemis.VisualScripting.Internal +namespace Artemis.Core.Internal { internal interface IExitNode : INode { } @@ -14,6 +11,8 @@ namespace Artemis.VisualScripting.Internal public T Value { get; private set; } + public override bool IsExitNode => true; + #endregion #region Constructors diff --git a/src/Artemis.VisualScripting/Model/Node.cs b/src/Artemis.Core/VisualScripting/Node.cs similarity index 82% rename from src/Artemis.VisualScripting/Model/Node.cs rename to src/Artemis.Core/VisualScripting/Node.cs index 497bfa4b6..877cf82a7 100644 --- a/src/Artemis.VisualScripting/Model/Node.cs +++ b/src/Artemis.Core/VisualScripting/Node.cs @@ -1,52 +1,55 @@ 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 +namespace Artemis.Core { - public abstract class Node : AbstractBindable, INode + public abstract class Node : CorePropertyChanged, INode { #region Properties & Fields private string _name; + public string Name { get => _name; - protected set => SetProperty(ref _name, value); + protected set => SetAndNotify(ref _name, value); } private string _description; + public string Description { get => _description; - protected set => SetProperty(ref _description, value); + protected set => SetAndNotify(ref _description, value); } private double _x; + public double X { get => _x; - set => SetProperty(ref _x, value); + set => SetAndNotify(ref _x, value); } private double _y; + public double Y { get => _y; - set => SetProperty(ref _y, value); + set => SetAndNotify(ref _y, value); } + public virtual bool IsExitNode => false; + private readonly List _pins = new(); public IReadOnlyCollection Pins => new ReadOnlyCollection(_pins); private readonly List _pinCollections = new(); public IReadOnlyCollection PinCollections => new ReadOnlyCollection(_pinCollections); - public object CustomView { get; private set; } - public object CustomViewModel { get; private set; } + public Type? CustomViewModelType { get; private set; } + public object? CustomViewModel { get; set; } #endregion @@ -59,7 +62,8 @@ namespace Artemis.VisualScripting.Model #region Construtors protected Node() - { } + { + } protected Node(string name, string description) { @@ -111,6 +115,7 @@ namespace Artemis.VisualScripting.Model pin.DisconnectAll(); OnPropertyChanged(nameof(Pins)); } + return isRemoved; } @@ -130,10 +135,9 @@ namespace Artemis.VisualScripting.Model return pin; } - protected void RegisterCustomView(DataTemplate view, object viewModel) + protected void RegisterCustomViewModel() { - CustomView = view; - CustomViewModel = viewModel; + CustomViewModelType = typeof(T); } public abstract void Evaluate(); @@ -145,4 +149,4 @@ namespace Artemis.VisualScripting.Model #endregion } -} +} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Attributes/UIAttribute.cs b/src/Artemis.Core/VisualScripting/NodeAttribute.cs similarity index 67% rename from src/Artemis.VisualScripting/Attributes/UIAttribute.cs rename to src/Artemis.Core/VisualScripting/NodeAttribute.cs index 86421c9d4..ffa408667 100644 --- a/src/Artemis.VisualScripting/Attributes/UIAttribute.cs +++ b/src/Artemis.Core/VisualScripting/NodeAttribute.cs @@ -1,8 +1,8 @@ using System; -namespace Artemis.VisualScripting.Attributes +namespace Artemis.Core { - public class UIAttribute : Attribute + public class NodeAttribute : Attribute { #region Properties & Fields @@ -14,18 +14,18 @@ namespace Artemis.VisualScripting.Attributes #region Constructors - public UIAttribute(string name) + public NodeAttribute(string name) { this.Name = name; } - public UIAttribute(string name, string description) + public NodeAttribute(string name, string description) { this.Name = name; this.Description = description; } - public UIAttribute(string name, string description, string category) + public NodeAttribute(string name, string description, string category) { this.Name = name; this.Description = description; diff --git a/src/Artemis.VisualScripting/Model/NodeData.cs b/src/Artemis.Core/VisualScripting/NodeData.cs similarity index 74% rename from src/Artemis.VisualScripting/Model/NodeData.cs rename to src/Artemis.Core/VisualScripting/NodeData.cs index ab1177138..d08c155dd 100644 --- a/src/Artemis.VisualScripting/Model/NodeData.cs +++ b/src/Artemis.Core/VisualScripting/NodeData.cs @@ -1,25 +1,27 @@ using System; -using Artemis.Core.VisualScripting; -namespace Artemis.VisualScripting.Model +namespace Artemis.Core { public class NodeData { #region Properties & Fields + public Plugin Plugin { get; } + public Type Type { get; } public string Name { get; } public string Description { get; } public string Category { get; } - + private Func _create; #endregion #region Constructors - public NodeData(Type type, string name, string description, string category, Func create) + internal NodeData(Plugin plugin, Type type, string name, string description, string category, Func create) { + this.Plugin = plugin; this.Type = type; this.Name = name; this.Description = description; diff --git a/src/Artemis.VisualScripting/Model/Script.cs b/src/Artemis.Core/VisualScripting/NodeScript.cs similarity index 77% rename from src/Artemis.VisualScripting/Model/Script.cs rename to src/Artemis.Core/VisualScripting/NodeScript.cs index 8a9ac837e..bccb384f0 100644 --- a/src/Artemis.VisualScripting/Model/Script.cs +++ b/src/Artemis.Core/VisualScripting/NodeScript.cs @@ -1,14 +1,12 @@ 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; +using Artemis.Core.Internal; +using Artemis.Core.Properties; -namespace Artemis.VisualScripting.Model +namespace Artemis.Core { - public abstract class Script : AbstractBindable, IScript + public abstract class NodeScript : CorePropertyChanged, INodeScript { #region Properties & Fields @@ -25,7 +23,7 @@ namespace Artemis.VisualScripting.Model #region Constructors - public Script(string name, string description) + public NodeScript(string name, string description) { this.Name = name; this.Description = description; @@ -59,7 +57,7 @@ namespace Artemis.VisualScripting.Model #endregion } - public class Script : Script, IScript + public class NodeScript : NodeScript, INodeScript { #region Properties & Fields @@ -71,7 +69,7 @@ namespace Artemis.VisualScripting.Model #region Constructors - public Script(string name, string description) + public NodeScript(string name, string description) : base(name, description) { ExitNode = new ExitNode(name, description); @@ -79,7 +77,7 @@ namespace Artemis.VisualScripting.Model } [UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)] - private Script(string name, string description, INode exitNode) + private NodeScript(string name, string description, INode exitNode) : base(name, description) { ExitNode = exitNode; diff --git a/src/Artemis.VisualScripting/Model/OutputPin.cs b/src/Artemis.Core/VisualScripting/OutputPin.cs similarity index 95% rename from src/Artemis.VisualScripting/Model/OutputPin.cs rename to src/Artemis.Core/VisualScripting/OutputPin.cs index 5cd238f80..e52a21d0e 100644 --- a/src/Artemis.VisualScripting/Model/OutputPin.cs +++ b/src/Artemis.Core/VisualScripting/OutputPin.cs @@ -1,7 +1,6 @@ using System; -using Artemis.Core.VisualScripting; -namespace Artemis.VisualScripting.Model +namespace Artemis.Core { public sealed class OutputPin : Pin { diff --git a/src/Artemis.VisualScripting/Model/OutputPinCollection.cs b/src/Artemis.Core/VisualScripting/OutputPinCollection.cs similarity index 88% rename from src/Artemis.VisualScripting/Model/OutputPinCollection.cs rename to src/Artemis.Core/VisualScripting/OutputPinCollection.cs index 4b2e57c37..2f371b80a 100644 --- a/src/Artemis.VisualScripting/Model/OutputPinCollection.cs +++ b/src/Artemis.Core/VisualScripting/OutputPinCollection.cs @@ -1,7 +1,6 @@ using System; -using Artemis.Core.VisualScripting; -namespace Artemis.VisualScripting.Model +namespace Artemis.Core { public sealed class OutputPinCollection : PinCollection { diff --git a/src/Artemis.VisualScripting/Model/Pin.cs b/src/Artemis.Core/VisualScripting/Pin.cs similarity index 87% rename from src/Artemis.VisualScripting/Model/Pin.cs rename to src/Artemis.Core/VisualScripting/Pin.cs index 7a1368a57..c1192b53c 100644 --- a/src/Artemis.VisualScripting/Model/Pin.cs +++ b/src/Artemis.Core/VisualScripting/Pin.cs @@ -1,12 +1,10 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using Artemis.Core.VisualScripting; -using Artemis.VisualScripting.ViewModel; -namespace Artemis.VisualScripting.Model +namespace Artemis.Core { - public abstract class Pin : AbstractBindable, IPin + public abstract class Pin : CorePropertyChanged, IPin { #region Properties & Fields @@ -17,7 +15,7 @@ namespace Artemis.VisualScripting.Model public bool IsEvaluated { get => _isEvaluated; - set => SetProperty(ref _isEvaluated, value); + set => SetAndNotify(ref _isEvaluated, value); } private readonly List _connectedTo = new(); diff --git a/src/Artemis.VisualScripting/Model/PinCollection.cs b/src/Artemis.Core/VisualScripting/PinCollection.cs similarity index 94% rename from src/Artemis.VisualScripting/Model/PinCollection.cs rename to src/Artemis.Core/VisualScripting/PinCollection.cs index cd1e606a7..469abf5dc 100644 --- a/src/Artemis.VisualScripting/Model/PinCollection.cs +++ b/src/Artemis.Core/VisualScripting/PinCollection.cs @@ -2,9 +2,8 @@ using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; -using Artemis.Core.VisualScripting; -namespace Artemis.VisualScripting.Model +namespace Artemis.Core { public abstract class PinCollection : IPinCollection { diff --git a/src/Artemis.Core/VisualScripting/PinDirection.cs b/src/Artemis.Core/VisualScripting/PinDirection.cs index cc4b8500b..1ca6b332a 100644 --- a/src/Artemis.Core/VisualScripting/PinDirection.cs +++ b/src/Artemis.Core/VisualScripting/PinDirection.cs @@ -1,4 +1,4 @@ -namespace Artemis.VisualScripting.Model +namespace Artemis.Core { public enum PinDirection { diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs index 472c38dc1..577a7a36c 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionsViewModel.cs @@ -2,12 +2,11 @@ using System.Collections.Generic; using System.ComponentModel; using Artemis.Core; +using Artemis.Core.Services; using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.ProfileEditor.Conditions; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; -using Artemis.VisualScripting.Model; -using Artemis.VisualScripting.Services; using Stylet; namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions @@ -16,33 +15,24 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions { private readonly IDataModelConditionsVmFactory _dataModelConditionsVmFactory; private readonly IProfileEditorService _profileEditorService; + private readonly INodeService _nodeService; private RenderProfileElement _renderProfileElement; private bool _displayStartHint; private bool _isEventCondition; - public DisplayConditionsViewModel(IProfileEditorService profileEditorService, IDataModelConditionsVmFactory dataModelConditionsVmFactory) + public DisplayConditionsViewModel(IProfileEditorService profileEditorService, INodeService nodeService, IDataModelConditionsVmFactory dataModelConditionsVmFactory) { _profileEditorService = profileEditorService; + _nodeService = nodeService; _dataModelConditionsVmFactory = dataModelConditionsVmFactory; AvailableNodes = _nodeService.AvailableNodes; - Script = new Script("Display Condition (TODO)", "TODO"); + Script = new NodeScript("Display Condition (TODO)", "TODO"); } - #region TODO - private static NodeService _nodeService; - - static DisplayConditionsViewModel() - { - _nodeService = new NodeService(); - _nodeService.InitializeNodes(); - } - - #endregion - - private Script _script; - public Script Script + private NodeScript _script; + public NodeScript Script { get => _script; private set => SetAndNotify(ref _script, value); @@ -161,7 +151,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions // renderProfileElement.DisplayCondition = new DataModelConditionGroup(null); if (renderProfileElement.DisplayCondition == null) - renderProfileElement.DisplayCondition = new Script("Display Condition (TODO)", "-"); + renderProfileElement.DisplayCondition = new NodeScript("Display Condition (TODO)", "-"); //List modules = new(); //if (_profileEditorService.SelectedProfileConfiguration?.Module != null) diff --git a/src/Artemis.UI/Screens/RootViewModel.cs b/src/Artemis.UI/Screens/RootViewModel.cs index b4b3aaf2f..b5edea137 100644 --- a/src/Artemis.UI/Screens/RootViewModel.cs +++ b/src/Artemis.UI/Screens/RootViewModel.cs @@ -172,6 +172,7 @@ namespace Artemis.UI.Screens _builtInRegistrationService.RegisterBuiltInDataModelDisplays(); _builtInRegistrationService.RegisterBuiltInDataModelInputs(); _builtInRegistrationService.RegisterBuiltInPropertyEditors(); + _builtInRegistrationService.RegisterBuiltInNodeTypes(); _window = (MaterialWindow) View; diff --git a/src/Artemis.UI/Services/RegistrationService.cs b/src/Artemis.UI/Services/RegistrationService.cs index 563908898..ec5633647 100644 --- a/src/Artemis.UI/Services/RegistrationService.cs +++ b/src/Artemis.UI/Services/RegistrationService.cs @@ -10,6 +10,7 @@ using Artemis.UI.Ninject; using Artemis.UI.Providers; using Artemis.UI.Shared.Services; using Artemis.UI.SkiaSharp; +using Artemis.VisualScripting.Nodes; using Serilog; namespace Artemis.UI.Services @@ -25,6 +26,7 @@ namespace Artemis.UI.Services private readonly IMessageService _messageService; private readonly IWebServerService _webServerService; private readonly IRgbService _rgbService; + private readonly INodeService _nodeService; private readonly ISettingsService _settingsService; private bool _registeredBuiltInDataModelDisplays; private bool _registeredBuiltInDataModelInputs; @@ -40,6 +42,7 @@ namespace Artemis.UI.Services IMessageService messageService, IWebServerService webServerService, IRgbService rgbService, + INodeService nodeService, ISettingsService settingsService) { _logger = logger; @@ -51,6 +54,7 @@ namespace Artemis.UI.Services _messageService = messageService; _webServerService = webServerService; _rgbService = rgbService; + _nodeService = nodeService; _settingsService = settingsService; LoadPluginModules(); @@ -113,6 +117,12 @@ namespace Artemis.UI.Services _webServerService.AddController(Constants.CorePlugin.Features.First().Instance!); } + public void RegisterBuiltInNodeTypes() + { + foreach (Type nodeType in typeof(SumIntegersNode).Assembly.GetTypes().Where(t => typeof(INode).IsAssignableFrom(t) && t.IsPublic && !t.IsAbstract && !t.IsInterface)) + _nodeService.RegisterNodeType(Constants.CorePlugin, nodeType); + } + /// public void ApplyPreferredGraphicsContext() { @@ -167,5 +177,6 @@ namespace Artemis.UI.Services void RegisterProviders(); void RegisterControllers(); void ApplyPreferredGraphicsContext(); + void RegisterBuiltInNodeTypes(); } } \ No newline at end of file diff --git a/src/Artemis.UI/packages.lock.json b/src/Artemis.UI/packages.lock.json index 88c76e6f1..cab03eb16 100644 --- a/src/Artemis.UI/packages.lock.json +++ b/src/Artemis.UI/packages.lock.json @@ -1482,7 +1482,8 @@ "type": "Project", "dependencies": { "Artemis.Core": "1.0.0", - "JetBrains.Annotations": "2021.1.0" + "JetBrains.Annotations": "2021.1.0", + "Stylet": "1.3.6" } } } diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index 86031c078..44e4e5ba7 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -37,6 +37,7 @@ + diff --git a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptEditor.cs b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptEditor.cs index dad4ef715..82977bcf5 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptEditor.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptEditor.cs @@ -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); } diff --git a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptNodeCreationBox.cs b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptNodeCreationBox.cs index 6019a7811..496da874c 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptNodeCreationBox.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptNodeCreationBox.cs @@ -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 { diff --git a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptPinPresenter.cs b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptPinPresenter.cs index 60cfe6f38..76c15b45c 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptPinPresenter.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptPinPresenter.cs @@ -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 { diff --git a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptPresenter.cs b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptPresenter.cs index 7da76fc75..f9e37b791 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/VisualScriptPresenter.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/VisualScriptPresenter.cs @@ -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) diff --git a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScript.cs b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScript.cs index 3645e79b0..fa5ea0bd9 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScript.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScript.cs @@ -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; diff --git a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptCable.cs b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptCable.cs index d3e939b32..447718406 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptCable.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptCable.cs @@ -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 diff --git a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptNode.cs b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptNode.cs index 5c499eeec..b69f56a01 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptNode.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptNode.cs @@ -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 } diff --git a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptPin.cs b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptPin.cs index 793b9a6ec..933d8125e 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptPin.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptPin.cs @@ -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 diff --git a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptPinCollection.cs b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptPinCollection.cs index 80aaa60f2..761542452 100644 --- a/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptPinCollection.cs +++ b/src/Artemis.VisualScripting/Editor/Controls/Wrapper/VisualScriptPinCollection.cs @@ -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 diff --git a/src/Artemis.VisualScripting/Editor/EditorStyles.xaml b/src/Artemis.VisualScripting/Editor/EditorStyles.xaml index 743c4dead..0ddf8a63b 100644 --- a/src/Artemis.VisualScripting/Editor/EditorStyles.xaml +++ b/src/Artemis.VisualScripting/Editor/EditorStyles.xaml @@ -6,8 +6,5 @@ - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Editor/Styles/VisualScriptNodeCreationBox.xaml b/src/Artemis.VisualScripting/Editor/Styles/VisualScriptNodeCreationBox.xaml index 454a7376b..7b5a11b17 100644 --- a/src/Artemis.VisualScripting/Editor/Styles/VisualScriptNodeCreationBox.xaml +++ b/src/Artemis.VisualScripting/Editor/Styles/VisualScriptNodeCreationBox.xaml @@ -1,10 +1,10 @@  + xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core"> + DataType="{x:Type core:NodeData}"> diff --git a/src/Artemis.VisualScripting/Editor/Styles/VisualScriptNodePresenter.xaml b/src/Artemis.VisualScripting/Editor/Styles/VisualScriptNodePresenter.xaml index 53591e89a..f5f500011 100644 --- a/src/Artemis.VisualScripting/Editor/Styles/VisualScriptNodePresenter.xaml +++ b/src/Artemis.VisualScripting/Editor/Styles/VisualScriptNodePresenter.xaml @@ -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">