diff --git a/src/Artemis.Core/Constants.cs b/src/Artemis.Core/Constants.cs
index 7d455e13e..69208acb3 100644
--- a/src/Artemis.Core/Constants.cs
+++ b/src/Artemis.Core/Constants.cs
@@ -38,7 +38,7 @@ namespace Artemis.Core
///
/// The full path to the Artemis data folder
///
- public static readonly string DataFolder = Path.Combine(BaseFolder, "Artemis.Avalonia");
+ public static readonly string DataFolder = Path.Combine(BaseFolder, "Artemis");
///
/// The full path to the Artemis logs folder
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index 6966ff44c..b0bab4093 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -382,7 +382,7 @@ namespace Artemis.Core
if (ShouldBeEnabled)
Enable();
- else if (Timeline.IsFinished && !_renderCopies.Any())
+ else if (Suspended || (Timeline.IsFinished && !_renderCopies.Any()))
Disable();
if (Timeline.Delta == TimeSpan.Zero)
diff --git a/src/Artemis.Core/Utilities/Numeric.cs b/src/Artemis.Core/Utilities/Numeric.cs
index d96516148..09b64603f 100644
--- a/src/Artemis.Core/Utilities/Numeric.cs
+++ b/src/Artemis.Core/Utilities/Numeric.cs
@@ -60,6 +60,7 @@ namespace Artemis.Core
int value => value,
double value => (float) value,
byte value => value,
+ Numeric value => value,
_ => ParseFloatOrDefault(pathValue?.ToString())
};
}
diff --git a/src/Artemis.Core/VisualScripting/InputPin.cs b/src/Artemis.Core/VisualScripting/InputPin.cs
index 2b218fb44..1efb780d0 100644
--- a/src/Artemis.Core/VisualScripting/InputPin.cs
+++ b/src/Artemis.Core/VisualScripting/InputPin.cs
@@ -17,6 +17,7 @@ namespace Artemis.Core
: base(node, name)
{
Value = default;
+ IsNumeric = typeof(T) == typeof(Numeric);
}
#endregion
@@ -80,6 +81,7 @@ namespace Artemis.Core
{
_type = type;
_value = type.GetDefault();
+ IsNumeric = type == typeof(Numeric);
}
#endregion
@@ -103,6 +105,7 @@ namespace Artemis.Core
// Change the type
SetAndNotify(ref _type, type, nameof(Type));
Value = type.GetDefault();
+ IsNumeric = type == typeof(Numeric);
}
private void Evaluate()
@@ -169,7 +172,7 @@ namespace Artemis.Core
OnPropertyChanged(nameof(PinValue));
}
}
-
+
#endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/VisualScripting/Interfaces/IPin.cs b/src/Artemis.Core/VisualScripting/Interfaces/IPin.cs
index 197f40365..a9389fc40 100644
--- a/src/Artemis.Core/VisualScripting/Interfaces/IPin.cs
+++ b/src/Artemis.Core/VisualScripting/Interfaces/IPin.cs
@@ -29,6 +29,11 @@ namespace Artemis.Core
///
Type Type { get; }
+ ///
+ /// Gets a boolean indicating whether the type of this pin is numeric.
+ ///
+ bool IsNumeric { get; }
+
///
/// Gets the value the pin holds
///
diff --git a/src/Artemis.Core/VisualScripting/Internal/EventConditionEventStartNode.cs b/src/Artemis.Core/VisualScripting/Internal/EventConditionEventStartNode.cs
index c169e0555..4aa4eca1a 100644
--- a/src/Artemis.Core/VisualScripting/Internal/EventConditionEventStartNode.cs
+++ b/src/Artemis.Core/VisualScripting/Internal/EventConditionEventStartNode.cs
@@ -47,7 +47,10 @@ internal class EventConditionEventStartNode : DefaultNode, IEventConditionNode
foreach ((PropertyInfo propertyInfo, OutputPin outputPin) in _propertyPins)
{
if (outputPin.ConnectedTo.Any())
- outputPin.Value = propertyInfo.GetValue(_dataModelEvent.LastEventArgumentsUntyped) ?? outputPin.Type.GetDefault()!;
+ {
+ object value = propertyInfo.GetValue(_dataModelEvent.LastEventArgumentsUntyped) ?? outputPin.Type.GetDefault()!;
+ outputPin.Value = outputPin.IsNumeric ? new Numeric(value) : value;
+ }
}
}
@@ -61,6 +64,9 @@ internal class EventConditionEventStartNode : DefaultNode, IEventConditionNode
// Grab the first pin from the bucket that isn't on the node yet
OutputPin? pin = _pinBucket.FirstOrDefault(p => !Pins.Contains(p));
+ if (Numeric.IsTypeCompatible(valueType))
+ valueType = typeof(Numeric);
+
// If there is none, create a new one and add it to the bucket
if (pin == null)
{
diff --git a/src/Artemis.Core/VisualScripting/Internal/EventConditionValueChangedStartNode.cs b/src/Artemis.Core/VisualScripting/Internal/EventConditionValueChangedStartNode.cs
index 5bbf1d77b..abf571979 100644
--- a/src/Artemis.Core/VisualScripting/Internal/EventConditionValueChangedStartNode.cs
+++ b/src/Artemis.Core/VisualScripting/Internal/EventConditionValueChangedStartNode.cs
@@ -20,10 +20,11 @@ internal class EventConditionValueChangedStartNode : DefaultNode, IEventConditio
public void UpdateOutputPins(DataModelPath dataModelPath)
{
- Type? type = dataModelPath?.GetPropertyType();
- if (Numeric.IsTypeCompatible(type))
+ Type? type = dataModelPath.GetPropertyType();
+ if (type == null)
+ type = typeof(object);
+ else if (Numeric.IsTypeCompatible(type))
type = typeof(Numeric);
- type ??= typeof(object);
if (NewValue.Type != type)
NewValue.ChangeType(type);
@@ -33,8 +34,8 @@ internal class EventConditionValueChangedStartNode : DefaultNode, IEventConditio
public void UpdateValues(object? newValue, object? oldValue)
{
- _newValue = newValue;
- _oldValue = oldValue;
+ _newValue = NewValue.IsNumeric ? new Numeric(newValue) : newValue;
+ _oldValue = OldValue.IsNumeric ? new Numeric(oldValue) : oldValue;
}
///
diff --git a/src/Artemis.Core/VisualScripting/OutputPin.cs b/src/Artemis.Core/VisualScripting/OutputPin.cs
index a2b1ce1f0..0027c867f 100644
--- a/src/Artemis.Core/VisualScripting/OutputPin.cs
+++ b/src/Artemis.Core/VisualScripting/OutputPin.cs
@@ -17,6 +17,7 @@ namespace Artemis.Core
: base(node, name)
{
_value = default;
+ IsNumeric = typeof(T) == typeof(Numeric);
}
#endregion
@@ -70,6 +71,7 @@ namespace Artemis.Core
{
_type = type;
_value = type.GetDefault();
+ IsNumeric = type == typeof(Numeric);
}
#endregion
@@ -90,6 +92,7 @@ namespace Artemis.Core
// Change the type
SetAndNotify(ref _type, type, nameof(Type));
Value = type.GetDefault();
+ IsNumeric = type == typeof(Numeric);
}
#endregion
diff --git a/src/Artemis.Core/VisualScripting/Pin.cs b/src/Artemis.Core/VisualScripting/Pin.cs
index 46916fae5..b9626f87e 100644
--- a/src/Artemis.Core/VisualScripting/Pin.cs
+++ b/src/Artemis.Core/VisualScripting/Pin.cs
@@ -50,10 +50,19 @@ namespace Artemis.Core
get => _isEvaluated;
set => SetAndNotify(ref _isEvaluated, value);
}
+
+ private bool _isNumeric;
+
+ ///
+ public bool IsNumeric
+ {
+ get => _isNumeric;
+ protected set => SetAndNotify(ref _isNumeric, value);
+ }
private readonly List _connectedTo = new();
private string _name;
-
+
///
public IReadOnlyList ConnectedTo => new ReadOnlyCollection(_connectedTo);
diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs
index b64aaedc9..86793643e 100644
--- a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs
+++ b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugViewModel.cs
@@ -32,7 +32,7 @@ public class DataModelDebugViewModel : ActivatableViewModelBase, IRoutableViewMo
{
_dataModelUIService = dataModelUIService;
_pluginManagementService = pluginManagementService;
- _updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(25), DispatcherPriority.Normal, (_, _) => Update());
+ _updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(25), DispatcherPriority.DataBind, (_, _) => Update());
HostScreen = hostScreen;
Modules = new ObservableCollection();
diff --git a/src/Artemis.UI/Screens/Plugins/PluginSettingsViewModel.cs b/src/Artemis.UI/Screens/Plugins/PluginSettingsViewModel.cs
index 5c1baf29d..6a7c6c9fb 100644
--- a/src/Artemis.UI/Screens/Plugins/PluginSettingsViewModel.cs
+++ b/src/Artemis.UI/Screens/Plugins/PluginSettingsViewModel.cs
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
+using System.Linq;
using System.Reactive;
using System.Threading.Tasks;
using Artemis.Core;
@@ -13,52 +14,36 @@ namespace Artemis.UI.Screens.Plugins;
public class PluginSettingsViewModel : ActivatableViewModelBase
{
private Plugin _plugin;
-
- private readonly ISettingsVmFactory _settingsVmFactory;
+
private readonly IPluginManagementService _pluginManagementService;
private readonly INotificationService _notificationService;
-
- private PluginViewModel _pluginViewModel;
public PluginSettingsViewModel(Plugin plugin, ISettingsVmFactory settingsVmFactory, IPluginManagementService pluginManagementService, INotificationService notificationService)
{
_plugin = plugin;
- _settingsVmFactory = settingsVmFactory;
_pluginManagementService = pluginManagementService;
_notificationService = notificationService;
Reload = ReactiveCommand.CreateFromTask(ExecuteReload);
-
PluginViewModel = settingsVmFactory.PluginViewModel(_plugin, Reload);
- PluginFeatures = new ObservableCollection();
- foreach (PluginFeatureInfo pluginFeatureInfo in _plugin.Features)
- PluginFeatures.Add(settingsVmFactory.PluginFeatureViewModel(pluginFeatureInfo, false));
+ PluginFeatures = new ObservableCollection(_plugin.Features.Select(f => settingsVmFactory.PluginFeatureViewModel(f, false)));
}
public ReactiveCommand Reload { get; }
- public PluginViewModel PluginViewModel
- {
- get => _pluginViewModel;
- private set => RaiseAndSetIfChanged(ref _pluginViewModel, value);
- }
+ public PluginViewModel PluginViewModel { get; }
public ObservableCollection PluginFeatures { get; }
private async Task ExecuteReload()
{
+ // Unloading the plugin will remove this viewmodel, this method is it's final act 😭
bool wasEnabled = _plugin.IsEnabled;
await Task.Run(() => _pluginManagementService.UnloadPlugin(_plugin));
- PluginFeatures.Clear();
_plugin = _pluginManagementService.LoadPlugin(_plugin.Directory);
-
- PluginViewModel = _settingsVmFactory.PluginViewModel(_plugin, Reload);
- foreach (PluginFeatureInfo pluginFeatureInfo in _plugin.Features)
- PluginFeatures.Add(_settingsVmFactory.PluginFeatureViewModel(pluginFeatureInfo, false));
-
if (wasEnabled)
- await PluginViewModel.UpdateEnabled(true);
+ await Task.Run(() => _pluginManagementService.EnablePlugin(_plugin, true, true));
_notificationService.CreateNotification().WithTitle("Reloaded plugin.").Show();
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs
index 3568cfff7..260270e6b 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/DisplayCondition/DisplayConditionScriptViewModel.cs
@@ -44,7 +44,7 @@ public class DisplayConditionScriptViewModel : ActivatableViewModelBase
.DisposeWith(d);
});
- _conditionViewModel = this.WhenAnyValue(vm => vm.SelectedConditionTypeViewModel).Select(_ => CreateConditionViewModel()).ToProperty(this, vm => vm.ConditionViewModel);
+ _conditionViewModel = this.WhenAnyValue(vm => vm.SelectedConditionTypeViewModel, vm => vm.ProfileElement).Select(_ => CreateConditionViewModel()).ToProperty(this, vm => vm.ConditionViewModel);
}
public RenderProfileElement? ProfileElement => _profileElement?.Value;
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml
index 021b19b77..7889634a4 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml
@@ -40,6 +40,7 @@
Classes="icon-button icon-button-small"
ToolTip.Tip="Toggle suspended state"
IsChecked="{CompiledBinding Folder.Suspended}"
+ Focusable="False"
VerticalAlignment="Center"
Margin="4 0">
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemView.axaml
index 81907f35d..240a164d6 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemView.axaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/LayerTreeItemView.axaml
@@ -31,6 +31,7 @@
Classes="icon-button icon-button-small"
ToolTip.Tip="Toggle suspended state"
IsChecked="{CompiledBinding Layer.Suspended}"
+ Focusable="False"
VerticalAlignment="Center"
Margin="4 0">
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs
index 8773076e5..a9ad9f829 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/TreeItemViewModel.cs
@@ -31,6 +31,7 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
private ProfileElement? _profileElement;
private string? _renameValue;
private bool _renaming;
+ private TimeSpan _time;
protected TreeItemViewModel(TreeItemViewModel? parent,
ProfileElement? profileElement,
@@ -56,6 +57,7 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
this.WhenActivated(d =>
{
+ ProfileEditorService.Time.Subscribe(t => _time = t).DisposeWith(d);
ProfileEditorService.ProfileElement.Subscribe(element => _currentProfileElement = element).DisposeWith(d);
SubscribeToProfileElement(d);
CreateTreeItems();
@@ -173,6 +175,7 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
Observable.FromEventPattern(x => ProfileElement.ChildRemoved += x, x => ProfileElement.ChildRemoved -= x)
.Subscribe(c => RemoveTreeItemsIfFound(c.Sender, c.EventArgs.ProfileElement))
.DisposeWith(d);
+ ProfileElement.WhenAnyValue(e => e.Suspended).Subscribe(_ => ProfileEditorService.ChangeTime(_time)).DisposeWith(d);
}
protected void RemoveTreeItemsIfFound(object? sender, ProfileElement profileElement)
diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelNode.cs b/src/Artemis.VisualScripting/Nodes/DataModel/DataModelNode.cs
index 6a9a39c82..411f7c1f1 100644
--- a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelNode.cs
+++ b/src/Artemis.VisualScripting/Nodes/DataModel/DataModelNode.cs
@@ -42,16 +42,17 @@ public class DataModelNode : Node