mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Core - Fixed data model namespaces
Modules - Added IsPropertyInUse API UI - Properly dispose data model paths wherever they are used
This commit is contained in:
parent
222fddd749
commit
3f22ebae8a
@ -57,6 +57,7 @@
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Clayerbrushes_005Cinternal/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Clayereffects_005Cinternal/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cmodules_005Cactivationrequirements/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cmodules_005Cattributes/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cprerequisites/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cprerequisites_005Cprerequisiteaction/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cprofiling/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
20
src/Artemis.Core/Events/DataModelPathEventArgs.cs
Normal file
20
src/Artemis.Core/Events/DataModelPathEventArgs.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides data about data model path related events
|
||||
/// </summary>
|
||||
public class DataModelPathEventArgs : EventArgs
|
||||
{
|
||||
internal DataModelPathEventArgs(DataModelPath dataModelPath)
|
||||
{
|
||||
DataModelPath = dataModelPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data model path this event is related to
|
||||
/// </summary>
|
||||
public DataModelPath DataModelPath { get; }
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
|
||||
namespace Artemis.Core
|
||||
@ -175,6 +175,8 @@ namespace Artemis.Core
|
||||
|
||||
internal void Invalidate()
|
||||
{
|
||||
Target?.RemoveDataModelPath(this);
|
||||
|
||||
foreach (DataModelPathSegment dataModelPathSegment in _segments)
|
||||
dataModelPathSegment.Dispose();
|
||||
_segments.Clear();
|
||||
@ -187,11 +189,11 @@ namespace Artemis.Core
|
||||
|
||||
internal void Initialize()
|
||||
{
|
||||
Invalidate();
|
||||
|
||||
if (Target == null)
|
||||
return;
|
||||
|
||||
Target.AddDataModelPath(this);
|
||||
|
||||
DataModelPathSegment startSegment = new(this, "target", "target");
|
||||
startSegment.Node = _segments.AddFirst(startSegment);
|
||||
|
||||
@ -260,7 +262,7 @@ namespace Artemis.Core
|
||||
DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded;
|
||||
DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved;
|
||||
}
|
||||
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <summary>
|
||||
@ -330,6 +332,7 @@ namespace Artemis.Core
|
||||
if (e.Registration.DataModel.Module.Id != Entity.DataModelId)
|
||||
return;
|
||||
|
||||
Invalidate();
|
||||
Target = e.Registration.DataModel;
|
||||
Initialize();
|
||||
}
|
||||
@ -339,8 +342,8 @@ namespace Artemis.Core
|
||||
if (e.Registration.DataModel.Module.Id != Entity.DataModelId)
|
||||
return;
|
||||
|
||||
Target = null;
|
||||
Invalidate();
|
||||
Target = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Humanizer;
|
||||
|
||||
namespace Artemis.Core
|
||||
@ -301,7 +301,7 @@ namespace Artemis.Core
|
||||
private void DynamicChildOnDynamicChildRemoved(object? sender, DynamicDataModelChildEventArgs e)
|
||||
{
|
||||
if (e.DynamicChild.BaseValue == _dynamicDataModel)
|
||||
DataModelPath.Initialize();
|
||||
DataModelPath.Invalidate();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -5,6 +5,9 @@ using Artemis.Storage.Entities.Profile;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a category containing <see cref="ProfileConfigurations" />
|
||||
/// </summary>
|
||||
public class ProfileCategory : CorePropertyChanged, IStorageModel
|
||||
{
|
||||
private readonly List<ProfileConfiguration> _profileConfigurations = new();
|
||||
|
||||
@ -59,6 +59,8 @@ namespace Artemis.Core
|
||||
foreach (BaseLayerEffect baseLayerEffect in LayerEffects)
|
||||
baseLayerEffect.Dispose();
|
||||
|
||||
DisplayCondition?.Dispose();
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
public class ProfileConfiguration : CorePropertyChanged, IStorageModel
|
||||
/// <summary>
|
||||
/// Represents the configuration of a profile, contained in a <see cref="ProfileCategory" />
|
||||
/// </summary>
|
||||
public class ProfileConfiguration : CorePropertyChanged, IStorageModel, IDisposable
|
||||
{
|
||||
private ProfileCategory _category;
|
||||
private bool _disposed;
|
||||
|
||||
private bool _isMissingModule;
|
||||
private bool _isSuspended;
|
||||
@ -140,11 +145,17 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("ProfileConfiguration");
|
||||
|
||||
ActivationConditionMet = ActivationCondition == null || ActivationCondition.Evaluate();
|
||||
}
|
||||
|
||||
public bool ShouldBeActive(bool includeActivationCondition)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("ProfileConfiguration");
|
||||
|
||||
if (Category.IsSuspended || IsSuspended || IsMissingModule)
|
||||
return false;
|
||||
|
||||
@ -161,15 +172,32 @@ namespace Artemis.Core
|
||||
|
||||
internal void LoadModules(List<Module> enabledModules)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("ProfileConfiguration");
|
||||
|
||||
Module = enabledModules.FirstOrDefault(m => m.Id == Entity.ModuleId);
|
||||
IsMissingModule = Module == null && Entity.ModuleId != null;
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
_disposed = true;
|
||||
ActivationCondition?.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IStorageModel
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Load()
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("ProfileConfiguration");
|
||||
|
||||
Name = Entity.Name;
|
||||
IsSuspended = Entity.IsSuspended;
|
||||
ActivationBehaviour = (ActivationBehaviour) Entity.ActivationBehaviour;
|
||||
@ -185,6 +213,9 @@ namespace Artemis.Core
|
||||
/// <inheritdoc />
|
||||
public void Save()
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("ProfileConfiguration");
|
||||
|
||||
Entity.Name = Name;
|
||||
Entity.IsSuspended = IsSuspended;
|
||||
Entity.ActivationBehaviour = (int) ActivationBehaviour;
|
||||
@ -199,9 +230,7 @@ namespace Artemis.Core
|
||||
Entity.ActivationCondition = ActivationCondition.Entity;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entity.ActivationCondition = null;
|
||||
}
|
||||
|
||||
if (!IsMissingModule)
|
||||
Entity.ModuleId = Module?.Id;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core.DataModelExpansions
|
||||
namespace Artemis.Core.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an attribute that marks a data model property to be ignored by the UI
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core.DataModelExpansions
|
||||
namespace Artemis.Core.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an attribute that describes a data model property
|
||||
|
||||
@ -6,15 +6,15 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using Humanizer;
|
||||
using Newtonsoft.Json;
|
||||
using Module = Artemis.Core.Modules.Module;
|
||||
|
||||
namespace Artemis.Core.DataModelExpansions
|
||||
namespace Artemis.Core.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a data model that contains information on a game/application etc.
|
||||
/// </summary>
|
||||
public abstract class DataModel
|
||||
{
|
||||
private readonly HashSet<string> _activePathsHashSet = new();
|
||||
private readonly List<DataModelPath> _activePaths = new();
|
||||
private readonly Dictionary<string, DynamicChild> _dynamicChildren = new();
|
||||
|
||||
@ -65,36 +65,7 @@ namespace Artemis.Core.DataModelExpansions
|
||||
/// <returns></returns>
|
||||
public ReadOnlyCollection<PropertyInfo> GetHiddenProperties()
|
||||
{
|
||||
if (Module is Module module)
|
||||
return module.HiddenProperties;
|
||||
|
||||
return new List<PropertyInfo>().AsReadOnly();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a dynamic child has been added to this data model
|
||||
/// </summary>
|
||||
public event EventHandler<DynamicDataModelChildEventArgs>? DynamicChildAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a dynamic child has been removed from this data model
|
||||
/// </summary>
|
||||
public event EventHandler<DynamicDataModelChildEventArgs>? DynamicChildRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DynamicChildAdded" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDynamicDataModelAdded(DynamicDataModelChildEventArgs e)
|
||||
{
|
||||
DynamicChildAdded?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DynamicChildRemoved" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDynamicDataModelRemoved(DynamicDataModelChildEventArgs e)
|
||||
{
|
||||
DynamicChildRemoved?.Invoke(this, e);
|
||||
return Module.HiddenProperties;
|
||||
}
|
||||
|
||||
#region Dynamic children
|
||||
@ -285,15 +256,103 @@ namespace Artemis.Core.DataModelExpansions
|
||||
|
||||
#region Paths
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the provided dot-separated path is in use
|
||||
/// </summary>
|
||||
/// <param name="path">The path to check per example: <c>MyDataModelChild.MyDataModelProperty</c></param>
|
||||
/// <param name="includeChildren">
|
||||
/// If <see langword="true" /> any child of the given path will return true as well; if
|
||||
/// <see langword="false" /> only an exact path match returns <see langword="true" />.
|
||||
/// </param>
|
||||
internal bool IsPropertyInUse(string path, bool includeChildren)
|
||||
{
|
||||
path = path.ToUpperInvariant();
|
||||
return includeChildren
|
||||
? _activePathsHashSet.Any(p => p.StartsWith(path, StringComparison.Ordinal))
|
||||
: _activePathsHashSet.Contains(path);
|
||||
}
|
||||
|
||||
internal void AddDataModelPath(DataModelPath path)
|
||||
{
|
||||
if (!_activePaths.Contains(path))
|
||||
_activePaths.Add(path);
|
||||
if (_activePaths.Contains(path))
|
||||
return;
|
||||
|
||||
_activePaths.Add(path);
|
||||
|
||||
// Add to the hashset if this is the first path pointing
|
||||
string hashPath = path.Path.ToUpperInvariant();
|
||||
if (!_activePathsHashSet.Contains(hashPath))
|
||||
_activePathsHashSet.Add(hashPath);
|
||||
|
||||
OnActivePathAdded(new DataModelPathEventArgs(path));
|
||||
}
|
||||
|
||||
internal void RemoveDataModelPath(DataModelPath path)
|
||||
{
|
||||
_activePaths.Remove(path);
|
||||
if (!_activePaths.Remove(path))
|
||||
return;
|
||||
|
||||
// Remove from the hashset if this was the last path pointing there
|
||||
if (_activePaths.All(p => p.Path != path.Path))
|
||||
_activePathsHashSet.Remove(path.Path.ToUpperInvariant());
|
||||
|
||||
OnActivePathRemoved(new DataModelPathEventArgs(path));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a dynamic child has been added to this data model
|
||||
/// </summary>
|
||||
public event EventHandler<DynamicDataModelChildEventArgs>? DynamicChildAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a dynamic child has been removed from this data model
|
||||
/// </summary>
|
||||
public event EventHandler<DynamicDataModelChildEventArgs>? DynamicChildRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a dynamic child has been added to this data model
|
||||
/// </summary>
|
||||
public event EventHandler<DataModelPathEventArgs>? ActivePathAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a dynamic child has been removed from this data model
|
||||
/// </summary>
|
||||
public event EventHandler<DataModelPathEventArgs>? ActivePathRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DynamicChildAdded" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDynamicDataModelAdded(DynamicDataModelChildEventArgs e)
|
||||
{
|
||||
DynamicChildAdded?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DynamicChildRemoved" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDynamicDataModelRemoved(DynamicDataModelChildEventArgs e)
|
||||
{
|
||||
DynamicChildRemoved?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="ActivePathAdded" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnActivePathAdded(DataModelPathEventArgs e)
|
||||
{
|
||||
ActivePathAdded?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="ActivePathRemoved" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnActivePathRemoved(DataModelPathEventArgs e)
|
||||
{
|
||||
ActivePathRemoved?.Invoke(this, e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core.DataModelExpansions
|
||||
namespace Artemis.Core.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a dynamic child value with its property attribute
|
||||
|
||||
@ -5,7 +5,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using System.Text;
|
||||
|
||||
namespace Artemis.Core.Modules
|
||||
{
|
||||
@ -25,7 +25,8 @@ namespace Artemis.Core.Modules
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hide the provided property using a lambda expression, e.g. HideProperty(dm => dm.TimeDataModel.CurrentTimeUTC)
|
||||
/// Hide the provided property using a lambda expression, e.g.
|
||||
/// <c>HideProperty(dm => dm.TimeDataModel.CurrentTimeUTC)</c>
|
||||
/// </summary>
|
||||
/// <param name="propertyLambda">A lambda expression pointing to the property to ignore</param>
|
||||
public void HideProperty<TProperty>(Expression<Func<T, TProperty>> propertyLambda)
|
||||
@ -36,8 +37,8 @@ namespace Artemis.Core.Modules
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop hiding the provided property using a lambda expression, e.g. ShowProperty(dm =>
|
||||
/// dm.TimeDataModel.CurrentTimeUTC)
|
||||
/// Stop hiding the provided property using a lambda expression, e.g.
|
||||
/// <c>ShowProperty(dm => dm.TimeDataModel.CurrentTimeUTC)</c>
|
||||
/// </summary>
|
||||
/// <param name="propertyLambda">A lambda expression pointing to the property to stop ignoring</param>
|
||||
public void ShowProperty<TProperty>(Expression<Func<T, TProperty>> propertyLambda)
|
||||
@ -46,6 +47,36 @@ namespace Artemis.Core.Modules
|
||||
HiddenPropertiesList.RemoveAll(p => p.Equals(propertyInfo));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the provided dot-separated path is actively being used by Artemis
|
||||
/// <para>Note: <see cref="IsPropertyInUse" /> is slightly faster but string-based.</para>
|
||||
/// </summary>
|
||||
/// <param name="propertyLambda">
|
||||
/// The path to check per example: <c>IsPropertyInUse(dm => dm.TimeDataModel.CurrentTimeUTC)</c>
|
||||
/// </param>
|
||||
/// <param name="includeChildren">
|
||||
/// If <see langword="true" /> any child of the given path will return true as well; if
|
||||
/// <see langword="false" /> only an exact path match returns <see langword="true" />.
|
||||
/// </param>
|
||||
public bool IsPropertyInUse<TProperty>(Expression<Func<T, TProperty>> propertyLambda, bool includeChildren)
|
||||
{
|
||||
string path = GetMemberPath((MemberExpression) propertyLambda.Body);
|
||||
return IsPropertyInUse(path, includeChildren);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the provided dot-separated path is actively being used by Artemis
|
||||
/// </summary>
|
||||
/// <param name="path">The path to check per example: <c>MyDataModelChild.MyDataModelProperty</c></param>
|
||||
/// <param name="includeChildren">
|
||||
/// If <see langword="true" /> any child of the given path will return true as well; if
|
||||
/// <see langword="false" /> only an exact path match returns <see langword="true" />.
|
||||
/// </param>
|
||||
public bool IsPropertyInUse(string path, bool includeChildren)
|
||||
{
|
||||
return DataModel.IsPropertyInUse(path, includeChildren);
|
||||
}
|
||||
|
||||
internal override void InternalEnable()
|
||||
{
|
||||
DataModel = Activator.CreateInstance<T>();
|
||||
@ -59,6 +90,20 @@ namespace Artemis.Core.Modules
|
||||
Deactivate(true);
|
||||
base.InternalDisable();
|
||||
}
|
||||
|
||||
private static string GetMemberPath(MemberExpression? me)
|
||||
{
|
||||
StringBuilder builder = new();
|
||||
while (me != null)
|
||||
{
|
||||
builder.Insert(0, me.Member.Name);
|
||||
me = me.Expression as MemberExpression;
|
||||
if (me != null)
|
||||
builder.Insert(0, ".");
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -78,7 +123,7 @@ namespace Artemis.Core.Modules
|
||||
/// Gets a read only collection of default profile paths
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<(DefaultCategoryName, string)> DefaultProfilePaths => _defaultProfilePaths.AsReadOnly();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A list of activation requirements
|
||||
/// <para>
|
||||
|
||||
@ -4,7 +4,6 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Ninject;
|
||||
using Artemis.Storage;
|
||||
using HidSharp;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core.Services
|
||||
{
|
||||
|
||||
@ -357,6 +357,8 @@ namespace Artemis.Core.Services
|
||||
ProfileEntity profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
||||
if (profileEntity != null)
|
||||
_profileRepository.Remove(profileEntity);
|
||||
|
||||
profileConfiguration.Dispose();
|
||||
}
|
||||
|
||||
public void SaveProfileCategory(ProfileCategory profileCategory)
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using EmbedIO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using EmbedIO;
|
||||
using EmbedIO.WebApi;
|
||||
|
||||
@ -4,7 +4,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using EmbedIO;
|
||||
using EmbedIO.WebApi;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System.Linq.Expressions;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
|
||||
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
|
||||
@ -272,6 +272,7 @@ namespace Artemis.UI.Shared.Input
|
||||
_updateTimer.Dispose();
|
||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||
|
||||
DataModelViewModel?.Dispose();
|
||||
DataModelPath?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using MaterialDesignColors.ColorManipulation;
|
||||
using Stylet;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared.Services;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
using System.Collections;
|
||||
using System.Windows.Documents;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared.Services;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared.Services;
|
||||
|
||||
namespace Artemis.UI.Shared
|
||||
|
||||
@ -3,8 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Stylet;
|
||||
|
||||
@ -13,7 +14,7 @@ namespace Artemis.UI.Shared
|
||||
/// <summary>
|
||||
/// Represents a base class for a view model that visualizes a part of the data model
|
||||
/// </summary>
|
||||
public abstract class DataModelVisualizationViewModel : PropertyChangedBase
|
||||
public abstract class DataModelVisualizationViewModel : PropertyChangedBase, IDisposable
|
||||
{
|
||||
private const int MaxDepth = 4;
|
||||
private BindableCollection<DataModelVisualizationViewModel> _children;
|
||||
@ -22,6 +23,7 @@ namespace Artemis.UI.Shared
|
||||
private bool _isVisualizationExpanded;
|
||||
private DataModelVisualizationViewModel? _parent;
|
||||
private DataModelPropertyAttribute? _propertyDescription;
|
||||
private bool _populatedStaticChildren;
|
||||
|
||||
internal DataModelVisualizationViewModel(DataModel? dataModel, DataModelVisualizationViewModel? parent, DataModelPath? dataModelPath)
|
||||
{
|
||||
@ -206,21 +208,26 @@ namespace Artemis.UI.Shared
|
||||
if (modelType == null)
|
||||
throw new ArtemisSharedUIException("Failed to populate data model visualization properties, couldn't get a property type");
|
||||
|
||||
// Add missing static children
|
||||
foreach (PropertyInfo propertyInfo in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(t => t.MetadataToken))
|
||||
// Add missing static children only once, they're static after all
|
||||
if (!_populatedStaticChildren)
|
||||
{
|
||||
string childPath = AppendToPath(propertyInfo.Name);
|
||||
if (Children.Any(c => c.Path != null && c.Path.Equals(childPath)))
|
||||
continue;
|
||||
if (propertyInfo.GetCustomAttribute<DataModelIgnoreAttribute>() != null)
|
||||
continue;
|
||||
MethodInfo? getMethod = propertyInfo.GetGetMethod();
|
||||
if (getMethod == null || getMethod.GetParameters().Any())
|
||||
continue;
|
||||
foreach (PropertyInfo propertyInfo in modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(t => t.MetadataToken))
|
||||
{
|
||||
string childPath = AppendToPath(propertyInfo.Name);
|
||||
if (Children.Any(c => c.Path != null && c.Path.Equals(childPath)))
|
||||
continue;
|
||||
if (propertyInfo.GetCustomAttribute<DataModelIgnoreAttribute>() != null)
|
||||
continue;
|
||||
MethodInfo? getMethod = propertyInfo.GetGetMethod();
|
||||
if (getMethod == null || getMethod.GetParameters().Any())
|
||||
continue;
|
||||
|
||||
DataModelVisualizationViewModel? child = CreateChild(dataModelUIService, childPath, GetChildDepth());
|
||||
if (child != null)
|
||||
Children.Add(child);
|
||||
DataModelVisualizationViewModel? child = CreateChild(dataModelUIService, childPath, GetChildDepth());
|
||||
if (child != null)
|
||||
Children.Add(child);
|
||||
}
|
||||
|
||||
_populatedStaticChildren = true;
|
||||
}
|
||||
|
||||
// Remove static children that should be hidden
|
||||
@ -302,7 +309,14 @@ namespace Artemis.UI.Shared
|
||||
|
||||
private string AppendToPath(string toAppend)
|
||||
{
|
||||
return !string.IsNullOrEmpty(Path) ? $"{Path}.{toAppend}" : toAppend;
|
||||
if (string.IsNullOrEmpty(Path))
|
||||
return toAppend;
|
||||
|
||||
StringBuilder builder = new();
|
||||
builder.Append(Path);
|
||||
builder.Append(".");
|
||||
builder.Append(toAppend);
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private void RequestUpdate()
|
||||
@ -327,5 +341,33 @@ namespace Artemis.UI.Shared
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <summary>
|
||||
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
|
||||
/// </summary>
|
||||
/// <param name="disposing">
|
||||
/// <see langword="true" /> to release both managed and unmanaged resources;
|
||||
/// <see langword="false" /> to release only unmanaged resources.
|
||||
/// </param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
DataModelPath?.Dispose();
|
||||
foreach (DataModelVisualizationViewModel dataModelVisualizationViewModel in Children)
|
||||
dataModelVisualizationViewModel.Dispose(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared.Input;
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.UI.Shared.DefaultTypes.DataModel.Display;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared.Input;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.DefaultTypes.DataModel.Input
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Input;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.DefaultTypes.DataModel.Input
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared;
|
||||
using Stylet;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Input;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.DefaultTypes.DataModel.Input
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared;
|
||||
using SkiaSharp;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.Modules;
|
||||
using Artemis.UI.Shared;
|
||||
|
||||
namespace Artemis.UI.DefaultTypes.DataModel.Input
|
||||
|
||||
@ -87,7 +87,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
protected override void OnClose()
|
||||
{
|
||||
_updateTimer.Dispose();
|
||||
base.OnClose();
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -109,6 +109,9 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
{
|
||||
_updateTimer.Stop();
|
||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||
MainDataModel?.Dispose();
|
||||
MainDataModel = null;
|
||||
|
||||
_pluginManagementService.PluginFeatureEnabled -= OnPluginFeatureToggled;
|
||||
_pluginManagementService.PluginFeatureDisabled -= OnPluginFeatureToggled;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user