1
0
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:
Robert 2022-09-08 23:02:04 +02:00
commit daf39c3cd3
9 changed files with 116 additions and 32 deletions

View File

@ -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);

View File

@ -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
/// <inheritdoc />
public List<Type> GetRegisteredTypes()
{
return NodeTypeStore.GetColors().Select(c => c.Type).Distinct().ToList();
}
/// <inheritdoc />
public TypeColorRegistration GetTypeColorRegistration(Type type)
{
@ -132,6 +139,12 @@ public interface INodeService : IArtemisService
/// </summary>
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>
/// Gets the best matching registration for the provided type
/// </summary>

View File

@ -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)
{
lock (ColorRegistrations)

View File

@ -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);
});
}

View File

@ -14,7 +14,12 @@ public class DataModelEventNode : Node<DataModelPathEntity, DataModelEventNodeCu
private readonly Dictionary<Func<DataModelEventArgs, object>, 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<Func<DataModelEventArgs, object>, OutputPin>();
@ -43,18 +48,40 @@ public class DataModelEventNode : Node<DataModelPathEntity, DataModelEventNodeCu
public override void Evaluate()
{
object? pathValue = _dataModelPath?.GetValue();
if (pathValue is not IDataModelEvent dataModelEvent)
return;
TimeSinceLastTrigger.Value = new Numeric(dataModelEvent.TimeSinceLastTrigger.TotalMilliseconds);
TriggerCount.Value = new Numeric(dataModelEvent.TriggerCount);
foreach ((Func<DataModelEventArgs, object> 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<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();
if (pathValue is IDataModelEvent dataModelEvent)
CreatePins(dataModelEvent);
CreateEventPins(dataModelEvent);
else
CreateValuePins();
}
private void CreatePins(IDataModelEvent? dataModelEvent)
private void CreateEventPins(IDataModelEvent dataModelEvent)
{
if (_dataModelEvent == dataModelEvent)
return;
List<IPin> 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<DataModelPathEntity, DataModelEventNodeCu
_propertyPins.Add(expression, CreateOrAddOutputPin(propertyInfo.PropertyType, propertyInfo.Name.Humanize()));
}
}
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)
{

View File

@ -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"/>

View File

@ -19,7 +19,8 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
private ObservableCollection<Module>? _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<Module>();
List<Type> nodePinTypes = nodeService.GetRegisteredTypes();
nodePinTypes.AddRange(Constants.NumberTypes);
nodePinTypes.Add(typeof(IDataModelEvent));
NodePinTypes = new ObservableCollection<Type>(nodePinTypes);
this.WhenActivated(d =>
{
// Set up extra modules
@ -50,6 +56,7 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
public PluginSetting<bool> ShowFullPaths { get; }
public PluginSetting<bool> ShowDataModelValues { get; }
public ObservableCollection<Type> NodePinTypes { get; }
public ObservableCollection<Module>? Modules
{
@ -63,8 +70,6 @@ public class DataModelEventNodeCustomViewModel : CustomNodeViewModel
set => this.RaiseAndSetIfChanged(ref _dataModelPath, value);
}
public List<Type> FilterTypes => new() {typeof(IDataModelEvent)};
private void UpdateDataModelPath(DataModelPathEntity? entity)
{
try

View File

@ -12,5 +12,6 @@
Modules="{CompiledBinding Modules}"
ShowDataModelValues="{CompiledBinding ShowDataModelValues.Value}"
ShowFullPath="{CompiledBinding ShowFullPaths.Value}"
FilterTypes="{CompiledBinding NodePinTypes}"
MaxWidth="300"/>
</UserControl>

View File

@ -19,7 +19,7 @@ public class DataModelNodeCustomViewModel : CustomNodeViewModel
private ObservableCollection<Module>? _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<Type> nodePinTypes = nodeService.GetRegisteredTypes();
nodePinTypes.AddRange(Constants.NumberTypes);
NodePinTypes = new ObservableCollection<Type>(nodePinTypes);
this.WhenActivated(d =>
{
// Set up extra modules
@ -49,7 +53,8 @@ public class DataModelNodeCustomViewModel : CustomNodeViewModel
public PluginSetting<bool> ShowFullPaths { get; }
public PluginSetting<bool> ShowDataModelValues { get; }
public ObservableCollection<Type> NodePinTypes { get; }
public ObservableCollection<Module>? Modules
{
get => _modules;