mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Merge branch 'development'
This commit is contained in:
commit
daf39c3cd3
@ -345,8 +345,8 @@ public abstract class DataModel
|
|||||||
{
|
{
|
||||||
lock (_activePaths)
|
lock (_activePaths)
|
||||||
{
|
{
|
||||||
if (_activePaths.Contains(path))
|
if (_activePaths.Any(p => ReferenceEquals(p, path)))
|
||||||
return;
|
throw new ArtemisCoreException("Path already present on this data model, initialization done twice?");
|
||||||
|
|
||||||
_activePaths.Add(path);
|
_activePaths.Add(path);
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -37,6 +38,12 @@ internal class NodeService : INodeService
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public List<Type> GetRegisteredTypes()
|
||||||
|
{
|
||||||
|
return NodeTypeStore.GetColors().Select(c => c.Type).Distinct().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public TypeColorRegistration GetTypeColorRegistration(Type type)
|
public TypeColorRegistration GetTypeColorRegistration(Type type)
|
||||||
{
|
{
|
||||||
@ -132,6 +139,12 @@ public interface INodeService : IArtemisService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
IEnumerable<NodeData> AvailableNodes { get; }
|
IEnumerable<NodeData> AvailableNodes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all currently available node pin types.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A <see cref="List{T}"/> of <see cref="Type"/> containing the currently available node pin types.</returns>
|
||||||
|
List<Type> GetRegisteredTypes();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the best matching registration for the provided type
|
/// Gets the best matching registration for the provided type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -96,6 +96,14 @@ internal class NodeTypeStore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<TypeColorRegistration> GetColors()
|
||||||
|
{
|
||||||
|
lock (ColorRegistrations)
|
||||||
|
{
|
||||||
|
return new List<TypeColorRegistration>(ColorRegistrations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static TypeColorRegistration? GetColor(Type type)
|
public static TypeColorRegistration? GetColor(Type type)
|
||||||
{
|
{
|
||||||
lock (ColorRegistrations)
|
lock (ColorRegistrations)
|
||||||
|
|||||||
@ -48,7 +48,12 @@ public class DataModelDebugViewModel : ActivatableViewModelBase
|
|||||||
|
|
||||||
GetDataModel();
|
GetDataModel();
|
||||||
_updateTimer.Start();
|
_updateTimer.Start();
|
||||||
Disposable.Create(() => _updateTimer.Stop()).DisposeWith(disposables);
|
Disposable.Create(() =>
|
||||||
|
{
|
||||||
|
_updateTimer.Stop();
|
||||||
|
MainDataModel?.Dispose();
|
||||||
|
MainDataModel = null;
|
||||||
|
}).DisposeWith(disposables);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,11 @@ public class DataModelEventNode : Node<DataModelPathEntity, DataModelEventNodeCu
|
|||||||
private readonly Dictionary<Func<DataModelEventArgs, object>, OutputPin> _propertyPins;
|
private readonly Dictionary<Func<DataModelEventArgs, object>, OutputPin> _propertyPins;
|
||||||
private DataModelPath? _dataModelPath;
|
private DataModelPath? _dataModelPath;
|
||||||
private IDataModelEvent? _dataModelEvent;
|
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.")
|
public DataModelEventNode() : base("Data Model-Event", "Outputs the latest values of a data model event.")
|
||||||
{
|
{
|
||||||
@ -43,18 +48,40 @@ public class DataModelEventNode : Node<DataModelPathEntity, DataModelEventNodeCu
|
|||||||
public override void Evaluate()
|
public override void Evaluate()
|
||||||
{
|
{
|
||||||
object? pathValue = _dataModelPath?.GetValue();
|
object? pathValue = _dataModelPath?.GetValue();
|
||||||
if (pathValue is not IDataModelEvent dataModelEvent)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TimeSinceLastTrigger.Value = new Numeric(dataModelEvent.TimeSinceLastTrigger.TotalMilliseconds);
|
// If the path is a data model event, evaluate the event
|
||||||
TriggerCount.Value = new Numeric(dataModelEvent.TriggerCount);
|
if (pathValue is IDataModelEvent dataModelEvent)
|
||||||
|
|
||||||
foreach ((Func<DataModelEventArgs, object> propertyAccessor, OutputPin outputPin) in _propertyPins)
|
|
||||||
{
|
{
|
||||||
if (!outputPin.ConnectedTo.Any())
|
TimeSinceLastTrigger.Value = dataModelEvent.TimeSinceLastTrigger.TotalMilliseconds;
|
||||||
continue;
|
TriggerCount.Value = dataModelEvent.TriggerCount;
|
||||||
object value = dataModelEvent.LastEventArgumentsUntyped != null ? propertyAccessor(dataModelEvent.LastEventArgumentsUntyped) : outputPin.Type.GetDefault()!;
|
|
||||||
outputPin.Value = outputPin.IsNumeric ? new Numeric(value) : value;
|
foreach ((Func<DataModelEventArgs, object> 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<DataModelPathEntity, DataModelEventNodeCu
|
|||||||
{
|
{
|
||||||
object? pathValue = _dataModelPath?.GetValue();
|
object? pathValue = _dataModelPath?.GetValue();
|
||||||
if (pathValue is IDataModelEvent dataModelEvent)
|
if (pathValue is IDataModelEvent dataModelEvent)
|
||||||
CreatePins(dataModelEvent);
|
CreateEventPins(dataModelEvent);
|
||||||
|
else
|
||||||
|
CreateValuePins();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreatePins(IDataModelEvent? dataModelEvent)
|
private void CreateEventPins(IDataModelEvent dataModelEvent)
|
||||||
{
|
{
|
||||||
if (_dataModelEvent == dataModelEvent)
|
if (_dataModelEvent == dataModelEvent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<IPin> pins = Pins.Skip(2).ToList();
|
ClearPins();
|
||||||
while (pins.Any())
|
|
||||||
RemovePin((Pin) pins.First());
|
|
||||||
_propertyPins.Clear();
|
|
||||||
|
|
||||||
_dataModelEvent = dataModelEvent;
|
_dataModelEvent = dataModelEvent;
|
||||||
if (dataModelEvent == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (PropertyInfo propertyInfo in dataModelEvent.ArgumentsType.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
foreach (PropertyInfo propertyInfo in dataModelEvent.ArgumentsType.GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||||
.Where(p => p.CustomAttributes.All(a => a.AttributeType != typeof(DataModelIgnoreAttribute))))
|
.Where(p => p.CustomAttributes.All(a => a.AttributeType != typeof(DataModelIgnoreAttribute))))
|
||||||
{
|
{
|
||||||
@ -113,6 +135,31 @@ public class DataModelEventNode : Node<DataModelPathEntity, DataModelEventNodeCu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CreateValuePins()
|
||||||
|
{
|
||||||
|
ClearPins();
|
||||||
|
|
||||||
|
Type? propertyType = _dataModelPath?.GetPropertyType();
|
||||||
|
if (propertyType == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_oldValuePin = CreateOrAddOutputPin(propertyType, "Old value");
|
||||||
|
_newValuePin = CreateOrAddOutputPin(propertyType, "New value");
|
||||||
|
_lastValue = null;
|
||||||
|
_valueChangeCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearPins()
|
||||||
|
{
|
||||||
|
List<IPin> 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)
|
private void DataModelPathOnPathValidated(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
// Update the output pin now that the type is known and attempt to restore the connection that was likely missing
|
// Update the output pin now that the type is known and attempt to restore the connection that was likely missing
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
Modules="{CompiledBinding Modules}"
|
Modules="{CompiledBinding Modules}"
|
||||||
ShowDataModelValues="{CompiledBinding ShowDataModelValues.Value}"
|
ShowDataModelValues="{CompiledBinding ShowDataModelValues.Value}"
|
||||||
ShowFullPath="{CompiledBinding ShowFullPaths.Value}"
|
ShowFullPath="{CompiledBinding ShowFullPaths.Value}"
|
||||||
FilterTypes="{CompiledBinding FilterTypes}"
|
FilterTypes="{CompiledBinding NodePinTypes}"
|
||||||
IsEventPicker="True"
|
IsEventPicker="True"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
MaxWidth="300"/>
|
MaxWidth="300"/>
|
||||||
|
|||||||
@ -19,7 +19,8 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
|
|||||||
private ObservableCollection<Module>? _modules;
|
private ObservableCollection<Module>? _modules;
|
||||||
private bool _updating;
|
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;
|
_node = node;
|
||||||
_nodeEditorService = nodeEditorService;
|
_nodeEditorService = nodeEditorService;
|
||||||
@ -28,6 +29,11 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
|
|||||||
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
|
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
|
||||||
Modules = new ObservableCollection<Module>();
|
Modules = new ObservableCollection<Module>();
|
||||||
|
|
||||||
|
List<Type> nodePinTypes = nodeService.GetRegisteredTypes();
|
||||||
|
nodePinTypes.AddRange(Constants.NumberTypes);
|
||||||
|
nodePinTypes.Add(typeof(IDataModelEvent));
|
||||||
|
NodePinTypes = new ObservableCollection<Type>(nodePinTypes);
|
||||||
|
|
||||||
this.WhenActivated(d =>
|
this.WhenActivated(d =>
|
||||||
{
|
{
|
||||||
// Set up extra modules
|
// Set up extra modules
|
||||||
@ -50,6 +56,7 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
|
|||||||
|
|
||||||
public PluginSetting<bool> ShowFullPaths { get; }
|
public PluginSetting<bool> ShowFullPaths { get; }
|
||||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||||
|
public ObservableCollection<Type> NodePinTypes { get; }
|
||||||
|
|
||||||
public ObservableCollection<Module>? Modules
|
public ObservableCollection<Module>? Modules
|
||||||
{
|
{
|
||||||
@ -63,8 +70,6 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
|
|||||||
set => this.RaiseAndSetIfChanged(ref _dataModelPath, value);
|
set => this.RaiseAndSetIfChanged(ref _dataModelPath, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Type> FilterTypes => new() {typeof(IDataModelEvent)};
|
|
||||||
|
|
||||||
private void UpdateDataModelPath(DataModelPathEntity? entity)
|
private void UpdateDataModelPath(DataModelPathEntity? entity)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@ -12,5 +12,6 @@
|
|||||||
Modules="{CompiledBinding Modules}"
|
Modules="{CompiledBinding Modules}"
|
||||||
ShowDataModelValues="{CompiledBinding ShowDataModelValues.Value}"
|
ShowDataModelValues="{CompiledBinding ShowDataModelValues.Value}"
|
||||||
ShowFullPath="{CompiledBinding ShowFullPaths.Value}"
|
ShowFullPath="{CompiledBinding ShowFullPaths.Value}"
|
||||||
|
FilterTypes="{CompiledBinding NodePinTypes}"
|
||||||
MaxWidth="300"/>
|
MaxWidth="300"/>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -19,7 +19,7 @@ public class DataModelNodeCustomViewModel : CustomNodeViewModel
|
|||||||
private ObservableCollection<Module>? _modules;
|
private ObservableCollection<Module>? _modules;
|
||||||
private bool _updating;
|
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;
|
_node = node;
|
||||||
_nodeEditorService = nodeEditorService;
|
_nodeEditorService = nodeEditorService;
|
||||||
@ -27,6 +27,10 @@ public class DataModelNodeCustomViewModel : CustomNodeViewModel
|
|||||||
ShowFullPaths = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true);
|
ShowFullPaths = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true);
|
||||||
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
|
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false);
|
||||||
|
|
||||||
|
List<Type> nodePinTypes = nodeService.GetRegisteredTypes();
|
||||||
|
nodePinTypes.AddRange(Constants.NumberTypes);
|
||||||
|
NodePinTypes = new ObservableCollection<Type>(nodePinTypes);
|
||||||
|
|
||||||
this.WhenActivated(d =>
|
this.WhenActivated(d =>
|
||||||
{
|
{
|
||||||
// Set up extra modules
|
// Set up extra modules
|
||||||
@ -49,6 +53,7 @@ public class DataModelNodeCustomViewModel : CustomNodeViewModel
|
|||||||
|
|
||||||
public PluginSetting<bool> ShowFullPaths { get; }
|
public PluginSetting<bool> ShowFullPaths { get; }
|
||||||
public PluginSetting<bool> ShowDataModelValues { get; }
|
public PluginSetting<bool> ShowDataModelValues { get; }
|
||||||
|
public ObservableCollection<Type> NodePinTypes { get; }
|
||||||
|
|
||||||
public ObservableCollection<Module>? Modules
|
public ObservableCollection<Module>? Modules
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user