diff --git a/src/Artemis.Core/JsonConverters/ForgivingIntConverter.cs b/src/Artemis.Core/JsonConverters/ForgivingIntConverter.cs new file mode 100644 index 000000000..77a09cb2b --- /dev/null +++ b/src/Artemis.Core/JsonConverters/ForgivingIntConverter.cs @@ -0,0 +1,31 @@ +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Artemis.Core.JsonConverters +{ + /// + /// An int converter that, if required, will round float values + /// + internal class ForgivingIntConverter : JsonConverter + { + public override bool CanWrite => false; + + public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + public override int ReadJson(JsonReader reader, Type objectType, int existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JValue jsonValue = serializer.Deserialize(reader); + + if (jsonValue.Type == JTokenType.Float) + return (int) Math.Round(jsonValue.Value()); + if (jsonValue.Type == JTokenType.Integer) + return jsonValue.Value(); + + throw new FormatException(); + } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/ConditionalDataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/ConditionalDataBinding.cs index 7b4e26a5b..765e0927c 100644 --- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/ConditionalDataBinding.cs +++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Conditional/ConditionalDataBinding.cs @@ -75,7 +75,7 @@ namespace Artemis.Core return condition; } - + /// /// Removes a condition from the conditional data binding's collection and disposes it /// diff --git a/src/Artemis.Core/Models/Profile/DataModel/DataModelEvent.cs b/src/Artemis.Core/Models/Profile/DataModel/DataModelEvent.cs index 0b94d541b..c9e2c32d8 100644 --- a/src/Artemis.Core/Models/Profile/DataModel/DataModelEvent.cs +++ b/src/Artemis.Core/Models/Profile/DataModel/DataModelEvent.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using Artemis.Core.DataModelExpansions; namespace Artemis.Core @@ -8,6 +10,45 @@ namespace Artemis.Core /// public class DataModelEvent : IDataModelEvent where T : DataModelEventArgs { + private bool _trackHistory; + + /// + /// Creates a new instance of the class with history tracking disabled + /// + public DataModelEvent() + { + } + + /// + /// Creates a new instance of the + /// + /// A boolean indicating whether the last 20 events should be tracked + public DataModelEvent(bool trackHistory) + { + _trackHistory = trackHistory; + } + + /// + [DataModelProperty(Name = "Last event trigger", Description = "The time at which the event last triggered")] + public DateTime LastTrigger { get; private set; } + + /// + /// Gets the event arguments of the last time the event was triggered + /// + [DataModelProperty(Description = "The arguments of the last time this event triggered")] + public T? LastEventArguments { get; private set; } + + /// + [DataModelProperty(Description = "The total amount of times this event has triggered since the module was activated")] + public int TriggerCount { get; private set; } + + /// + /// Gets a queue of the last 20 event arguments + /// Always empty if is + /// + [DataModelProperty(Description = "The arguments of the last time this event triggered")] + public Queue EventArgumentsHistory { get; } = new Queue(20); + /// /// Trigger the event with the given /// @@ -21,6 +62,16 @@ namespace Artemis.Core LastTrigger = DateTime.Now; TriggerCount++; + if (TrackHistory) + { + lock (EventArgumentsHistory) + { + if (EventArgumentsHistory.Count == 20) + EventArgumentsHistory.Dequeue(); + EventArgumentsHistory.Enqueue(eventArgs); + } + } + OnEventTriggered(); } @@ -30,26 +81,38 @@ namespace Artemis.Core } /// - public DateTime LastTrigger { get; private set; } - - /// - public int TriggerCount { get; private set; } - - /// - /// Gets the event arguments of the last time the event was triggered - /// - public T? LastEventArguments { get; private set; } + [DataModelIgnore] + public Type ArgumentsType => typeof(T); /// [DataModelIgnore] - public Type ArgumentsType => typeof(T); + public bool TrackHistory + { + get => _trackHistory; + set + { + EventArgumentsHistory.Clear(); + _trackHistory = value; + } + } /// [DataModelIgnore] public DataModelEventArgs? LastEventArgumentsUntyped => LastEventArguments; + /// + [DataModelIgnore] + public List EventArgumentsHistoryUntyped => EventArgumentsHistory.Cast().ToList(); + /// public event EventHandler? EventTriggered; + + /// + public void Reset() + { + TriggerCount = 0; + EventArgumentsHistory.Clear(); + } } /// @@ -57,6 +120,45 @@ namespace Artemis.Core /// public class DataModelEvent : IDataModelEvent { + private bool _trackHistory; + + /// + /// Creates a new instance of the class with history tracking disabled + /// + public DataModelEvent() + { + } + + /// + /// Creates a new instance of the + /// + /// A boolean indicating whether the last 20 events should be tracked + public DataModelEvent(bool trackHistory) + { + _trackHistory = trackHistory; + } + + /// + [DataModelProperty(Name = "Last event trigger", Description = "The time at which the event last triggered")] + public DateTime LastTrigger { get; private set; } + + /// + /// Gets the event arguments of the last time the event was triggered + /// + [DataModelProperty(Description = "The arguments of the last time this event triggered")] + public DataModelEventArgs? LastEventArguments { get; private set; } + + /// + [DataModelProperty(Description = "The total amount of times this event has triggered since the module was activated")] + public int TriggerCount { get; private set; } + + /// + /// Gets a queue of the last 20 event arguments + /// Always empty if is + /// + [DataModelProperty(Description = "The arguments of the last time this event triggered")] + public Queue EventArgumentsHistory { get; } = new Queue(20); + /// /// Trigger the event /// @@ -68,6 +170,16 @@ namespace Artemis.Core LastTrigger = DateTime.Now; TriggerCount++; + if (TrackHistory) + { + lock (EventArgumentsHistory) + { + if (EventArgumentsHistory.Count == 20) + EventArgumentsHistory.Dequeue(); + EventArgumentsHistory.Enqueue(eventArgs); + } + } + OnEventTriggered(); } @@ -75,27 +187,39 @@ namespace Artemis.Core { EventTriggered?.Invoke(this, EventArgs.Empty); } - - /// - public DateTime LastTrigger { get; private set; } - - /// - public int TriggerCount { get; private set; } - - /// - /// Gets the event arguments of the last time the event was triggered - /// - public DataModelEventArgs? LastEventArguments { get; private set; } - + /// [DataModelIgnore] public Type ArgumentsType => typeof(DataModelEventArgs); + /// + [DataModelIgnore] + public bool TrackHistory + { + get => _trackHistory; + set + { + EventArgumentsHistory.Clear(); + _trackHistory = value; + } + } + /// [DataModelIgnore] public DataModelEventArgs? LastEventArgumentsUntyped => LastEventArguments; + /// + [DataModelIgnore] + public List EventArgumentsHistoryUntyped => EventArgumentsHistory.ToList(); + /// public event EventHandler? EventTriggered; + + /// + public void Reset() + { + TriggerCount = 0; + EventArgumentsHistory.Clear(); + } } } \ No newline at end of file diff --git a/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs b/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs index 7d3897870..054257402 100644 --- a/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs +++ b/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -281,7 +280,7 @@ namespace Artemis.Core Entity.Path = Path; Entity.DataModelGuid = DataModelGuid; - + Entity.WrapperType = Target switch { ListPredicateWrapperDataModel _ => PathWrapperType.List, diff --git a/src/Artemis.Core/Models/Profile/DataModel/IDataModelEvent.cs b/src/Artemis.Core/Models/Profile/DataModel/IDataModelEvent.cs index d1643d159..36b9c3824 100644 --- a/src/Artemis.Core/Models/Profile/DataModel/IDataModelEvent.cs +++ b/src/Artemis.Core/Models/Profile/DataModel/IDataModelEvent.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Artemis.Core { @@ -19,14 +20,31 @@ namespace Artemis.Core /// Type ArgumentsType { get; } + /// + /// Gets or sets a boolean indicating whether the last 20 events should be tracked + /// Note: setting this to will clear the current history + /// + bool TrackHistory { get; set; } + /// /// Gets the event arguments of the last time the event was triggered by its base type /// public DataModelEventArgs? LastEventArgumentsUntyped { get; } + /// + /// Gets a list of the last 20 event arguments by their base type. + /// Always empty if is + /// + public List EventArgumentsHistoryUntyped { get; } + /// /// Fires when the event is triggered /// event EventHandler EventTriggered; + + /// + /// Resets the trigger count and history of this data model event + /// + void Reset(); } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs index 9098b1556..7901cb0a0 100644 --- a/src/Artemis.Core/Services/CoreService.cs +++ b/src/Artemis.Core/Services/CoreService.cs @@ -146,7 +146,7 @@ namespace Artemis.Core.Services { JsonConvert.DefaultSettings = () => new JsonSerializerSettings { - Converters = new List {new SKColorConverter()} + Converters = new List {new SKColorConverter(), new ForgivingIntConverter()} }; } diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs index 3e656da26..88f1a0933 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Input/DataModelDynamicViewModel.cs @@ -131,6 +131,8 @@ namespace Artemis.UI.Shared.Input } } + public bool LoadEventChildren { get; set; } = true; + public void ChangeDataModel(DataModelPropertiesViewModel dataModel) { if (DataModelViewModel != null) @@ -199,17 +201,17 @@ namespace Artemis.UI.Shared.Input private void OnUpdateTimerOnElapsed(object sender, ElapsedEventArgs e) { - // if (!IsDataModelViewModelOpen) - // return; - // - // UpdateDataModelVisualization(); + if (!IsDataModelViewModelOpen) + return; + + UpdateDataModelVisualization(); } private void UpdateDataModelVisualization() { - DataModelViewModel.Update(_dataModelUIService); + DataModelViewModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren)); foreach (DataModelPropertiesViewModel extraDataModelViewModel in ExtraDataModelViewModels) - extraDataModelViewModel.Update(_dataModelUIService); + extraDataModelViewModel.Update(_dataModelUIService, new DataModelUpdateConfiguration(LoadEventChildren)); } #endregion diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelEventViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelEventViewModel.cs index 9e0d64dac..93946c297 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelEventViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelEventViewModel.cs @@ -1,4 +1,6 @@ -using Artemis.Core; +using System; +using System.Linq; +using Artemis.Core; using Artemis.Core.DataModelExpansions; using Artemis.UI.Shared.Services; @@ -6,12 +8,36 @@ namespace Artemis.UI.Shared { public class DataModelEventViewModel : DataModelVisualizationViewModel { + private Type _displayValueType; + internal DataModelEventViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, DataModelPath dataModelPath) : base(dataModel, parent, dataModelPath) { } - public override void Update(IDataModelUIService dataModelUIService) + public Type DisplayValueType { + get => _displayValueType; + set => SetAndNotify(ref _displayValueType, value); + } + + public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) + { + DisplayValueType = DataModelPath?.GetPropertyType(); + + if (configuration != null) + { + if (configuration.CreateEventChildren) + PopulateProperties(dataModelUIService, configuration); + else if (Children.Any()) + Children.Clear(); + } + + // Only update children if the parent is expanded + if (Parent != null && !Parent.IsRootViewModel && !Parent.IsVisualizationExpanded) + return; + + foreach (DataModelVisualizationViewModel dataModelVisualizationViewModel in Children) + dataModelVisualizationViewModel.Update(dataModelUIService, configuration); } public override object GetCurrentValue() diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertiesViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertiesViewModel.cs index 4241b3179..e8e91d41f 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertiesViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertiesViewModel.cs @@ -39,17 +39,17 @@ namespace Artemis.UI.Shared public override string DisplayPath => null; - public override void Update(IDataModelUIService dataModelUIService) + public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) { ((ListPredicateWrapperDataModel) DataModel).UntypedValue = DisplayValue; - PopulateProperties(dataModelUIService); + PopulateProperties(dataModelUIService, configuration); if (DisplayViewModel == null) return; if (IsVisualizationExpanded && !DisplayViewModel.IsVisualizationExpanded) DisplayViewModel.IsVisualizationExpanded = IsVisualizationExpanded; - DisplayViewModel.Update(dataModelUIService); + DisplayViewModel.Update(dataModelUIService, null); } public override object GetCurrentValue() diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertyViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertyViewModel.cs index 4d6a1b9db..2f3fc3ddf 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertyViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListPropertyViewModel.cs @@ -39,7 +39,7 @@ namespace Artemis.UI.Shared return DisplayValue; } - public override void Update(IDataModelUIService dataModelUIService) + public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) { // Display value gets updated by parent, don't do anything if it is null if (DisplayValue == null) diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListViewModel.cs index 2b230020a..feac25943 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListViewModel.cs @@ -45,7 +45,7 @@ namespace Artemis.UI.Shared public BindableCollection ListChildren { get; set; } - public override void Update(IDataModelUIService dataModelUIService) + public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) { if (Parent != null && !Parent.IsVisualizationExpanded) return; @@ -83,7 +83,7 @@ namespace Artemis.UI.Shared dataModelListPropertyViewModel.Index = index; } - child.Update(dataModelUIService); + child.Update(dataModelUIService, configuration); index++; } diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertiesViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertiesViewModel.cs index 420551577..4ac8c0bc7 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertiesViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertiesViewModel.cs @@ -26,7 +26,7 @@ namespace Artemis.UI.Shared set => SetAndNotify(ref _displayValue, value); } - public override void Update(IDataModelUIService dataModelUIService) + public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) { DisplayValueType = DataModelPath?.GetPropertyType(); @@ -38,14 +38,14 @@ namespace Artemis.UI.Shared DisplayValue = null; // Always populate properties - PopulateProperties(dataModelUIService); + PopulateProperties(dataModelUIService, configuration); // Only update children if the parent is expanded if (Parent != null && !Parent.IsRootViewModel && !Parent.IsVisualizationExpanded) return; foreach (DataModelVisualizationViewModel dataModelVisualizationViewModel in Children) - dataModelVisualizationViewModel.Update(dataModelUIService); + dataModelVisualizationViewModel.Update(dataModelUIService, configuration); } public override object GetCurrentValue() diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertyViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertyViewModel.cs index 10be7eb85..4174176b8 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertyViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertyViewModel.cs @@ -33,7 +33,7 @@ namespace Artemis.UI.Shared set => SetAndNotify(ref _displayViewModel, value); } - public override void Update(IDataModelUIService dataModelUIService) + public override void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) { if (Parent != null && !Parent.IsVisualizationExpanded && !Parent.IsRootViewModel) return; diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs index dd960bc97..18e67c5e3 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs @@ -87,8 +87,9 @@ namespace Artemis.UI.Shared /// /// Updates the datamodel and if in an parent, any children /// - /// - public abstract void Update(IDataModelUIService dataModelUIService); + /// The data model UI service used during update + /// The configuration to apply while updating + public abstract void Update(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration); public virtual object GetCurrentValue() { @@ -147,7 +148,7 @@ namespace Artemis.UI.Shared return 0; } - internal void PopulateProperties(IDataModelUIService dataModelUIService) + internal void PopulateProperties(IDataModelUIService dataModelUIService, DataModelUpdateConfiguration dataModelUpdateConfiguration) { if (IsRootViewModel && DataModel == null) return; @@ -260,4 +261,14 @@ namespace Artemis.UI.Shared #endregion } + + public class DataModelUpdateConfiguration + { + public bool CreateEventChildren { get; } + + public DataModelUpdateConfiguration(bool createEventChildren) + { + CreateEventChildren = createEventChildren; + } + } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Extensions/DataModelWrapperExtensions.cs b/src/Artemis.UI.Shared/Extensions/DataModelWrapperExtensions.cs index de5bf9c94..8903a3d59 100644 --- a/src/Artemis.UI.Shared/Extensions/DataModelWrapperExtensions.cs +++ b/src/Artemis.UI.Shared/Extensions/DataModelWrapperExtensions.cs @@ -6,21 +6,21 @@ namespace Artemis.UI.Shared { public static class DataModelWrapperExtensions { - public static DataModelPropertiesViewModel CreateViewModel(this EventPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService) + public static DataModelPropertiesViewModel CreateViewModel(this EventPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) { DataModelPropertiesViewModel viewModel = new DataModelPropertiesViewModel(wrapper, null, new DataModelPath(wrapper)); - viewModel.Update(dataModelUIService); - viewModel.UpdateRequested += (sender, args) => viewModel.Update(dataModelUIService); + viewModel.Update(dataModelUIService, configuration); + viewModel.UpdateRequested += (sender, args) => viewModel.Update(dataModelUIService, configuration); viewModel.Children.First().IsVisualizationExpanded = true; return viewModel; } - public static DataModelPropertiesViewModel CreateViewModel(this ListPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService) + public static DataModelPropertiesViewModel CreateViewModel(this ListPredicateWrapperDataModel wrapper, IDataModelUIService dataModelUIService, DataModelUpdateConfiguration configuration) { DataModelPropertiesViewModel viewModel = new DataModelPropertiesViewModel(wrapper, null, new DataModelPath(wrapper)); - viewModel.Update(dataModelUIService); - viewModel.UpdateRequested += (sender, args) => viewModel.Update(dataModelUIService); + viewModel.Update(dataModelUIService, configuration); + viewModel.UpdateRequested += (sender, args) => viewModel.Update(dataModelUIService, configuration); viewModel.Children.First().IsVisualizationExpanded = true; return viewModel; diff --git a/src/Artemis.UI.Shared/Services/DataModelUIService.cs b/src/Artemis.UI.Shared/Services/DataModelUIService.cs index e5b440c9c..8f4e86ef1 100644 --- a/src/Artemis.UI.Shared/Services/DataModelUIService.cs +++ b/src/Artemis.UI.Shared/Services/DataModelUIService.cs @@ -37,8 +37,8 @@ namespace Artemis.UI.Shared.Services viewModel.Children.Add(new DataModelPropertiesViewModel(dataModelExpansion, viewModel, new DataModelPath(dataModelExpansion))); // Update to populate children - viewModel.Update(this); - viewModel.UpdateRequested += (sender, args) => viewModel.Update(this); + viewModel.Update(this, null); + viewModel.UpdateRequested += (sender, args) => viewModel.Update(this, null); return viewModel; } @@ -67,8 +67,8 @@ namespace Artemis.UI.Shared.Services viewModel.Children.Add(new DataModelPropertiesViewModel(dataModel, viewModel, null)); // Update to populate children - viewModel.Update(this); - viewModel.UpdateRequested += (sender, args) => viewModel.Update(this); + viewModel.Update(this, null); + viewModel.UpdateRequested += (sender, args) => viewModel.Update(this, null); return viewModel; } @@ -173,7 +173,7 @@ namespace Artemis.UI.Shared.Services else result = _kernel.Get(); - if (result != null) + if (result != null) result.PropertyDescription = description; return result; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs index 7a88e8b5b..0cae105e4 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Abstract/DataModelConditionViewModel.cs @@ -47,25 +47,11 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions.Abstract return true; } - // Event - if (IsEvent(newType)) - { - if (this is DataModelConditionEventViewModel) - return false; - groupViewModel.ConvertToConditionEvent(this); - return true; - } - // Predicate if (this is DataModelConditionPredicateViewModel) return false; groupViewModel.ConvertToPredicate(this); return true; } - - protected bool IsEvent(Type type) - { - return type == typeof(DataModelEvent) || type.IsGenericType && type.GetGenericTypeDefinition() == typeof(DataModelEvent<>); - } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs index 98f4d5905..324dd7e7e 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionEventViewModel.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Windows.Media; @@ -32,19 +32,11 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions { LeftSideSelectionViewModel = _dataModelUIService.GetDynamicSelectionViewModel(_profileEditorService.GetCurrentModule()); LeftSideSelectionViewModel.PropertySelected += LeftSideSelectionViewModelOnPropertySelected; + LeftSideSelectionViewModel.LoadEventChildren = false; IReadOnlyCollection editors = _dataModelUIService.RegisteredDataModelEditors; - List supportedInputTypes = editors.Select(e => e.SupportedType).ToList(); - supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes)); - supportedInputTypes.Add(typeof(IEnumerable<>)); - - // Events are only supported in the root group enforce that here - if (Parent is DataModelConditionGroupViewModel groupViewModel && groupViewModel.IsRootGroup) - { - supportedInputTypes.Add(typeof(DataModelEvent)); - supportedInputTypes.Add(typeof(DataModelEvent<>)); - } - + List supportedInputTypes = new List {typeof(DataModelEvent), typeof(DataModelEvent<>)}; + LeftSideSelectionViewModel.FilterTypes = supportedInputTypes.ToArray(); LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(185, 164, 10)); LeftSideSelectionViewModel.Placeholder = "Select an event"; @@ -84,11 +76,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions public void ApplyEvent() { - Type newType = LeftSideSelectionViewModel.DataModelPath.GetPropertyType(); - bool converted = ConvertIfRequired(newType); - if (converted) - return; - DataModelConditionEvent.UpdateEvent(LeftSideSelectionViewModel.DataModelPath); _profileEditorService.UpdateSelectedProfileElement(); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml index 7507ef77a..501a2162f 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupView.xaml @@ -18,6 +18,7 @@ + @@ -109,12 +110,20 @@ - + - + + + + + + diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs index 17ab0ecc6..69f9726fe 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionGroupViewModel.cs @@ -40,15 +40,21 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions }); } - public ConditionGroupType GroupType { get; set; } + public ConditionGroupType GroupType { get; } public DataModelConditionGroup DataModelConditionGroup => (DataModelConditionGroup) Model; public bool IsRootGroup { get => _isRootGroup; - set => SetAndNotify(ref _isRootGroup, value); + set + { + if (!SetAndNotify(ref _isRootGroup, value)) return; + NotifyOfPropertyChange(nameof(CanAddEventCondition)); + } } + public bool CanAddEventCondition => IsRootGroup && GroupType == ConditionGroupType.General; + public bool IsEventGroup { get => _isEventGroup; @@ -94,6 +100,23 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions _profileEditorService.UpdateSelectedProfileElement(); } + public void AddEventCondition() + { + if (!CanAddEventCondition) + return; + + // Find a good spot for the event, behind the last existing event + int index = 0; + DataModelConditionPart existing = DataModelConditionGroup.Children.LastOrDefault(c => c is DataModelConditionEvent); + if (existing != null) + index = DataModelConditionGroup.Children.IndexOf(existing) + 1; + + DataModelConditionGroup.AddChild(new DataModelConditionEvent(DataModelConditionGroup), index); + + Update(); + _profileEditorService.UpdateSelectedProfileElement(); + } + public void AddGroup() { DataModelConditionGroup.AddChild(new DataModelConditionGroup(DataModelConditionGroup)); @@ -171,24 +194,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions Update(); } - public void ConvertToConditionEvent(DataModelConditionViewModel predicateViewModel) - { - // Remove the old child - DataModelConditionGroup.RemoveChild(predicateViewModel.Model); - - DataModelConditionPart rootGroup = DataModelConditionGroup; - while (rootGroup.Parent != null) - rootGroup = rootGroup.Parent; - - // Insert an event at the start of the root group - DataModelConditionEvent conditionEvent = new DataModelConditionEvent(rootGroup); - conditionEvent.UpdateEvent(predicateViewModel.LeftSideSelectionViewModel.DataModelPath); - rootGroup.AddChild(conditionEvent, 0); - - // Update to switch the VMs - Update(); - } - public void ConvertToPredicate(DataModelConditionViewModel listViewModel) { // Store the old index and remove the old predicate diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs index 82986f02a..c1da5d680 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/DataModelConditionListViewModel.cs @@ -73,13 +73,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes)); supportedInputTypes.Add(typeof(IEnumerable<>)); - // Events are only supported in the root group enforce that here - if (Parent is DataModelConditionGroupViewModel groupViewModel && groupViewModel.IsRootGroup) - { - supportedInputTypes.Add(typeof(DataModelEvent)); - supportedInputTypes.Add(typeof(DataModelEvent<>)); - } - LeftSideSelectionViewModel.FilterTypes = supportedInputTypes.ToArray(); LeftSideSelectionViewModel.ButtonBrush = new SolidColorBrush(Color.FromRgb(71, 108, 188)); LeftSideSelectionViewModel.Placeholder = "Select a list"; diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateViewModel.cs index 2b7b8c28c..75326fef2 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionEventPredicateViewModel.cs @@ -67,7 +67,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions DataModelConditionEventPredicate.DataModelConditionEvent.EventArgumentType ); - return wrapper.CreateViewModel(_dataModelUIService); + return wrapper.CreateViewModel(_dataModelUIService, new DataModelUpdateConfiguration(false)); } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateViewModel.cs index 71b223f4c..5c7f781c5 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionGeneralPredicateViewModel.cs @@ -34,13 +34,6 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions supportedInputTypes.AddRange(editors.Where(e => e.CompatibleConversionTypes != null).SelectMany(e => e.CompatibleConversionTypes)); supportedInputTypes.Add(typeof(IEnumerable<>)); - // Events are only supported in the root group enforce that here - if (Parent is DataModelConditionGroupViewModel groupViewModel && groupViewModel.IsRootGroup) - { - supportedInputTypes.Add(typeof(DataModelEvent)); - supportedInputTypes.Add(typeof(DataModelEvent<>)); - } - return supportedInputTypes; } diff --git a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateViewModel.cs index f446d6672..59a0236cc 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Conditions/Predicate/DataModelConditionListPredicateViewModel.cs @@ -77,7 +77,7 @@ namespace Artemis.UI.Screens.ProfileEditor.Conditions DataModelConditionListPredicate.DataModelConditionList.ListType ); - return wrapper.CreateViewModel(_dataModelUIService); + return wrapper.CreateViewModel(_dataModelUIService, new DataModelUpdateConfiguration(true)); } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugView.xaml b/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugView.xaml index 2b211033c..f04946b2f 100644 --- a/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugView.xaml +++ b/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugView.xaml @@ -135,6 +135,25 @@ + + + + + + + + + + [] + + + + + + List item [] diff --git a/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugViewModel.cs b/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugViewModel.cs index 2446f2666..8d7e501ac 100644 --- a/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugViewModel.cs @@ -99,7 +99,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs { lock (MainDataModel) { - MainDataModel.Update(_dataModelUIService); + MainDataModel.Update(_dataModelUIService, null); } }