mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +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:
1 parent
222fddd749
commit
3f22ebae8a
48 files changed
+305
-103
No files matched your search
@@ -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>
|
||||
|
||||
Reference in new issue
Block a user