mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Data model node - Fixed pins disconnecting after restart
Data model event node - Fixed pins disconnecting after restart Node editor - Fixed connecting already connected input pins to an output pin causing a crash Node editor - Added auto-save every 2 minutes while nodes are open (profiles are already auto-saved whenever you make a change, nodes will get the same treatment later)
This commit is contained in:
parent
0120f37c93
commit
88f01abe0d
@ -11,17 +11,15 @@ namespace Artemis.Core.Services;
|
|||||||
internal class ProcessMonitorService : IProcessMonitorService
|
internal class ProcessMonitorService : IProcessMonitorService
|
||||||
{
|
{
|
||||||
private readonly ProcessComparer _comparer;
|
private readonly ProcessComparer _comparer;
|
||||||
private readonly ILogger _logger;
|
|
||||||
private Process[] _lastScannedProcesses;
|
private Process[] _lastScannedProcesses;
|
||||||
|
|
||||||
public ProcessMonitorService(ILogger logger)
|
public ProcessMonitorService()
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_comparer = new ProcessComparer();
|
||||||
_lastScannedProcesses = Process.GetProcesses();
|
_lastScannedProcesses = Process.GetProcesses();
|
||||||
Timer processScanTimer = new(1000);
|
Timer processScanTimer = new(1000);
|
||||||
processScanTimer.Elapsed += OnTimerElapsed;
|
processScanTimer.Elapsed += OnTimerElapsed;
|
||||||
processScanTimer.Start();
|
processScanTimer.Start();
|
||||||
_comparer = new ProcessComparer();
|
|
||||||
|
|
||||||
ProcessActivationRequirement.ProcessMonitorService = this;
|
ProcessActivationRequirement.ProcessMonitorService = this;
|
||||||
}
|
}
|
||||||
@ -30,16 +28,9 @@ internal class ProcessMonitorService : IProcessMonitorService
|
|||||||
{
|
{
|
||||||
Process[] newProcesses = Process.GetProcesses();
|
Process[] newProcesses = Process.GetProcesses();
|
||||||
foreach (Process startedProcess in newProcesses.Except(_lastScannedProcesses, _comparer))
|
foreach (Process startedProcess in newProcesses.Except(_lastScannedProcesses, _comparer))
|
||||||
{
|
|
||||||
ProcessStarted?.Invoke(this, new ProcessEventArgs(startedProcess));
|
ProcessStarted?.Invoke(this, new ProcessEventArgs(startedProcess));
|
||||||
//_logger.Verbose("Started Process: {startedProcess}", startedProcess.ProcessName);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Process stoppedProcess in _lastScannedProcesses.Except(newProcesses, _comparer))
|
foreach (Process stoppedProcess in _lastScannedProcesses.Except(newProcesses, _comparer))
|
||||||
{
|
|
||||||
ProcessStopped?.Invoke(this, new ProcessEventArgs(stoppedProcess));
|
ProcessStopped?.Invoke(this, new ProcessEventArgs(stoppedProcess));
|
||||||
//_logger.Verbose("Stopped Process: {stoppedProcess}", stoppedProcess.ProcessName);
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastScannedProcesses = newProcesses;
|
_lastScannedProcesses = newProcesses;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ namespace Artemis.Core;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a node script
|
/// Represents a node script
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface INodeScript : INotifyPropertyChanged, IDisposable
|
public interface INodeScript : INotifyPropertyChanged, IDisposable, IStorageModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the node script.
|
/// Gets the name of the node script.
|
||||||
@ -66,6 +66,11 @@ public interface INodeScript : INotifyPropertyChanged, IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="node">The node to remove</param>
|
/// <param name="node">The node to remove</param>
|
||||||
void RemoveNode(INode node);
|
void RemoveNode(INode node);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads missing connections between the nodes of this node script from storage
|
||||||
|
/// </summary>
|
||||||
|
void LoadConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace Artemis.Core;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a node script
|
/// Represents a node script
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class NodeScript : CorePropertyChanged, INodeScript, IStorageModel
|
public abstract class NodeScript : CorePropertyChanged, INodeScript
|
||||||
{
|
{
|
||||||
private void NodeTypeStoreOnNodeTypeChanged(object? sender, NodeTypeStoreEvent e)
|
private void NodeTypeStoreOnNodeTypeChanged(object? sender, NodeTypeStoreEvent e)
|
||||||
{
|
{
|
||||||
@ -226,9 +226,7 @@ public abstract class NodeScript : CorePropertyChanged, INodeScript, IStorageMod
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Loads missing connections between the nodes of this node script from the <see cref="Entity" />
|
|
||||||
/// </summary>
|
|
||||||
public void LoadConnections()
|
public void LoadConnections()
|
||||||
{
|
{
|
||||||
List<INode> nodes = Nodes.ToList();
|
List<INode> nodes = Nodes.ToList();
|
||||||
|
|||||||
@ -33,12 +33,14 @@ public class LinuxInputProvider : InputProvider
|
|||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
|
{
|
||||||
for (int i = _readers.Count - 1; i >= 0; i--)
|
for (int i = _readers.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
_readers[i].InputEvent -= OnInputEvent;
|
_readers[i].InputEvent -= OnInputEvent;
|
||||||
_readers[i].Dispose();
|
_readers[i].Dispose();
|
||||||
_readers.RemoveAt(i);
|
_readers.RemoveAt(i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
@ -49,6 +51,7 @@ public class LinuxInputProvider : InputProvider
|
|||||||
{
|
{
|
||||||
if (sender is not LinuxInputDeviceReader reader)
|
if (sender is not LinuxInputDeviceReader reader)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (reader.InputDevice.DeviceType)
|
switch (reader.InputDevice.DeviceType)
|
||||||
{
|
{
|
||||||
case LinuxDeviceType.Keyboard:
|
case LinuxDeviceType.Keyboard:
|
||||||
@ -64,18 +67,16 @@ public class LinuxInputProvider : InputProvider
|
|||||||
|
|
||||||
private void HandleKeyboardData(LinuxInputDevice keyboard, LinuxInputEventArgs args)
|
private void HandleKeyboardData(LinuxInputDevice keyboard, LinuxInputEventArgs args)
|
||||||
{
|
{
|
||||||
switch (args.Type)
|
if (args.Type != LinuxInputEventType.KEY)
|
||||||
{
|
return;
|
||||||
case LinuxInputEventType.KEY:
|
|
||||||
KeyboardKey key = InputUtilities.KeyFromKeyCode((LinuxKeyboardKeyCodes) args.Code);
|
KeyboardKey key = InputUtilities.KeyFromKeyCode((LinuxKeyboardKeyCodes) args.Code);
|
||||||
bool isDown = args.Value != 0;
|
bool isDown = args.Value != 0;
|
||||||
|
|
||||||
//_logger.Verbose($"Keyboard Key: {(LinuxKeyboardKeyCodes)args.Code} | Down: {isDown}");
|
//_logger.Verbose($"Keyboard Key: {(LinuxKeyboardKeyCodes)args.Code} | Down: {isDown}");
|
||||||
|
|
||||||
LinuxInputDevice.LinuxInputId identifier = keyboard.InputId;
|
LinuxInputDevice.LinuxInputId identifier = keyboard.InputId;
|
||||||
|
|
||||||
OnIdentifierReceived(identifier, InputDeviceType.Keyboard);
|
OnIdentifierReceived(identifier, InputDeviceType.Keyboard);
|
||||||
|
|
||||||
ArtemisDevice? device = null;
|
ArtemisDevice? device = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -88,16 +89,12 @@ public class LinuxInputProvider : InputProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
OnKeyboardDataReceived(device, key, isDown);
|
OnKeyboardDataReceived(device, key, isDown);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleMouseData(LinuxInputDevice mouse, LinuxInputEventArgs args)
|
private void HandleMouseData(LinuxInputDevice mouse, LinuxInputEventArgs args)
|
||||||
{
|
{
|
||||||
LinuxInputDevice.LinuxInputId identifier = mouse.InputId;
|
LinuxInputDevice.LinuxInputId identifier = mouse.InputId;
|
||||||
|
|
||||||
OnIdentifierReceived(identifier, InputDeviceType.Mouse);
|
OnIdentifierReceived(identifier, InputDeviceType.Mouse);
|
||||||
|
|
||||||
ArtemisDevice? device = null;
|
ArtemisDevice? device = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -112,13 +109,11 @@ public class LinuxInputProvider : InputProvider
|
|||||||
switch (args.Type)
|
switch (args.Type)
|
||||||
{
|
{
|
||||||
case LinuxInputEventType.KEY:
|
case LinuxInputEventType.KEY:
|
||||||
var key = (LinuxKeyboardKeyCodes)args.Code;
|
LinuxKeyboardKeyCodes key = (LinuxKeyboardKeyCodes) args.Code;
|
||||||
if (key == LinuxKeyboardKeyCodes.BTN_TOUCH ||
|
if (key == LinuxKeyboardKeyCodes.BTN_TOUCH ||
|
||||||
(key >= LinuxKeyboardKeyCodes.BTN_TOOL_PEN && key <= LinuxKeyboardKeyCodes.BTN_TOOL_QUADTAP))
|
(key >= LinuxKeyboardKeyCodes.BTN_TOOL_PEN && key <= LinuxKeyboardKeyCodes.BTN_TOOL_QUADTAP))
|
||||||
{
|
|
||||||
//trackpad input, ignore.
|
//trackpad input, ignore.
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
//0 - up
|
//0 - up
|
||||||
//1 - down
|
//1 - down
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
|
|
||||||
namespace Artemis.UI.Shared.Services.NodeEditor.Commands;
|
namespace Artemis.UI.Shared.Services.NodeEditor.Commands;
|
||||||
@ -8,9 +9,9 @@ namespace Artemis.UI.Shared.Services.NodeEditor.Commands;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConnectPins : INodeEditorCommand
|
public class ConnectPins : INodeEditorCommand
|
||||||
{
|
{
|
||||||
private readonly List<IPin>? _originalConnections;
|
private readonly IPin _output;
|
||||||
private readonly IPin _source;
|
private readonly IPin _input;
|
||||||
private readonly IPin _target;
|
private readonly IPin? _originalConnection;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the <see cref="ConnectPins" /> class.
|
/// Creates a new instance of the <see cref="ConnectPins" /> class.
|
||||||
@ -19,10 +20,18 @@ public class ConnectPins : INodeEditorCommand
|
|||||||
/// <param name="target">The target of the connection.</param>
|
/// <param name="target">The target of the connection.</param>
|
||||||
public ConnectPins(IPin source, IPin target)
|
public ConnectPins(IPin source, IPin target)
|
||||||
{
|
{
|
||||||
_source = source;
|
if (source.Direction == PinDirection.Output)
|
||||||
_target = target;
|
{
|
||||||
|
_output = source;
|
||||||
|
_input = target;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_output = target;
|
||||||
|
_input = source;
|
||||||
|
}
|
||||||
|
|
||||||
_originalConnections = _target.Direction == PinDirection.Input ? new List<IPin>(_target.ConnectedTo) : null;
|
_originalConnection = _input.ConnectedTo.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Implementation of INodeEditorCommand
|
#region Implementation of INodeEditorCommand
|
||||||
@ -33,20 +42,16 @@ public class ConnectPins : INodeEditorCommand
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Execute()
|
public void Execute()
|
||||||
{
|
{
|
||||||
if (_target.Direction == PinDirection.Input)
|
_input.DisconnectAll();
|
||||||
_target.DisconnectAll();
|
_output.ConnectTo(_input);
|
||||||
_source.ConnectTo(_target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Undo()
|
public void Undo()
|
||||||
{
|
{
|
||||||
_target.DisconnectFrom(_source);
|
_input.DisconnectAll();
|
||||||
|
if (_originalConnection != null)
|
||||||
if (_originalConnections == null)
|
_input.ConnectTo(_originalConnection);
|
||||||
return;
|
|
||||||
foreach (IPin pin in _originalConnections)
|
|
||||||
_target.ConnectTo(pin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -25,6 +25,7 @@ public class DataBindingViewModel : ActivatableViewModelBase
|
|||||||
private ObservableAsPropertyHelper<ILayerProperty?>? _layerProperty;
|
private ObservableAsPropertyHelper<ILayerProperty?>? _layerProperty;
|
||||||
private ObservableAsPropertyHelper<NodeScriptViewModel?>? _nodeScriptViewModel;
|
private ObservableAsPropertyHelper<NodeScriptViewModel?>? _nodeScriptViewModel;
|
||||||
private bool _playing;
|
private bool _playing;
|
||||||
|
private bool _editorOpen;
|
||||||
|
|
||||||
public DataBindingViewModel(IProfileEditorService profileEditorService, INodeVmFactory nodeVmFactory, IWindowService windowService, ISettingsService settingsService)
|
public DataBindingViewModel(IProfileEditorService profileEditorService, INodeVmFactory nodeVmFactory, IWindowService windowService, ISettingsService settingsService)
|
||||||
{
|
{
|
||||||
@ -49,11 +50,18 @@ public class DataBindingViewModel : ActivatableViewModelBase
|
|||||||
.DisposeWith(d);
|
.DisposeWith(d);
|
||||||
_profileEditorService.Playing.CombineLatest(_profileEditorService.SuspendedEditing).Subscribe(tuple => _playing = tuple.First || tuple.Second).DisposeWith(d);
|
_profileEditorService.Playing.CombineLatest(_profileEditorService.SuspendedEditing).Subscribe(tuple => _playing = tuple.First || tuple.Second).DisposeWith(d);
|
||||||
|
|
||||||
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(60.0 / 1000), DispatcherPriority.Render, Update);
|
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Render, Update);
|
||||||
|
// TODO: Remove in favor of saving each time a node editor command is executed
|
||||||
|
DispatcherTimer saveTimer = new(TimeSpan.FromMinutes(2), DispatcherPriority.Normal, Save);
|
||||||
|
|
||||||
updateTimer.Start();
|
updateTimer.Start();
|
||||||
|
saveTimer.Start();
|
||||||
|
|
||||||
Disposable.Create(() =>
|
Disposable.Create(() =>
|
||||||
{
|
{
|
||||||
updateTimer.Stop();
|
updateTimer.Stop();
|
||||||
|
saveTimer.Stop();
|
||||||
|
|
||||||
_profileEditorService.SaveProfile();
|
_profileEditorService.SaveProfile();
|
||||||
}).DisposeWith(d);
|
}).DisposeWith(d);
|
||||||
});
|
});
|
||||||
@ -74,11 +82,19 @@ public class DataBindingViewModel : ActivatableViewModelBase
|
|||||||
|
|
||||||
public async Task OpenEditor()
|
public async Task OpenEditor()
|
||||||
{
|
{
|
||||||
if (LayerProperty != null && LayerProperty.BaseDataBinding.IsEnabled)
|
if (LayerProperty == null || !LayerProperty.BaseDataBinding.IsEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
|
_editorOpen = true;
|
||||||
await _windowService.ShowDialogAsync<NodeScriptWindowViewModel, bool>(("nodeScript", LayerProperty.BaseDataBinding.Script));
|
await _windowService.ShowDialogAsync<NodeScriptWindowViewModel, bool>(("nodeScript", LayerProperty.BaseDataBinding.Script));
|
||||||
await _profileEditorService.SaveProfileAsync();
|
await _profileEditorService.SaveProfileAsync();
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_editorOpen = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update(object? sender, EventArgs e)
|
private void Update(object? sender, EventArgs e)
|
||||||
@ -89,4 +105,10 @@ public class DataBindingViewModel : ActivatableViewModelBase
|
|||||||
|
|
||||||
LayerProperty?.UpdateDataBinding();
|
LayerProperty?.UpdateDataBinding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Save(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!_editorOpen)
|
||||||
|
_profileEditorService.SaveProfile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -12,6 +12,7 @@ using Artemis.UI.Shared;
|
|||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using Artemis.UI.Shared.Services.NodeEditor;
|
using Artemis.UI.Shared.Services.NodeEditor;
|
||||||
using Artemis.UI.Shared.Services.NodeEditor.Commands;
|
using Artemis.UI.Shared.Services.NodeEditor.Commands;
|
||||||
|
using Artemis.UI.Shared.Services.ProfileEditor;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
@ -25,6 +26,7 @@ public class NodeScriptWindowViewModel : DialogViewModelBase<bool>
|
|||||||
private readonly INodeEditorService _nodeEditorService;
|
private readonly INodeEditorService _nodeEditorService;
|
||||||
private readonly INodeService _nodeService;
|
private readonly INodeService _nodeService;
|
||||||
private readonly ISettingsService _settingsService;
|
private readonly ISettingsService _settingsService;
|
||||||
|
private readonly IProfileService _profileService;
|
||||||
private readonly IWindowService _windowService;
|
private readonly IWindowService _windowService;
|
||||||
|
|
||||||
public NodeScriptWindowViewModel(NodeScript nodeScript,
|
public NodeScriptWindowViewModel(NodeScript nodeScript,
|
||||||
@ -32,6 +34,7 @@ public class NodeScriptWindowViewModel : DialogViewModelBase<bool>
|
|||||||
INodeEditorService nodeEditorService,
|
INodeEditorService nodeEditorService,
|
||||||
INodeVmFactory vmFactory,
|
INodeVmFactory vmFactory,
|
||||||
ISettingsService settingsService,
|
ISettingsService settingsService,
|
||||||
|
IProfileService profileService,
|
||||||
IWindowService windowService)
|
IWindowService windowService)
|
||||||
{
|
{
|
||||||
NodeScript = nodeScript;
|
NodeScript = nodeScript;
|
||||||
@ -43,6 +46,7 @@ public class NodeScriptWindowViewModel : DialogViewModelBase<bool>
|
|||||||
_nodeService = nodeService;
|
_nodeService = nodeService;
|
||||||
_nodeEditorService = nodeEditorService;
|
_nodeEditorService = nodeEditorService;
|
||||||
_settingsService = settingsService;
|
_settingsService = settingsService;
|
||||||
|
_profileService = profileService;
|
||||||
_windowService = windowService;
|
_windowService = windowService;
|
||||||
|
|
||||||
SourceList<NodeData> nodeSourceList = new();
|
SourceList<NodeData> nodeSourceList = new();
|
||||||
@ -60,8 +64,17 @@ public class NodeScriptWindowViewModel : DialogViewModelBase<bool>
|
|||||||
this.WhenActivated(d =>
|
this.WhenActivated(d =>
|
||||||
{
|
{
|
||||||
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Normal, Update);
|
DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Normal, Update);
|
||||||
|
// TODO: Remove in favor of saving each time a node editor command is executed
|
||||||
|
DispatcherTimer saveTimer = new(TimeSpan.FromMinutes(2), DispatcherPriority.Normal, Save);
|
||||||
|
|
||||||
updateTimer.Start();
|
updateTimer.Start();
|
||||||
Disposable.Create(() => updateTimer.Stop()).DisposeWith(d);
|
saveTimer.Start();
|
||||||
|
|
||||||
|
Disposable.Create(() =>
|
||||||
|
{
|
||||||
|
updateTimer.Stop();
|
||||||
|
saveTimer.Stop();
|
||||||
|
}).DisposeWith(d);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,4 +146,10 @@ public class NodeScriptWindowViewModel : DialogViewModelBase<bool>
|
|||||||
{
|
{
|
||||||
NodeScript.Run();
|
NodeScript.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Save(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (NodeScript.Context is Profile profile)
|
||||||
|
_profileService.SaveProfile(profile, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -48,9 +48,7 @@ public class DataModelEventCycleNode : Node<DataModelPathEntity, DataModelEventC
|
|||||||
public override void Evaluate()
|
public override void Evaluate()
|
||||||
{
|
{
|
||||||
object? pathValue = _dataModelPath?.GetValue();
|
object? pathValue = _dataModelPath?.GetValue();
|
||||||
bool hasTriggered = pathValue is IDataModelEvent dataModelEvent
|
bool hasTriggered = pathValue is IDataModelEvent dataModelEvent ? EvaluateEvent(dataModelEvent) : EvaluateValue(pathValue);
|
||||||
? EvaluateEvent(dataModelEvent)
|
|
||||||
: EvaluateValue(pathValue);
|
|
||||||
|
|
||||||
if (hasTriggered)
|
if (hasTriggered)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Events;
|
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.VisualScripting.Nodes.DataModel.Screens;
|
using Artemis.VisualScripting.Nodes.DataModel.Screens;
|
||||||
@ -41,6 +40,47 @@ public class DataModelEventNode : Node<DataModelPathEntity, DataModelEventNodeCu
|
|||||||
UpdateDataModelPath();
|
UpdateDataModelPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 (!outputPin.ConnectedTo.Any())
|
||||||
|
continue;
|
||||||
|
object value = dataModelEvent.LastEventArgumentsUntyped != null ? propertyAccessor(dataModelEvent.LastEventArgumentsUntyped) : outputPin.Type.GetDefault()!;
|
||||||
|
outputPin.Value = outputPin.IsNumeric ? new Numeric(value) : value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateDataModelPath()
|
||||||
|
{
|
||||||
|
DataModelPath? old = _dataModelPath;
|
||||||
|
_dataModelPath = Storage != null ? new DataModelPath(Storage) : null;
|
||||||
|
if (_dataModelPath != null)
|
||||||
|
_dataModelPath.PathValidated += DataModelPathOnPathValidated;
|
||||||
|
|
||||||
|
if (old != null)
|
||||||
|
{
|
||||||
|
old.PathValidated -= DataModelPathOnPathValidated;
|
||||||
|
old.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateOutputPins();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateOutputPins()
|
||||||
|
{
|
||||||
|
object? pathValue = _dataModelPath?.GetValue();
|
||||||
|
if (pathValue is IDataModelEvent dataModelEvent)
|
||||||
|
CreatePins(dataModelEvent);
|
||||||
|
}
|
||||||
|
|
||||||
private void CreatePins(IDataModelEvent? dataModelEvent)
|
private void CreatePins(IDataModelEvent? dataModelEvent)
|
||||||
{
|
{
|
||||||
if (_dataModelEvent == dataModelEvent)
|
if (_dataModelEvent == dataModelEvent)
|
||||||
@ -73,33 +113,11 @@ public class DataModelEventNode : Node<DataModelPathEntity, DataModelEventNodeCu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Evaluate()
|
private void DataModelPathOnPathValidated(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
object? pathValue = _dataModelPath?.GetValue();
|
// Update the output pin now that the type is known and attempt to restore the connection that was likely missing
|
||||||
if (pathValue is not IDataModelEvent dataModelEvent)
|
UpdateOutputPins();
|
||||||
return;
|
Script?.LoadConnections();
|
||||||
|
|
||||||
TimeSinceLastTrigger.Value = new Numeric(dataModelEvent.TimeSinceLastTrigger.TotalMilliseconds);
|
|
||||||
TriggerCount.Value = new Numeric(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateDataModelPath()
|
|
||||||
{
|
|
||||||
DataModelPath? old = _dataModelPath;
|
|
||||||
_dataModelPath = Storage != null ? new DataModelPath(Storage) : null;
|
|
||||||
old?.Dispose();
|
|
||||||
|
|
||||||
object? pathValue = _dataModelPath?.GetValue();
|
|
||||||
if (pathValue is IDataModelEvent dataModelEvent)
|
|
||||||
CreatePins(dataModelEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.VisualScripting.Nodes.DataModel.Screens;
|
using Artemis.VisualScripting.Nodes.DataModel.Screens;
|
||||||
using Avalonia.Threading;
|
|
||||||
|
|
||||||
namespace Artemis.VisualScripting.Nodes.DataModel;
|
namespace Artemis.VisualScripting.Nodes.DataModel;
|
||||||
|
|
||||||
@ -61,17 +60,24 @@ public class DataModelNode : Node<DataModelPathEntity, DataModelNodeCustomViewMo
|
|||||||
private void UpdateDataModelPath()
|
private void UpdateDataModelPath()
|
||||||
{
|
{
|
||||||
DataModelPath? old = _dataModelPath;
|
DataModelPath? old = _dataModelPath;
|
||||||
old?.Dispose();
|
|
||||||
|
|
||||||
_dataModelPath = Storage != null ? new DataModelPath(Storage) : null;
|
_dataModelPath = Storage != null ? new DataModelPath(Storage) : null;
|
||||||
if (_dataModelPath != null)
|
if (_dataModelPath != null)
|
||||||
_dataModelPath.PathValidated += DataModelPathOnPathValidated;
|
_dataModelPath.PathValidated += DataModelPathOnPathValidated;
|
||||||
|
|
||||||
|
if (old != null)
|
||||||
|
{
|
||||||
|
old.PathValidated -= DataModelPathOnPathValidated;
|
||||||
|
old.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
UpdateOutputPin();
|
UpdateOutputPin();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DataModelPathOnPathValidated(object? sender, EventArgs e)
|
private void DataModelPathOnPathValidated(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.InvokeAsync(UpdateOutputPin);
|
// Update the output pin now that the type is known and attempt to restore the connection that was likely missing
|
||||||
|
UpdateOutputPin();
|
||||||
|
Script?.LoadConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user