diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs index fd8485857..0e08216d0 100644 --- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs +++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs @@ -25,6 +25,7 @@ namespace Artemis.Core.Models.Profile.Conditions { Parent = parent; DisplayConditionPredicateEntity = entity; + PredicateType = (PredicateType) entity.PredicateType; } public DisplayConditionPredicateEntity DisplayConditionPredicateEntity { get; set; } @@ -124,6 +125,9 @@ namespace Artemis.Core.Models.Profile.Conditions StaticConditionLambda = null; CompiledStaticConditionLambda = null; + if (Operator == null) + return; + // If the operator does not support a right side, create a static expression because the right side will simply be null if (PredicateType == PredicateType.Dynamic && Operator.SupportsRightSide) CreateDynamicExpression(); @@ -133,6 +137,7 @@ namespace Artemis.Core.Models.Profile.Conditions internal override void ApplyToEntity() { + DisplayConditionPredicateEntity.PredicateType = (int)PredicateType; DisplayConditionPredicateEntity.LeftDataModelGuid = LeftDataModel?.PluginInfo?.Guid; DisplayConditionPredicateEntity.LeftPropertyPath = LeftPropertyPath; @@ -173,14 +178,14 @@ namespace Artemis.Core.Models.Profile.Conditions } // Right side dynamic - if (DisplayConditionPredicateEntity.RightDataModelGuid != null) + if (PredicateType == PredicateType.Dynamic && DisplayConditionPredicateEntity.RightDataModelGuid != null) { var dataModel = dataModelService.GetPluginDataModelByGuid(DisplayConditionPredicateEntity.RightDataModelGuid.Value); if (dataModel != null && dataModel.ContainsPath(DisplayConditionPredicateEntity.RightPropertyPath)) UpdateRightSide(dataModel, DisplayConditionPredicateEntity.RightPropertyPath); } // Right side static - else if (DisplayConditionPredicateEntity.RightStaticValue != null) + else if (PredicateType == PredicateType.Static && DisplayConditionPredicateEntity.RightStaticValue != null) { try { @@ -188,7 +193,20 @@ namespace Artemis.Core.Models.Profile.Conditions { // Use the left side type so JSON.NET has a better idea what to do var leftSideType = LeftDataModel.GetTypeAtPath(LeftPropertyPath); - UpdateRightSide(JsonConvert.DeserializeObject(DisplayConditionPredicateEntity.RightStaticValue, leftSideType)); + object rightSideValue; + + try + { + rightSideValue = JsonConvert.DeserializeObject(DisplayConditionPredicateEntity.RightStaticValue, leftSideType); + } + // If deserialization fails, use the type's default + catch (JsonSerializationException e) + { + dataModelService.LogDeserializationFailure(this, e); + rightSideValue = Activator.CreateInstance(leftSideType); + } + + UpdateRightSide(rightSideValue); } else { @@ -265,7 +283,7 @@ namespace Artemis.Core.Models.Profile.Conditions private void CreateDynamicExpression() { - if (LeftDataModel == null || RightDataModel == null) + if (LeftDataModel == null || RightDataModel == null || Operator == null) return; var leftSideParameter = Expression.Parameter(typeof(DataModel), "leftDataModel"); @@ -306,8 +324,8 @@ namespace Artemis.Core.Models.Profile.Conditions return; // If the right side value is null, the constant type cannot be inferred and must be provided manually - var rightSideConstant = RightStaticValue != null - ? Expression.Constant(RightStaticValue) + var rightSideConstant = RightStaticValue != null + ? Expression.Constant(RightStaticValue) : Expression.Constant(null, leftSideAccessor.Type); var conditionExpression = Operator.CreateExpression(leftSideAccessor, rightSideConstant); @@ -315,6 +333,13 @@ namespace Artemis.Core.Models.Profile.Conditions StaticConditionLambda = Expression.Lambda>(conditionExpression, leftSideParameter); CompiledStaticConditionLambda = StaticConditionLambda.Compile(); } + + public override string ToString() + { + if (PredicateType == PredicateType.Dynamic) + return $"[Dynamic] {LeftPropertyPath} {Operator.Description} {RightPropertyPath}"; + return $"[Static] {LeftPropertyPath} {Operator.Description} {RightStaticValue}"; + } } public enum PredicateType diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index f269b5ab3..6f93f36c7 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -223,12 +223,14 @@ namespace Artemis.Core.Models.Profile // Ensure the layer must still be displayed UpdateDisplayCondition(); - // TODO: No point updating further than this if the layer is not going to be rendered - // Update the layer timeline, this will give us a new delta time which could be negative in case the main segment wrapped back // to it's start UpdateTimeline(deltaTime); + // No point updating further than this if the layer is not going to be rendered + if (TimelinePosition > TimelineLength) + return; + General.Update(); Transform.Update(); LayerBrush.BaseProperties?.Update(); @@ -285,7 +287,7 @@ namespace Artemis.Core.Models.Profile /// public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo) { - if (!Enabled) + if (!Enabled || TimelinePosition > TimelineLength) return; // Ensure the layer is ready diff --git a/src/Artemis.Core/Plugins/Abstract/BaseDataModelExpansion.cs b/src/Artemis.Core/Plugins/Abstract/BaseDataModelExpansion.cs index 28847607b..6aae3af27 100644 --- a/src/Artemis.Core/Plugins/Abstract/BaseDataModelExpansion.cs +++ b/src/Artemis.Core/Plugins/Abstract/BaseDataModelExpansion.cs @@ -1,6 +1,12 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; using Artemis.Core.Plugins.Abstract.DataModels; using Artemis.Core.Plugins.Abstract.DataModels.Attributes; +using Artemis.Core.Utilities; namespace Artemis.Core.Plugins.Abstract { @@ -18,6 +24,27 @@ namespace Artemis.Core.Plugins.Abstract internal set => InternalDataModel = value; } + /// + /// Hide the provided property using a lambda expression, e.g. HideProperty(dm => dm.TimeDataModel.CurrentTimeUTC) + /// + /// A lambda expression pointing to the property to ignore + public void HideProperty(Expression> propertyLambda) + { + var propertyInfo = ReflectionUtilities.GetPropertyInfo(DataModel, propertyLambda); + if (!HiddenPropertiesList.Any(p => p.Equals(propertyInfo))) + HiddenPropertiesList.Add(propertyInfo); + } + + /// + /// Stop hiding the provided property using a lambda expression, e.g. ShowProperty(dm => dm.TimeDataModel.CurrentTimeUTC) + /// + /// A lambda expression pointing to the property to stop ignoring + public void ShowProperty(Expression> propertyLambda) + { + var propertyInfo = ReflectionUtilities.GetPropertyInfo(DataModel, propertyLambda); + HiddenPropertiesList.RemoveAll(p => p.Equals(propertyInfo)); + } + internal override void InternalEnablePlugin() { DataModel = Activator.CreateInstance(); @@ -39,6 +66,13 @@ namespace Artemis.Core.Plugins.Abstract /// public abstract class BaseDataModelExpansion : Plugin { + protected readonly List HiddenPropertiesList = new List(); + + /// + /// Gets a list of all properties ignored at runtime using IgnoreProperty(x => x.y) + /// + public ReadOnlyCollection HiddenProperties => HiddenPropertiesList.AsReadOnly(); + internal DataModel InternalDataModel { get; set; } public abstract void Update(double deltaTime); diff --git a/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs b/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs index 5720867d1..69c22364a 100644 --- a/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs +++ b/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Reflection; using Artemis.Core.Plugins.Abstract.DataModels.Attributes; using Artemis.Core.Plugins.Models; @@ -51,5 +54,19 @@ namespace Artemis.Core.Plugins.Abstract.DataModels return result; } + + /// + /// Returns a read-only list of all properties in this datamodel that are to be ignored + /// + /// + public ReadOnlyCollection GetHiddenProperties() + { + if (PluginInfo.Instance is ProfileModule profileModule) + return profileModule.HiddenProperties; + if (PluginInfo.Instance is BaseDataModelExpansion dataModelExpansion) + return dataModelExpansion.HiddenProperties; + + return new List().AsReadOnly(); + } } } \ No newline at end of file diff --git a/src/Artemis.Core/Plugins/Abstract/Module.cs b/src/Artemis.Core/Plugins/Abstract/Module.cs index 6c2e2bcab..5592004e9 100644 --- a/src/Artemis.Core/Plugins/Abstract/Module.cs +++ b/src/Artemis.Core/Plugins/Abstract/Module.cs @@ -84,7 +84,7 @@ namespace Artemis.Core.Plugins.Abstract /// /// Called each frame when the module must update /// - /// Time since the last update + /// Time in seconds since the last update public abstract void Update(double deltaTime); /// diff --git a/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs b/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs index 8c3582854..76dd755fb 100644 --- a/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs +++ b/src/Artemis.Core/Plugins/Abstract/ProfileModule.cs @@ -1,16 +1,22 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; using Artemis.Core.Exceptions; using Artemis.Core.Models.Profile; using Artemis.Core.Models.Surface; using Artemis.Core.Plugins.Abstract.DataModels; using Artemis.Core.Plugins.Abstract.DataModels.Attributes; -using Artemis.Core.Plugins.Models; +using Artemis.Core.Utilities; using SkiaSharp; namespace Artemis.Core.Plugins.Abstract { /// - /// Allows you to add support for new games/applications while utilizing Artemis' profile engine and your own data model + /// Allows you to add support for new games/applications while utilizing Artemis' profile engine and your own data + /// model /// public abstract class ProfileModule : ProfileModule where T : DataModel { @@ -45,7 +51,29 @@ namespace Artemis.Core.Plugins.Abstract { return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description}; } - + + /// + /// Hide the provided property using a lambda expression, e.g. HideProperty(dm => dm.TimeDataModel.CurrentTimeUTC) + /// + /// A lambda expression pointing to the property to ignore + public void HideProperty(Expression> propertyLambda) + { + var propertyInfo = ReflectionUtilities.GetPropertyInfo(DataModel, propertyLambda); + if (!HiddenPropertiesList.Any(p => p.Equals(propertyInfo))) + HiddenPropertiesList.Add(propertyInfo); + } + + /// + /// Stop hiding the provided property using a lambda expression, e.g. ShowProperty(dm => + /// dm.TimeDataModel.CurrentTimeUTC) + /// + /// A lambda expression pointing to the property to stop ignoring + public void ShowProperty(Expression> propertyLambda) + { + var propertyInfo = ReflectionUtilities.GetPropertyInfo(DataModel, propertyLambda); + HiddenPropertiesList.RemoveAll(p => p.Equals(propertyInfo)); + } + internal override void InternalEnablePlugin() { DataModel = Activator.CreateInstance(); @@ -66,15 +94,28 @@ namespace Artemis.Core.Plugins.Abstract /// public abstract class ProfileModule : Module { + protected readonly List HiddenPropertiesList = new List(); + + /// + /// Gets a list of all properties ignored at runtime using IgnoreProperty(x => x.y) + /// + public ReadOnlyCollection HiddenProperties => HiddenPropertiesList.AsReadOnly(); + public Profile ActiveProfile { get; private set; } + /// + /// Disables updating the profile, rendering does continue + /// + public bool IsProfileUpdatingDisabled { get; set; } + /// public override void Update(double deltaTime) { lock (this) { // Update the profile - ActiveProfile?.Update(deltaTime); + if (!IsProfileUpdatingDisabled) + ActiveProfile?.Update(deltaTime); } } diff --git a/src/Artemis.Core/Plugins/Abstract/ViewModels/ModuleViewModel.cs b/src/Artemis.Core/Plugins/Abstract/ViewModels/ModuleViewModel.cs index b1d599d36..cd1247e35 100644 --- a/src/Artemis.Core/Plugins/Abstract/ViewModels/ModuleViewModel.cs +++ b/src/Artemis.Core/Plugins/Abstract/ViewModels/ModuleViewModel.cs @@ -2,14 +2,25 @@ namespace Artemis.Core.Plugins.Abstract.ViewModels { + /// + /// The base class for any view model that belongs to a module + /// public abstract class ModuleViewModel : Screen { + /// + /// The base class for any view model that belongs to a module + /// + /// The module this view model belongs to + /// The name of the tab that's shown on the modules UI page protected ModuleViewModel(Module module, string displayName) { Module = module; DisplayName = displayName; } + /// + /// Gets the module this view model belongs to + /// public Module Module { get; } } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs index f70ddbf13..3f7d154f1 100644 --- a/src/Artemis.Core/Services/CoreService.cs +++ b/src/Artemis.Core/Services/CoreService.cs @@ -60,7 +60,6 @@ namespace Artemis.Core.Services } public TimeSpan FrameTime { get; private set; } - public bool PluginUpdatingDisabled { get; set; } public bool ModuleRenderingDisabled { get; set; } public List StartupArguments { get; set; } @@ -140,21 +139,18 @@ namespace Artemis.Core.Services try { _frameStopWatch.Restart(); - if (!PluginUpdatingDisabled) + lock (_dataModelExpansions) { - lock (_dataModelExpansions) - { - // Update all active modules - foreach (var dataModelExpansion in _dataModelExpansions) - dataModelExpansion.Update(args.DeltaTime); - } + // Update all active modules + foreach (var dataModelExpansion in _dataModelExpansions) + dataModelExpansion.Update(args.DeltaTime); + } - lock (_modules) - { - // Update all active modules - foreach (var module in _modules) - module.Update(args.DeltaTime); - } + lock (_modules) + { + // Update all active modules + foreach (var module in _modules) + module.Update(args.DeltaTime); } // If there is no ready bitmap brush, skip the frame diff --git a/src/Artemis.Core/Services/DataModelService.cs b/src/Artemis.Core/Services/DataModelService.cs index 4c29ecadc..54c48978f 100644 --- a/src/Artemis.Core/Services/DataModelService.cs +++ b/src/Artemis.Core/Services/DataModelService.cs @@ -12,6 +12,8 @@ using Artemis.Core.Plugins.Abstract.DataModels; using Artemis.Core.Plugins.Exceptions; using Artemis.Core.Plugins.Models; using Artemis.Core.Services.Interfaces; +using Newtonsoft.Json; +using Serilog; namespace Artemis.Core.Services { @@ -22,11 +24,13 @@ namespace Artemis.Core.Services { private readonly List _dataModelExpansions; private readonly IPluginService _pluginService; + private readonly ILogger _logger; private readonly List _registeredConditionOperators; - internal DataModelService(IPluginService pluginService) + internal DataModelService(IPluginService pluginService, ILogger logger) { _pluginService = pluginService; + _logger = logger; _dataModelExpansions = new List(); _registeredConditionOperators = new List(); @@ -174,6 +178,11 @@ namespace Artemis.Core.Services return RegisteredConditionOperators.FirstOrDefault(o => o.PluginInfo.Guid == operatorPluginGuid && o.GetType().Name == operatorType); } + public void LogDeserializationFailure(DisplayConditionPredicate displayConditionPredicate, JsonSerializationException exception) + { + _logger.Warning(exception, "Failed to deserialize display condition predicate {predicate}", displayConditionPredicate); + } + private void RegisterBuiltInConditionOperators() { // General usage for any type diff --git a/src/Artemis.Core/Services/Interfaces/ICoreService.cs b/src/Artemis.Core/Services/Interfaces/ICoreService.cs index b16b39904..34a3969ee 100644 --- a/src/Artemis.Core/Services/Interfaces/ICoreService.cs +++ b/src/Artemis.Core/Services/Interfaces/ICoreService.cs @@ -15,12 +15,7 @@ namespace Artemis.Core.Services.Interfaces /// The time the last frame took to render /// TimeSpan FrameTime { get; } - - /// - /// Gets or sets whether modules are updated each frame by calling their Update method - /// - bool PluginUpdatingDisabled { get; set; } - + /// /// Gets or sets whether modules are rendered each frame by calling their Render method /// diff --git a/src/Artemis.Core/Services/Interfaces/IDataModelService.cs b/src/Artemis.Core/Services/Interfaces/IDataModelService.cs index f3d291cfc..e8d985889 100644 --- a/src/Artemis.Core/Services/Interfaces/IDataModelService.cs +++ b/src/Artemis.Core/Services/Interfaces/IDataModelService.cs @@ -5,6 +5,7 @@ using Artemis.Core.Models.Profile.Conditions; using Artemis.Core.Plugins.Abstract; using Artemis.Core.Plugins.Abstract.DataModels; using Artemis.Core.Plugins.Models; +using Newtonsoft.Json; namespace Artemis.Core.Services.Interfaces { @@ -59,5 +60,6 @@ namespace Artemis.Core.Services.Interfaces List GetCompatibleConditionOperators(Type type); DisplayConditionOperator GetConditionOperator(Guid operatorPluginGuid, string operatorType); + void LogDeserializationFailure(DisplayConditionPredicate displayConditionPredicate, JsonSerializationException exception); } } \ No newline at end of file diff --git a/src/Artemis.Core/Utilities/ReflectionUtilities.cs b/src/Artemis.Core/Utilities/ReflectionUtilities.cs new file mode 100644 index 000000000..ccc2e4a76 --- /dev/null +++ b/src/Artemis.Core/Utilities/ReflectionUtilities.cs @@ -0,0 +1,24 @@ +using System; +using System.Linq.Expressions; +using System.Reflection; + +namespace Artemis.Core.Utilities +{ + public static class ReflectionUtilities + { + public static PropertyInfo GetPropertyInfo(TSource source, Expression> propertyLambda) + { + var type = typeof(TSource); + + var member = propertyLambda.Body as MemberExpression; + if (member == null) + throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", propertyLambda)); + + var propInfo = member.Member as PropertyInfo; + if (propInfo == null) + throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", propertyLambda)); + + return propInfo; + } + } +} \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/DisplayConditionPredicateEntity.cs b/src/Artemis.Storage/Entities/Profile/DisplayConditionPredicateEntity.cs index 567a5b066..2e29e01ad 100644 --- a/src/Artemis.Storage/Entities/Profile/DisplayConditionPredicateEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/DisplayConditionPredicateEntity.cs @@ -5,6 +5,7 @@ namespace Artemis.Storage.Entities.Profile { public class DisplayConditionPredicateEntity : DisplayConditionPartEntity { + public int PredicateType { get; set; } public Guid? LeftDataModelGuid { get; set; } public string LeftPropertyPath { get; set; } diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertiesViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertiesViewModel.cs index 78c3aaadc..f089da6e1 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertiesViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertiesViewModel.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using System.Reflection; using Artemis.Core.Plugins.Abstract.DataModels; using Artemis.UI.Shared.Services; @@ -31,16 +32,29 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared private void PopulateProperties(IDataModelVisualizationService dataModelVisualizationService) { - if (Children.Any()) + if (IsRootViewModel) return; + // Add missing children var modelType = Parent.IsRootViewModel ? DataModel.GetType() : PropertyInfo.PropertyType; - foreach (var propertyInfo in modelType.GetProperties()) + foreach (var propertyInfo in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { + if (Children.Any(c => c.PropertyInfo.Equals(propertyInfo))) + continue; + var child = CreateChild(dataModelVisualizationService, propertyInfo, GetChildDepth()); if (child != null) Children.Add(child); } + + // Remove children that should be hidden + var childList = new List(Children); + var hiddenProperties = DataModel.GetHiddenProperties(); + foreach (var dataModelVisualizationViewModel in childList) + { + if (hiddenProperties.Contains(dataModelVisualizationViewModel.PropertyInfo)) + Children.Remove(dataModelVisualizationViewModel); + } } protected int GetChildDepth() diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs index 287ee237f..25bede591 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs @@ -1,9 +1,12 @@ using System; using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Reflection; using Artemis.Core.Extensions; using Artemis.Core.Models.Profile.Conditions; +using Artemis.Core.Plugins.Abstract; using Artemis.Core.Plugins.Abstract.DataModels; using Artemis.Core.Plugins.Abstract.DataModels.Attributes; using Artemis.UI.Shared.Exceptions; @@ -23,6 +26,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared private DataModelVisualizationViewModel _parent; private DataModelPropertyAttribute _propertyDescription; private PropertyInfo _propertyInfo; + private bool _isIgnored; internal DataModelVisualizationViewModel(DataModel dataModel, DataModelVisualizationViewModel parent, PropertyInfo propertyInfo) { @@ -31,7 +35,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared Parent = parent; Children = new BindableCollection(); IsMatchingFilteredTypes = true; - + if (dataModel == null && parent == null && propertyInfo == null) IsRootViewModel = true; else @@ -118,7 +122,7 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared } /// - /// Updates the datamodel and if in an parent, any children + /// Updates the datamodel and if in an parent, any children /// /// public abstract void Update(IDataModelVisualizationService dataModelVisualizationService); @@ -231,6 +235,9 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared // Skip properties decorated with DataModelIgnore if (Attribute.IsDefined(propertyInfo, typeof(DataModelIgnoreAttribute))) return null; + // Skip properties that are in the ignored properties list of the respective profile module/data model expansion + if (DataModel.GetHiddenProperties().Any(p => p.Equals(propertyInfo))) + return null; // If a display VM was found, prefer to use that in any case var typeViewModel = dataModelVisualizationService.GetDataModelDisplayViewModel(propertyInfo.PropertyType); @@ -248,17 +255,6 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared return null; } - #region Events - - public event EventHandler UpdateRequested; - - protected virtual void OnUpdateRequested() - { - UpdateRequested?.Invoke(this, EventArgs.Empty); - } - - #endregion - private void RequestUpdate() { Parent?.RequestUpdate(); @@ -283,6 +279,17 @@ namespace Artemis.UI.Shared.DataModelVisualization.Shared if (PropertyDescription != null && PropertyDescription.Name == null && PropertyInfo != null) PropertyDescription.Name = PropertyInfo.Name.Humanize(); } + + #region Events + + public event EventHandler UpdateRequested; + + protected virtual void OnUpdateRequested() + { + UpdateRequested?.Invoke(this, EventArgs.Empty); + } + + #endregion } public enum DisplayConditionSide diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs index 93ad6b336..3b5bb5c76 100644 --- a/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs +++ b/src/Artemis.UI.Shared/Services/Interfaces/IProfileEditorService.cs @@ -26,8 +26,6 @@ namespace Artemis.UI.Shared.Services.Interfaces void UpdateProfilePreview(); void UndoUpdateProfile(ProfileModule module); void RedoUpdateProfile(ProfileModule module); - void StopRegularRender(); - void ResumeRegularRender(); Module GetCurrentModule(); /// diff --git a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs index f9d651199..4edb6bf4f 100644 --- a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs +++ b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Artemis.Core.Models.Profile; using Artemis.Core.Models.Profile.LayerProperties; using Artemis.Core.Plugins.Abstract; using Artemis.Core.Plugins.Exceptions; using Artemis.Core.Plugins.Models; -using Artemis.Core.Services.Interfaces; using Artemis.Core.Services.Storage.Interfaces; using Artemis.UI.Shared.Events; using Artemis.UI.Shared.PropertyInput; @@ -19,18 +17,16 @@ namespace Artemis.UI.Shared.Services { public class ProfileEditorService : IProfileEditorService { - private readonly ICoreService _coreService; - private readonly IProfileService _profileService; private readonly ILogger _logger; + private readonly IProfileService _profileService; private readonly List _registeredPropertyEditors; private TimeSpan _currentTime; private int _pixelsPerSecond; - private object _selectedProfileLock = new object(); - private object _selectedProfileElementLock = new object(); + private readonly object _selectedProfileElementLock = new object(); + private readonly object _selectedProfileLock = new object(); - public ProfileEditorService(ICoreService coreService, IProfileService profileService, IKernel kernel, ILogger logger) + public ProfileEditorService(IProfileService profileService, IKernel kernel, ILogger logger) { - _coreService = coreService; _profileService = profileService; _logger = logger; _registeredPropertyEditors = new List(); @@ -126,7 +122,7 @@ namespace Artemis.UI.Shared.Services { if (SelectedProfile == null) return; - + // Stick to the main segment for any element that is not currently selected foreach (var folder in SelectedProfile.GetAllFolders()) folder.OverrideProgress(CurrentTime, folder != SelectedProfileElement); @@ -260,19 +256,9 @@ namespace Artemis.UI.Shared.Services public event EventHandler ProfileElementSelected; public event EventHandler SelectedProfileElementUpdated; public event EventHandler CurrentTimeChanged; - public event EventHandler CurrentTimelineChanged; public event EventHandler PixelsPerSecondChanged; public event EventHandler ProfilePreviewUpdated; - - public void StopRegularRender() - { - _coreService.PluginUpdatingDisabled = true; - } - - public void ResumeRegularRender() - { - _coreService.PluginUpdatingDisabled = false; - } + public event EventHandler CurrentTimelineChanged; protected virtual void OnSelectedProfileChanged(ProfileEventArgs e) { diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionPredicateView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionPredicateView.xaml index f1ee94310..a69b93f99 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionPredicateView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/DisplayConditions/DisplayConditionPredicateView.xaml @@ -8,6 +8,7 @@ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:converters="clr-namespace:Artemis.UI.Converters" xmlns:utilities="clr-namespace:Artemis.UI.Utilities" + xmlns:dataModel="clr-namespace:Artemis.UI.Shared.DataModelVisualization.Shared;assembly=Artemis.UI.Shared" x:Class="Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions.DisplayConditionPredicateView" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" @@ -20,6 +21,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -55,13 +97,12 @@ @@ -119,12 +160,12 @@ @@ -139,8 +180,8 @@ - + + \ No newline at end of file