diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs
index e6301860a..c238ae350 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Linq.Expressions;
using Artemis.Core.Plugins.Models;
using Artemis.Core.Services.Interfaces;
@@ -8,6 +9,24 @@ namespace Artemis.Core.Models.Profile.Conditions
{
public abstract class DisplayConditionOperator
{
+ ///
+ /// A read-only collection containing all primitive number types
+ ///
+ protected static IReadOnlyCollection NumberTypes = new List
+ {
+ typeof(sbyte),
+ typeof(byte),
+ typeof(short),
+ typeof(ushort),
+ typeof(int),
+ typeof(uint),
+ typeof(long),
+ typeof(ulong),
+ typeof(float),
+ typeof(double),
+ typeof(decimal)
+ };
+
private IDataModelService _dataModelService;
private bool _registered;
@@ -25,12 +44,12 @@ namespace Artemis.Core.Models.Profile.Conditions
///
/// Gets or sets the description of this logical operator
///
- public string Description { get; set; }
+ public abstract string Description { get; }
///
/// Gets or sets the icon of this logical operator
///
- public string Icon { get; set; }
+ public abstract string Icon { get; }
///
/// Creates a binary expression comparing two types
@@ -69,5 +88,12 @@ namespace Artemis.Core.Models.Profile.Conditions
// Profile editor service will call Unsubscribe
_dataModelService.RemoveConditionOperator(this);
}
+
+ public bool SupportsType(Type type)
+ {
+ if (type == null)
+ return true;
+ return CompatibleTypes.Any(t => t.IsAssignableFrom(type));
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/EqualsConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/EqualsConditionOperator.cs
new file mode 100644
index 000000000..9f2b3cee9
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/EqualsConditionOperator.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+namespace Artemis.Core.Models.Profile.Conditions.Operators
+{
+ public class EqualsConditionOperator : DisplayConditionOperator
+ {
+ public override IReadOnlyCollection CompatibleTypes => new List {typeof(object)};
+
+ public override string Description => "Equals";
+ public override string Icon => "Equal";
+
+ public override BinaryExpression CreateExpression(Type leftSideType, Type rightSideType)
+ {
+ var leftSideParameter = Expression.Parameter(leftSideType, "a");
+ var rightSideParameter = Expression.Parameter(rightSideType, "b");
+ return Expression.Equal(leftSideParameter, rightSideParameter);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanConditionOperator.cs
index 2d78469b0..058305ab7 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanConditionOperator.cs
@@ -6,20 +6,10 @@ namespace Artemis.Core.Models.Profile.Conditions.Operators
{
public class GreaterThanConditionOperator : DisplayConditionOperator
{
- public override IReadOnlyCollection CompatibleTypes => new List
- {
- typeof(sbyte),
- typeof(byte),
- typeof(short),
- typeof(ushort),
- typeof(int),
- typeof(uint),
- typeof(long),
- typeof(ulong),
- typeof(float),
- typeof(double),
- typeof(decimal)
- };
+ public override IReadOnlyCollection CompatibleTypes => NumberTypes;
+
+ public override string Description => "Is greater than";
+ public override string Icon => "GreaterThan";
public override BinaryExpression CreateExpression(Type leftSideType, Type rightSideType)
{
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs
new file mode 100644
index 000000000..a40aefcbc
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+namespace Artemis.Core.Models.Profile.Conditions.Operators
+{
+ public class GreaterThanOrEqualConditionOperator : DisplayConditionOperator
+ {
+ public override IReadOnlyCollection CompatibleTypes => NumberTypes;
+
+ public override string Description => "Is greater than or equal to";
+ public override string Icon => "GreaterThanOrEqual";
+
+ public override BinaryExpression CreateExpression(Type leftSideType, Type rightSideType)
+ {
+ var leftSideParameter = Expression.Parameter(leftSideType, "a");
+ var rightSideParameter = Expression.Parameter(rightSideType, "b");
+ return Expression.GreaterThanOrEqual(leftSideParameter, rightSideParameter);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanConditionOperator.cs
new file mode 100644
index 000000000..1ce2f1e3c
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanConditionOperator.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+namespace Artemis.Core.Models.Profile.Conditions.Operators
+{
+ public class LessThanConditionOperator : DisplayConditionOperator
+ {
+ public override IReadOnlyCollection CompatibleTypes => NumberTypes;
+
+ public override string Description => "Is less than";
+ public override string Icon => "LessThan";
+
+ public override BinaryExpression CreateExpression(Type leftSideType, Type rightSideType)
+ {
+ var leftSideParameter = Expression.Parameter(leftSideType, "a");
+ var rightSideParameter = Expression.Parameter(rightSideType, "b");
+ return Expression.LessThan(leftSideParameter, rightSideParameter);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanOrEqualConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanOrEqualConditionOperator.cs
new file mode 100644
index 000000000..cd2d75ccb
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanOrEqualConditionOperator.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+namespace Artemis.Core.Models.Profile.Conditions.Operators
+{
+ public class LessThanOrEqualConditionOperator : DisplayConditionOperator
+ {
+ public override IReadOnlyCollection CompatibleTypes => NumberTypes;
+
+ public override string Description => "Is less than or equal to";
+ public override string Icon => "LessThanOrEqual";
+
+ public override BinaryExpression CreateExpression(Type leftSideType, Type rightSideType)
+ {
+ var leftSideParameter = Expression.Parameter(leftSideType, "a");
+ var rightSideParameter = Expression.Parameter(rightSideType, "b");
+ return Expression.LessThanOrEqual(leftSideParameter, rightSideParameter);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/NotEqualConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/NotEqualConditionOperator.cs
new file mode 100644
index 000000000..00d83e516
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/NotEqualConditionOperator.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+namespace Artemis.Core.Models.Profile.Conditions.Operators
+{
+ public class NotEqualConditionOperator : DisplayConditionOperator
+ {
+ public override IReadOnlyCollection CompatibleTypes => new List { typeof(object) };
+
+ public override string Description => "Does not equal";
+ public override string Icon => "NotEqualVariant";
+
+ public override BinaryExpression CreateExpression(Type leftSideType, Type rightSideType)
+ {
+ var leftSideParameter = Expression.Parameter(leftSideType, "a");
+ var rightSideParameter = Expression.Parameter(rightSideType, "b");
+ return Expression.NotEqual(leftSideParameter, rightSideParameter);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/DataModelService.cs b/src/Artemis.Core/Services/DataModelService.cs
index 75cc7b729..dce63da5b 100644
--- a/src/Artemis.Core/Services/DataModelService.cs
+++ b/src/Artemis.Core/Services/DataModelService.cs
@@ -40,7 +40,18 @@ namespace Artemis.Core.Services
AddDataModelExpansionDataModel(dataModelExpansion);
}
- public ReadOnlyCollection DataModelExpansions
+ public IReadOnlyCollection RegisteredConditionOperators
+ {
+ get
+ {
+ lock (_registeredConditionOperators)
+ {
+ return _registeredConditionOperators.AsReadOnly();
+ }
+ }
+ }
+
+ public IReadOnlyCollection DataModelExpansions
{
get
{
@@ -128,13 +139,20 @@ namespace Artemis.Core.Services
{
lock (_registeredConditionOperators)
{
- return _registeredConditionOperators.Where(c => c.CompatibleTypes.Contains(type)).ToList();
+ if (type == null)
+ return new List(_registeredConditionOperators);
+ return _registeredConditionOperators.Where(c => c.CompatibleTypes.Any(t => t.IsAssignableFrom(type))).ToList();
}
}
private void RegisterBuiltInConditionOperators()
{
+ RegisterConditionOperator(Constants.CorePluginInfo, new EqualsConditionOperator());
+ RegisterConditionOperator(Constants.CorePluginInfo, new NotEqualConditionOperator());
+ RegisterConditionOperator(Constants.CorePluginInfo, new LessThanConditionOperator());
RegisterConditionOperator(Constants.CorePluginInfo, new GreaterThanConditionOperator());
+ RegisterConditionOperator(Constants.CorePluginInfo, new LessThanOrEqualConditionOperator());
+ RegisterConditionOperator(Constants.CorePluginInfo, new GreaterThanOrEqualConditionOperator());
}
private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
diff --git a/src/Artemis.Core/Services/Interfaces/IDataModelService.cs b/src/Artemis.Core/Services/Interfaces/IDataModelService.cs
index 57a7f27d1..24b6d5ab4 100644
--- a/src/Artemis.Core/Services/Interfaces/IDataModelService.cs
+++ b/src/Artemis.Core/Services/Interfaces/IDataModelService.cs
@@ -1,4 +1,5 @@
-using System.Collections.ObjectModel;
+using System;
+using System.Collections.Generic;
using Artemis.Core.Annotations;
using Artemis.Core.Models.Profile.Conditions;
using Artemis.Core.Plugins.Abstract;
@@ -9,7 +10,8 @@ namespace Artemis.Core.Services.Interfaces
{
public interface IDataModelService : IArtemisService
{
- ReadOnlyCollection DataModelExpansions { get; }
+ IReadOnlyCollection RegisteredConditionOperators { get; }
+ IReadOnlyCollection DataModelExpansions { get; }
///
/// Add an expansion to the datamodel to be available for use after the next update
@@ -48,5 +50,7 @@ namespace Artemis.Core.Services.Interfaces
///
/// The layer condition operator to remove
void RemoveConditionOperator([NotNull] DisplayConditionOperator displayConditionOperator);
+
+ List GetCompatibleConditionOperators(Type type);
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs
index 7bc781608..aaf767c55 100644
--- a/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs
+++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs
@@ -5,13 +5,26 @@ namespace Artemis.UI.Shared.DataModelVisualization
{
public abstract class DataModelInputViewModel : DataModelInputViewModel
{
- protected DataModelInputViewModel(DataModelPropertyAttribute description)
+ private T _inputValue;
+
+ protected DataModelInputViewModel(DataModelPropertyAttribute description, T initialValue)
{
Description = description;
+ InputValue = initialValue;
+ }
+
+ public T InputValue
+ {
+ get => _inputValue;
+ set => SetAndNotify(ref _inputValue, value);
}
public DataModelPropertyAttribute Description { get; }
internal override object InternalGuard { get; } = null;
+
+ protected void Submit()
+ {
+ }
}
///
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs
index 4c14e8c0f..77b136198 100644
--- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs
+++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Artemis.Core.Extensions;
@@ -19,6 +20,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
private DataModelVisualizationViewModel _parent;
private DataModelPropertyAttribute _propertyDescription;
private PropertyInfo _propertyInfo;
+ private bool _isMatchingFilteredTypes;
internal DataModelVisualizationViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, PropertyInfo propertyInfo)
{
@@ -26,6 +28,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
PropertyInfo = propertyInfo;
Parent = parent;
Children = new BindableCollection();
+ IsMatchingFilteredTypes = true;
if (dataModel == null && parent == null && propertyInfo == null)
IsRootViewModel = true;
@@ -65,6 +68,12 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
set => SetAndNotify(ref _children, value);
}
+ public bool IsMatchingFilteredTypes
+ {
+ get => _isMatchingFilteredTypes;
+ set => SetAndNotify(ref _isMatchingFilteredTypes, value);
+ }
+
public abstract void Update(IDataModelVisualizationService dataModelVisualizationService);
public virtual object GetCurrentValue()
@@ -72,6 +81,34 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared
return Parent == null ? null : PropertyInfo.GetValue(Parent.GetCurrentValue());
}
+ public void ApplyTypeFilter(params Type[] filteredTypes)
+ {
+ // If the VM has children, its own type is not relevant
+ if (Children.Any())
+ {
+ foreach (var child in Children)
+ child.ApplyTypeFilter(filteredTypes);
+
+ IsMatchingFilteredTypes = true;
+ return;
+ }
+
+ // If null is passed, clear the type filter
+ if (filteredTypes == null || filteredTypes.Length == 0)
+ {
+ IsMatchingFilteredTypes = true;
+ return;
+ }
+ // If this VM has no property info, assume it does not match
+ if (PropertyInfo == null)
+ {
+ IsMatchingFilteredTypes = false;
+ return;
+ }
+
+ IsMatchingFilteredTypes = filteredTypes.Any(t => t.IsAssignableFrom(PropertyInfo.PropertyType));
+ }
+
public DataModelVisualizationViewModel GetChildByPath(Guid dataModelGuid, string propertyPath)
{
var path = propertyPath.Split(".");
diff --git a/src/Artemis.UI.Shared/Services/DataModelVisualizationService.cs b/src/Artemis.UI.Shared/Services/DataModelVisualizationService.cs
index af71fa7df..b259f66d3 100644
--- a/src/Artemis.UI.Shared/Services/DataModelVisualizationService.cs
+++ b/src/Artemis.UI.Shared/Services/DataModelVisualizationService.cs
@@ -18,8 +18,6 @@ namespace Artemis.UI.Shared.Services
private readonly IKernel _kernel;
private readonly List _registeredDataModelDisplays;
private readonly List _registeredDataModelEditors;
- private DataModelPropertiesViewModel _cachedMainDataModel;
- private Dictionary _cachedDataModels;
public DataModelVisualizationService(IDataModelService dataModelService, IKernel kernel)
{
@@ -27,38 +25,24 @@ namespace Artemis.UI.Shared.Services
_kernel = kernel;
_registeredDataModelEditors = new List();
_registeredDataModelDisplays = new List();
- _cachedDataModels = new Dictionary();
}
public IReadOnlyCollection RegisteredDataModelEditors => _registeredDataModelEditors.AsReadOnly();
public IReadOnlyCollection RegisteredDataModelDisplays => _registeredDataModelDisplays.AsReadOnly();
- public DataModelPropertiesViewModel GetMainDataModelVisualization(bool useCache)
+ public DataModelPropertiesViewModel GetMainDataModelVisualization()
{
- // Return from cache if found
- if (useCache && _cachedMainDataModel != null)
- return _cachedMainDataModel;
-
var viewModel = new DataModelPropertiesViewModel(null, null, null);
foreach (var dataModelExpansion in _dataModelService.DataModelExpansions)
viewModel.Children.Add(new DataModelPropertiesViewModel(dataModelExpansion, viewModel, null));
// Update to populate children
viewModel.Update(this);
-
- // Add to cache
- _cachedMainDataModel = viewModel;
-
return viewModel;
}
- public DataModelPropertiesViewModel GetPluginDataModelVisualization(Plugin plugin, bool useCache)
+ public DataModelPropertiesViewModel GetPluginDataModelVisualization(Plugin plugin)
{
- // Return from cache if found
- var isCached = _cachedDataModels.TryGetValue(plugin, out var cachedMainDataModel);
- if (useCache && isCached)
- return cachedMainDataModel;
-
var dataModel = _dataModelService.GetPluginDataModel(plugin);
if (dataModel == null)
return null;
@@ -68,11 +52,6 @@ namespace Artemis.UI.Shared.Services
// Update to populate children
viewModel.Update(this);
-
- // Add to cache
- if (!isCached)
- _cachedDataModels.Add(plugin, viewModel);
-
return viewModel;
}
@@ -81,12 +60,6 @@ namespace Artemis.UI.Shared.Services
return _dataModelService.GetPluginExtendsDataModel(plugin);
}
- public void BustCache()
- {
- _cachedMainDataModel = null;
- _cachedDataModels.Clear();
- }
-
public DataModelVisualizationRegistration RegisterDataModelInput(PluginInfo pluginInfo) where T : DataModelInputViewModel
{
var viewModelType = typeof(T);
@@ -173,8 +146,8 @@ namespace Artemis.UI.Shared.Services
public interface IDataModelVisualizationService : IArtemisSharedUIService
{
- DataModelPropertiesViewModel GetMainDataModelVisualization(bool useCached);
- DataModelPropertiesViewModel GetPluginDataModelVisualization(Plugin plugin, bool useCached);
+ DataModelPropertiesViewModel GetMainDataModelVisualization();
+ DataModelPropertiesViewModel GetPluginDataModelVisualization(Plugin plugin);
///
/// Determines whether the given plugin expands the main data model
@@ -183,8 +156,6 @@ namespace Artemis.UI.Shared.Services
///
bool GetPluginExtendsDataModel(Plugin plugin);
- void BustCache();
-
DataModelVisualizationRegistration RegisterDataModelInput(PluginInfo pluginInfo) where T : DataModelInputViewModel;
DataModelVisualizationRegistration RegisterDataModelDisplay(PluginInfo pluginInfo) where T : DataModelDisplayViewModel;
void RemoveDataModelInput(DataModelVisualizationRegistration registration);
diff --git a/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs b/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs
index 62a761d62..bb5e9e677 100644
--- a/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs
+++ b/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs
@@ -22,6 +22,8 @@ namespace Artemis.UI.Shared.Services.Dialog
_viewManager = viewManager;
}
+ public bool IsExceptionDialogOpen { get; private set; }
+
public async Task ShowConfirmDialog(string header, string text, string confirmText = "Confirm", string cancelText = "Cancel")
{
var arguments = new IParameter[]
@@ -90,31 +92,28 @@ namespace Artemis.UI.Shared.Services.Dialog
public async Task ShowExceptionDialog(string message, Exception exception)
{
+ if (IsExceptionDialogOpen)
+ return;
+
+ IsExceptionDialogOpen = true;
var arguments = new IParameter[]
{
new ConstructorArgument("message", message),
new ConstructorArgument("exception", exception)
};
-
- try
+
+ await Execute.OnUIThreadAsync(async () =>
{
- await Execute.OnUIThreadAsync(async () =>
+ try
{
- try
- {
- DialogHost.CloseDialogCommand.Execute(new object(), null);
- await ShowDialog(arguments);
- }
- catch (Exception)
- {
- // ignored
- }
- });
- }
- catch (Exception)
- {
- // ignored
- }
+ DialogHost.CloseDialogCommand.Execute(new object(), null);
+ await ShowDialog(arguments);
+ }
+ finally
+ {
+ IsExceptionDialogOpen = false;
+ }
+ });
}
private async Task