From 36391851719d015faba7195d6f116a226fdab966 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 7 Jul 2020 19:53:24 +0200 Subject: [PATCH] Display conditions - Loosened up type rules for dynamic comparisons Display conditions - Improved static value input and added support for int and double --- src/Artemis.Core/Artemis.Core.csproj | 1 - src/Artemis.Core/Extensions/TypeExtensions.cs | 55 ++++++++++++++++ .../Conditions/DisplayConditionOperator.cs | 3 +- src/Artemis.Core/Services/DataModelService.cs | 3 +- .../DataModelInputViewModel.cs | 13 ++++ .../Shared/DataModelVisualizationViewModel.cs | 11 ++-- src/Artemis.UI.Shared/FodyWeavers.xml | 5 -- src/Artemis.UI.Shared/FodyWeavers.xsd | 64 ------------------- .../Services/DataModelVisualizationService.cs | 7 +- src/Artemis.UI/Artemis.UI.csproj | 11 +++- .../Input/DoubleDataModelInputView.xaml | 18 ++++++ .../Input/DoubleDataModelInputViewModel.cs | 20 ++++++ .../Input/IntDataModelInputView.xaml | 18 ++++++ .../Input/IntDataModelInputViewModel.cs | 20 ++++++ .../Input/StringDataModelInputView.xaml | 2 +- src/Artemis.UI/FodyWeavers.xml | 5 -- src/Artemis.UI/FodyWeavers.xsd | 64 ------------------- .../DisplayConditionPredicateViewModel.cs | 45 ++++++------- .../Services/RegistrationService.cs | 2 + .../GeneralDataModel.cs | 1 + .../GeneralModule.cs | 1 + 21 files changed, 197 insertions(+), 172 deletions(-) delete mode 100644 src/Artemis.UI.Shared/FodyWeavers.xml delete mode 100644 src/Artemis.UI.Shared/FodyWeavers.xsd create mode 100644 src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputView.xaml create mode 100644 src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputViewModel.cs create mode 100644 src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputView.xaml create mode 100644 src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputViewModel.cs delete mode 100644 src/Artemis.UI/FodyWeavers.xml delete mode 100644 src/Artemis.UI/FodyWeavers.xsd diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 9e94b34a1..76547bbd5 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -35,7 +35,6 @@ - diff --git a/src/Artemis.Core/Extensions/TypeExtensions.cs b/src/Artemis.Core/Extensions/TypeExtensions.cs index 79d3e7027..02aab161f 100644 --- a/src/Artemis.Core/Extensions/TypeExtensions.cs +++ b/src/Artemis.Core/Extensions/TypeExtensions.cs @@ -1,9 +1,25 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; namespace Artemis.Core.Extensions { public static class TypeExtensions { + private static readonly Dictionary> PrimitiveTypeConversions = new Dictionary> + { + {typeof(decimal), new List {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char)}}, + {typeof(double), new List {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float)}}, + {typeof(float), new List {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float)}}, + {typeof(ulong), new List {typeof(byte), typeof(ushort), typeof(uint), typeof(char)}}, + {typeof(long), new List {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(char)}}, + {typeof(uint), new List {typeof(byte), typeof(ushort), typeof(char)}}, + {typeof(int), new List {typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(char)}}, + {typeof(ushort), new List {typeof(byte), typeof(char)}}, + {typeof(short), new List {typeof(byte)}} + }; + public static bool IsGenericType(this Type type, Type genericType) { if (type == null) @@ -17,6 +33,21 @@ namespace Artemis.Core.Extensions return source.IsValueType && !source.IsPrimitive && !source.IsEnum; } + public static bool TypeIsNumber(this Type type) + { + return type == typeof(sbyte) + || type == typeof(byte) + || type == typeof(short) + || type == typeof(ushort) + || type == typeof(int) + || type == typeof(uint) + || type == typeof(long) + || type == typeof(ulong) + || type == typeof(float) + || type == typeof(double) + || type == typeof(decimal); + } + public static bool IsNumber(this object value) { return value is sbyte @@ -31,5 +62,29 @@ namespace Artemis.Core.Extensions || value is double || value is decimal; } + + // From https://stackoverflow.com/a/2224421/5015269 but inverted and renamed to match similar framework methods + /// + /// Determines whether an instance of a specified type can be casted to a variable of the current type + /// + /// + /// + /// + public static bool IsCastableFrom(this Type to, Type from) + { + if (to.TypeIsNumber() && from.TypeIsNumber()) + return true; + if (to.IsAssignableFrom(from)) + return true; + if (PrimitiveTypeConversions.ContainsKey(to) && PrimitiveTypeConversions[to].Contains(from)) + return true; + var castable = from.GetMethods(BindingFlags.Public | BindingFlags.Static) + .Any( + m => m.ReturnType == to && + (m.Name == "op_Implicit" || + m.Name == "op_Explicit") + ); + return castable; + } } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs index c238ae350..895da9a24 100644 --- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs +++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using Artemis.Core.Extensions; using Artemis.Core.Plugins.Models; using Artemis.Core.Services.Interfaces; @@ -93,7 +94,7 @@ namespace Artemis.Core.Models.Profile.Conditions { if (type == null) return true; - return CompatibleTypes.Any(t => t.IsAssignableFrom(type)); + return CompatibleTypes.Any(t => t.IsCastableFrom(type)); } } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/DataModelService.cs b/src/Artemis.Core/Services/DataModelService.cs index dce63da5b..548257500 100644 --- a/src/Artemis.Core/Services/DataModelService.cs +++ b/src/Artemis.Core/Services/DataModelService.cs @@ -4,6 +4,7 @@ using System.Collections.ObjectModel; using System.Linq; using Artemis.Core.Events; using Artemis.Core.Exceptions; +using Artemis.Core.Extensions; using Artemis.Core.Models.Profile.Conditions; using Artemis.Core.Models.Profile.Conditions.Operators; using Artemis.Core.Plugins.Abstract; @@ -141,7 +142,7 @@ namespace Artemis.Core.Services { if (type == null) return new List(_registeredConditionOperators); - return _registeredConditionOperators.Where(c => c.CompatibleTypes.Any(t => t.IsAssignableFrom(type))).ToList(); + return _registeredConditionOperators.Where(c => c.CompatibleTypes.Any(t => t.IsCastableFrom(type))).ToList(); } } diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs index 100ed4e52..216cb829a 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelInputViewModel.cs @@ -1,5 +1,8 @@ using System; +using System.Threading.Tasks; using System.Windows; +using System.Windows.Data; +using System.Windows.Input; using Artemis.Core.Plugins.Abstract.DataModels.Attributes; using Stylet; @@ -27,6 +30,9 @@ namespace Artemis.UI.Shared.DataModelVisualization /// public sealed override void Submit() { + foreach (var sourceUpdatingBinding in BindingOperations.GetSourceUpdatingBindings(View)) + sourceUpdatingBinding.UpdateSource(); + OnSubmit(); UpdateCallback(InputValue, true); } @@ -58,6 +64,13 @@ namespace Artemis.UI.Shared.DataModelVisualization throw new InvalidOperationException(string.Format("Tried to attach View {0} to ViewModel {1}, but it already has a view attached", view.GetType().Name, GetType().Name)); View = view; + + // After the animation finishes attempt to focus the input field + Task.Run(async () => + { + await Task.Delay(400); + await Execute.OnUIThreadAsync(() => View.MoveFocus(new TraversalRequest(FocusNavigationDirection.First))); + }); } public UIElement View { get; set; } diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs index 77b136198..49fa8cc49 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs @@ -81,13 +81,13 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared return Parent == null ? null : PropertyInfo.GetValue(Parent.GetCurrentValue()); } - public void ApplyTypeFilter(params Type[] filteredTypes) + public void ApplyTypeFilter(bool looseMatch, 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); + child.ApplyTypeFilter(looseMatch, filteredTypes); IsMatchingFilteredTypes = true; return; @@ -99,6 +99,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared IsMatchingFilteredTypes = true; return; } + // If this VM has no property info, assume it does not match if (PropertyInfo == null) { @@ -106,7 +107,10 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared return; } - IsMatchingFilteredTypes = filteredTypes.Any(t => t.IsAssignableFrom(PropertyInfo.PropertyType)); + if (looseMatch) + IsMatchingFilteredTypes = filteredTypes.Any(t => t.IsCastableFrom(PropertyInfo.PropertyType)); + else + IsMatchingFilteredTypes = filteredTypes.Any(t => t == PropertyInfo.PropertyType); } public DataModelVisualizationViewModel GetChildByPath(Guid dataModelGuid, string propertyPath) @@ -129,7 +133,6 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared return child.GetChildByPath(dataModelGuid, string.Join(".", path.Skip(1))); return child; } - } public string GetCurrentPath() diff --git a/src/Artemis.UI.Shared/FodyWeavers.xml b/src/Artemis.UI.Shared/FodyWeavers.xml deleted file mode 100644 index ef627f96d..000000000 --- a/src/Artemis.UI.Shared/FodyWeavers.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/Artemis.UI.Shared/FodyWeavers.xsd b/src/Artemis.UI.Shared/FodyWeavers.xsd deleted file mode 100644 index 221aeb8a5..000000000 --- a/src/Artemis.UI.Shared/FodyWeavers.xsd +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - Used to control if the On_PropertyName_Changed feature is enabled. - - - - - Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form. - - - - - Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project. - - - - - Used to control if equality checks should use the Equals method resolved from the base class. - - - - - Used to control if equality checks should use the static Equals method resolved from the base class. - - - - - Used to turn off build warnings from this weaver. - - - - - Used to turn off build warnings about mismatched On_PropertyName_Changed methods. - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/DataModelVisualizationService.cs b/src/Artemis.UI.Shared/Services/DataModelVisualizationService.cs index 672e7ff9b..3623a5631 100644 --- a/src/Artemis.UI.Shared/Services/DataModelVisualizationService.cs +++ b/src/Artemis.UI.Shared/Services/DataModelVisualizationService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Artemis.Core.Extensions; using Artemis.Core.Plugins.Abstract; using Artemis.Core.Plugins.Abstract.DataModels.Attributes; using Artemis.Core.Plugins.Exceptions; @@ -150,9 +151,13 @@ namespace Artemis.UI.Shared.Services { lock (_registeredDataModelEditors) { - var match = _registeredDataModelEditors.FirstOrDefault(d => d.SupportedType.IsAssignableFrom(propertyType)); + var match = _registeredDataModelEditors.FirstOrDefault(d => d.SupportedType == propertyType); if (match != null) { + // The view models expecting value types shouldn't be given null, avoid that + if (initialValue == null && propertyType.IsValueType) + initialValue = Activator.CreateInstance(propertyType); + var parameters = new IParameter[] { new ConstructorArgument("description", description), diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index ff6bbe51b..7f31320f3 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -83,9 +83,6 @@ - - - @@ -309,4 +306,12 @@ Resources.resx + + + Designer + + + Designer + + \ No newline at end of file diff --git a/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputView.xaml b/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputView.xaml new file mode 100644 index 000000000..0fef737eb --- /dev/null +++ b/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputView.xaml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputViewModel.cs b/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputViewModel.cs new file mode 100644 index 000000000..5b9548213 --- /dev/null +++ b/src/Artemis.UI/DataModelVisualization/Input/DoubleDataModelInputViewModel.cs @@ -0,0 +1,20 @@ +using System.Text.RegularExpressions; +using System.Windows.Input; +using Artemis.Core.Plugins.Abstract.DataModels.Attributes; +using Artemis.UI.Shared.DataModelVisualization; + +namespace Artemis.UI.DataModelVisualization.Input +{ + public class DoubleDataModelInputViewModel : DataModelInputViewModel + { + public DoubleDataModelInputViewModel(DataModelPropertyAttribute description, double initialValue) : base(description, initialValue) + { + } + + public void NumberValidationTextBox(object sender, TextCompositionEventArgs e) + { + var regex = new Regex("^[.|,][0-9]+$|^[0-9]*[.|,]{0,1}[0-9]*$"); + e.Handled = !regex.IsMatch(e.Text); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputView.xaml b/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputView.xaml new file mode 100644 index 000000000..f7062c072 --- /dev/null +++ b/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputView.xaml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputViewModel.cs b/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputViewModel.cs new file mode 100644 index 000000000..ccd780489 --- /dev/null +++ b/src/Artemis.UI/DataModelVisualization/Input/IntDataModelInputViewModel.cs @@ -0,0 +1,20 @@ +using System.Text.RegularExpressions; +using System.Windows.Input; +using Artemis.Core.Plugins.Abstract.DataModels.Attributes; +using Artemis.UI.Shared.DataModelVisualization; + +namespace Artemis.UI.DataModelVisualization.Input +{ + public class IntDataModelInputViewModel : DataModelInputViewModel + { + public IntDataModelInputViewModel(DataModelPropertyAttribute description, int initialValue) : base(description, initialValue) + { + } + + public void NumberValidationTextBox(object sender, TextCompositionEventArgs e) + { + var regex = new Regex("[^0-9]+"); + e.Handled = regex.IsMatch(e.Text); + } + } +} \ No newline at end of file diff --git a/src/Artemis.UI/DataModelVisualization/Input/StringDataModelInputView.xaml b/src/Artemis.UI/DataModelVisualization/Input/StringDataModelInputView.xaml index f8edaeef5..406a9d5dc 100644 --- a/src/Artemis.UI/DataModelVisualization/Input/StringDataModelInputView.xaml +++ b/src/Artemis.UI/DataModelVisualization/Input/StringDataModelInputView.xaml @@ -9,7 +9,7 @@ xmlns:behaviors="clr-namespace:Artemis.UI.Shared.Behaviors;assembly=Artemis.UI.Shared" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> - + diff --git a/src/Artemis.UI/FodyWeavers.xml b/src/Artemis.UI/FodyWeavers.xml deleted file mode 100644 index ef627f96d..000000000 --- a/src/Artemis.UI/FodyWeavers.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/FodyWeavers.xsd b/src/Artemis.UI/FodyWeavers.xsd deleted file mode 100644 index 221aeb8a5..000000000 --- a/src/Artemis.UI/FodyWeavers.xsd +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - Used to control if the On_PropertyName_Changed feature is enabled. - - - - - Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form. - - - - - Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project. - - - - - Used to control if equality checks should use the Equals method resolved from the base class. - - - - - Used to control if equality checks should use the static Equals method resolved from the base class. - - - - - Used to turn off build warnings from this weaver. - - - - - Used to turn off build warnings about mismatched On_PropertyName_Changed methods. - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs index 288420fc4..c21bb75b6 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs @@ -113,7 +113,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions if (RightSideInputViewModel == null) return; - if (!message.KeyDown && message.EventArgs.Key == Key.Escape) + if (!message.KeyDown && message.EventArgs.Key == Key.Escape) RightSideInputViewModel.Cancel(); if (!message.KeyDown && message.EventArgs.Key == Key.Enter) RightSideInputViewModel.Submit(); @@ -124,7 +124,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions if (RightSideInputViewModel == null) return; - if (message.Sender is FrameworkElement frameworkElement && !frameworkElement.IsDescendantOf(RightSideInputViewModel.View)) + if (message.Sender is FrameworkElement frameworkElement && !frameworkElement.IsDescendantOf(RightSideInputViewModel.View)) RightSideInputViewModel.Submit(); } @@ -156,7 +156,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions // If static, only allow selecting properties also supported by input if (DisplayConditionPredicate.PredicateType == PredicateType.Static) - LeftSideDataModel.ApplyTypeFilter(_supportedInputTypes.ToArray()); + LeftSideDataModel.ApplyTypeFilter(false, _supportedInputTypes.ToArray()); // Determine the left side property first SelectedLeftSideProperty = DisplayConditionPredicate.LeftPropertyPath != null @@ -164,21 +164,29 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions : null; var leftSideType = SelectedLeftSideProperty?.PropertyInfo?.PropertyType; - // Right side may only select properties matching the left side - if (SelectedLeftSideProperty != null) - RightSideDataModel.ApplyTypeFilter(leftSideType); - else - RightSideDataModel.ApplyTypeFilter(); - - // Determine the right side property first - if (DisplayConditionPredicate.RightPropertyPath != null) + if (DisplayConditionPredicate.PredicateType == PredicateType.Dynamic) { - // Ensure the right side property still matches the left side type, else set it to null - var selectedProperty = RightSideDataModel.GetChildByPath(DisplayConditionPredicate.RightDataModelGuid, DisplayConditionPredicate.RightPropertyPath); - SelectedRightSideProperty = selectedProperty.IsMatchingFilteredTypes ? selectedProperty : null; + // Right side may only select properties matching the left side + if (SelectedLeftSideProperty != null) + RightSideDataModel.ApplyTypeFilter(true, leftSideType); + else + RightSideDataModel.ApplyTypeFilter(true); + + // Determine the right side property + if (DisplayConditionPredicate.RightPropertyPath != null) + { + // Ensure the right side property still matches the left side type, else set it to null + var selectedProperty = RightSideDataModel.GetChildByPath(DisplayConditionPredicate.RightDataModelGuid, DisplayConditionPredicate.RightPropertyPath); + SelectedRightSideProperty = selectedProperty.IsMatchingFilteredTypes ? selectedProperty : null; + } + else + SelectedRightSideProperty = null; } else - SelectedRightSideProperty = null; + { + if (DisplayConditionPredicate.RightStaticValue != null && DisplayConditionPredicate.RightStaticValue.GetType() != leftSideType) + DisplayConditionPredicate.RightStaticValue = null; + } // Get the supported operators Operators = _dataModelService.GetCompatibleConditionOperators(leftSideType); @@ -201,13 +209,6 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions UpdateInputValue ); _eventAggregator.Subscribe(this); - - // After the animation finishes attempt to focus the input field - Task.Run(async () => - { - await Task.Delay(400); - await Execute.OnUIThreadAsync(() => RightSideInputViewModel.View.MoveFocus(new TraversalRequest(FocusNavigationDirection.First))); - }); } public void UpdateInputValue(object value, bool isSubmitted) diff --git a/src/Artemis.UI/Services/RegistrationService.cs b/src/Artemis.UI/Services/RegistrationService.cs index 15cf49c12..af85d07a4 100644 --- a/src/Artemis.UI/Services/RegistrationService.cs +++ b/src/Artemis.UI/Services/RegistrationService.cs @@ -38,6 +38,8 @@ namespace Artemis.UI.Services return; _dataModelVisualizationService.RegisterDataModelInput(Constants.CorePluginInfo); + _dataModelVisualizationService.RegisterDataModelInput(Constants.CorePluginInfo); + _dataModelVisualizationService.RegisterDataModelInput(Constants.CorePluginInfo); _registeredBuiltInDataModelInputs = true; } diff --git a/src/Plugins/Artemis.Plugins.Modules.General/GeneralDataModel.cs b/src/Plugins/Artemis.Plugins.Modules.General/GeneralDataModel.cs index a5a397bf3..03e286e1a 100644 --- a/src/Plugins/Artemis.Plugins.Modules.General/GeneralDataModel.cs +++ b/src/Plugins/Artemis.Plugins.Modules.General/GeneralDataModel.cs @@ -26,6 +26,7 @@ namespace Artemis.Plugins.Modules.General public PlayerInfo PlayerInfo { get; set; } public double UpdatesDividedByFour { get; set; } + public int Updates { get; set; } public List IntsList { get; set; } public List PlayerInfosList { get; set; } diff --git a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs index 5a349de3b..312cc144d 100644 --- a/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs +++ b/src/Plugins/Artemis.Plugins.Modules.General/GeneralModule.cs @@ -27,6 +27,7 @@ namespace Artemis.Plugins.Modules.General public override void Update(double deltaTime) { DataModel.UpdatesDividedByFour += 0.25; + DataModel.Updates += 1; DataModel.PlayerInfo.Position = new SKPoint(_rand.Next(100), _rand.Next(100)); DataModel.IntsList[0] = _rand.Next();