diff --git a/src/Artemis.Core/Plugins/Modules/DataModel.cs b/src/Artemis.Core/Plugins/Modules/DataModel.cs
index 2fabac52f..880fffc4a 100644
--- a/src/Artemis.Core/Plugins/Modules/DataModel.cs
+++ b/src/Artemis.Core/Plugins/Modules/DataModel.cs
@@ -345,8 +345,8 @@ public abstract class DataModel
{
lock (_activePaths)
{
- if (_activePaths.Contains(path))
- return;
+ if (_activePaths.Any(p => ReferenceEquals(p, path)))
+ throw new ArtemisCoreException("Path already present on this data model, initialization done twice?");
_activePaths.Add(path);
diff --git a/src/Artemis.Core/Services/NodeService.cs b/src/Artemis.Core/Services/NodeService.cs
index 867fe8cb3..5ebe8cc80 100644
--- a/src/Artemis.Core/Services/NodeService.cs
+++ b/src/Artemis.Core/Services/NodeService.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
@@ -37,6 +38,12 @@ internal class NodeService : INodeService
#region Methods
+ ///
+ public List GetRegisteredTypes()
+ {
+ return NodeTypeStore.GetColors().Select(c => c.Type).Distinct().ToList();
+ }
+
///
public TypeColorRegistration GetTypeColorRegistration(Type type)
{
@@ -132,6 +139,12 @@ public interface INodeService : IArtemisService
///
IEnumerable AvailableNodes { get; }
+ ///
+ /// Gets all currently available node pin types.
+ ///
+ /// A of containing the currently available node pin types.
+ List GetRegisteredTypes();
+
///
/// Gets the best matching registration for the provided type
///
diff --git a/src/Artemis.Core/Stores/NodeTypeStore.cs b/src/Artemis.Core/Stores/NodeTypeStore.cs
index fb96f2794..052cac84c 100644
--- a/src/Artemis.Core/Stores/NodeTypeStore.cs
+++ b/src/Artemis.Core/Stores/NodeTypeStore.cs
@@ -96,6 +96,14 @@ internal class NodeTypeStore
}
}
+ public static List GetColors()
+ {
+ lock (ColorRegistrations)
+ {
+ return new List(ColorRegistrations);
+ }
+ }
+
public static TypeColorRegistration? GetColor(Type type)
{
lock (ColorRegistrations)
diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs
index eae701ef3..a0f9586dc 100644
--- a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs
+++ b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs
@@ -48,7 +48,12 @@ public class DataModelDebugViewModel : ActivatableViewModelBase
GetDataModel();
_updateTimer.Start();
- Disposable.Create(() => _updateTimer.Stop()).DisposeWith(disposables);
+ Disposable.Create(() =>
+ {
+ _updateTimer.Stop();
+ MainDataModel?.Dispose();
+ MainDataModel = null;
+ }).DisposeWith(disposables);
});
}
diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventNode.cs b/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventNode.cs
index c38af35c2..054977e8b 100644
--- a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventNode.cs
+++ b/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventNode.cs
@@ -14,7 +14,12 @@ public class DataModelEventNode : Node, OutputPin> _propertyPins;
private DataModelPath? _dataModelPath;
private IDataModelEvent? _dataModelEvent;
-
+ private OutputPin? _oldValuePin;
+ private OutputPin? _newValuePin;
+ private DateTime _lastTrigger;
+ private object? _lastValue;
+ private int _valueChangeCount;
+
public DataModelEventNode() : base("Data Model-Event", "Outputs the latest values of a data model event.")
{
_propertyPins = new Dictionary, OutputPin>();
@@ -43,18 +48,40 @@ public class DataModelEventNode : Node propertyAccessor, OutputPin outputPin) in _propertyPins)
+ // If the path is a data model event, evaluate the event
+ if (pathValue is IDataModelEvent dataModelEvent)
{
- if (!outputPin.ConnectedTo.Any())
- continue;
- object value = dataModelEvent.LastEventArgumentsUntyped != null ? propertyAccessor(dataModelEvent.LastEventArgumentsUntyped) : outputPin.Type.GetDefault()!;
- outputPin.Value = outputPin.IsNumeric ? new Numeric(value) : value;
+ TimeSinceLastTrigger.Value = dataModelEvent.TimeSinceLastTrigger.TotalMilliseconds;
+ TriggerCount.Value = dataModelEvent.TriggerCount;
+
+ foreach ((Func propertyAccessor, OutputPin outputPin) in _propertyPins)
+ {
+ if (!outputPin.ConnectedTo.Any())
+ continue;
+ object value = dataModelEvent.LastEventArgumentsUntyped != null ? propertyAccessor(dataModelEvent.LastEventArgumentsUntyped) : outputPin.Type.GetDefault()!;
+ outputPin.Value = outputPin.IsNumeric ? new Numeric(value) : value;
+ }
+ }
+ // If the path is a regular value, evaluate the current value
+ else if (_oldValuePin != null && _newValuePin != null)
+ {
+ if (Equals(_lastValue, pathValue))
+ {
+ TimeSinceLastTrigger.Value = (DateTime.Now - _lastTrigger).TotalMilliseconds;
+ return;
+ }
+
+ _valueChangeCount++;
+ _lastTrigger = DateTime.Now;
+
+ _oldValuePin.Value = _lastValue;
+ _newValuePin.Value = pathValue;
+
+ _lastValue = pathValue;
+
+ TimeSinceLastTrigger.Value = 0;
+ TriggerCount.Value = _valueChangeCount;
}
}
@@ -78,23 +105,18 @@ public class DataModelEventNode : Node pins = Pins.Skip(2).ToList();
- while (pins.Any())
- RemovePin((Pin) pins.First());
- _propertyPins.Clear();
-
+
+ ClearPins();
_dataModelEvent = dataModelEvent;
- if (dataModelEvent == null)
- return;
-
foreach (PropertyInfo propertyInfo in dataModelEvent.ArgumentsType.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CustomAttributes.All(a => a.AttributeType != typeof(DataModelIgnoreAttribute))))
{
@@ -112,6 +134,31 @@ public class DataModelEventNode : Node pins = Pins.Skip(2).ToList();
+ foreach (IPin pin in pins)
+ RemovePin((Pin) pin);
+
+ _propertyPins.Clear();
+ _oldValuePin = null;
+ _newValuePin = null;
+ }
private void DataModelPathOnPathValidated(object? sender, EventArgs e)
{
diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml
index 5f988e54a..a73713e3c 100644
--- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml
+++ b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml
@@ -12,7 +12,7 @@
Modules="{CompiledBinding Modules}"
ShowDataModelValues="{CompiledBinding ShowDataModelValues.Value}"
ShowFullPath="{CompiledBinding ShowFullPaths.Value}"
- FilterTypes="{CompiledBinding FilterTypes}"
+ FilterTypes="{CompiledBinding NodePinTypes}"
IsEventPicker="True"
VerticalAlignment="Top"
MaxWidth="300"/>
diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomViewModel.cs
index c3ec5b539..9fe7d1058 100644
--- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomViewModel.cs
+++ b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomViewModel.cs
@@ -19,7 +19,8 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
private ObservableCollection? _modules;
private bool _updating;
- public DataModelEventNodeCustomViewModel(DataModelEventNode node, INodeScript script, ISettingsService settingsService, INodeEditorService nodeEditorService) : base(node, script)
+ public DataModelEventNodeCustomViewModel(DataModelEventNode node, INodeScript script, ISettingsService settingsService, INodeEditorService nodeEditorService, INodeService nodeService)
+ : base(node, script)
{
_node = node;
_nodeEditorService = nodeEditorService;
@@ -28,6 +29,11 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
Modules = new ObservableCollection();
+ List nodePinTypes = nodeService.GetRegisteredTypes();
+ nodePinTypes.AddRange(Constants.NumberTypes);
+ nodePinTypes.Add(typeof(IDataModelEvent));
+ NodePinTypes = new ObservableCollection(nodePinTypes);
+
this.WhenActivated(d =>
{
// Set up extra modules
@@ -50,6 +56,7 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
public PluginSetting ShowFullPaths { get; }
public PluginSetting ShowDataModelValues { get; }
+ public ObservableCollection NodePinTypes { get; }
public ObservableCollection? Modules
{
@@ -63,8 +70,6 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
set => this.RaiseAndSetIfChanged(ref _dataModelPath, value);
}
- public List FilterTypes => new() {typeof(IDataModelEvent)};
-
private void UpdateDataModelPath(DataModelPathEntity? entity)
{
try
diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml
index 376e79962..cef80d0ae 100644
--- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml
+++ b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml
@@ -12,5 +12,6 @@
Modules="{CompiledBinding Modules}"
ShowDataModelValues="{CompiledBinding ShowDataModelValues.Value}"
ShowFullPath="{CompiledBinding ShowFullPaths.Value}"
+ FilterTypes="{CompiledBinding NodePinTypes}"
MaxWidth="300"/>
\ No newline at end of file
diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomViewModel.cs
index af5f1ffe2..55b4d6dd2 100644
--- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomViewModel.cs
+++ b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomViewModel.cs
@@ -19,7 +19,7 @@ public class DataModelNodeCustomViewModel : CustomNodeViewModel
private ObservableCollection? _modules;
private bool _updating;
- public DataModelNodeCustomViewModel(DataModelNode node, INodeScript script, ISettingsService settingsService, INodeEditorService nodeEditorService) : base(node, script)
+ public DataModelNodeCustomViewModel(DataModelNode node, INodeScript script, ISettingsService settingsService, INodeEditorService nodeEditorService, INodeService nodeService) : base(node, script)
{
_node = node;
_nodeEditorService = nodeEditorService;
@@ -27,6 +27,10 @@ public class DataModelNodeCustomViewModel : CustomNodeViewModel
ShowFullPaths = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true);
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
+ List nodePinTypes = nodeService.GetRegisteredTypes();
+ nodePinTypes.AddRange(Constants.NumberTypes);
+ NodePinTypes = new ObservableCollection(nodePinTypes);
+
this.WhenActivated(d =>
{
// Set up extra modules
@@ -49,7 +53,8 @@ public class DataModelNodeCustomViewModel : CustomNodeViewModel
public PluginSetting ShowFullPaths { get; }
public PluginSetting ShowDataModelValues { get; }
-
+ public ObservableCollection NodePinTypes { get; }
+
public ObservableCollection? Modules
{
get => _modules;