diff --git a/Project-Aurora/Project-Aurora/Profiles/GameStateParameterLookup.cs b/Project-Aurora/Project-Aurora/Profiles/GameStateParameterLookup.cs
index daa9c8f1a..64a12dbcb 100644
--- a/Project-Aurora/Project-Aurora/Profiles/GameStateParameterLookup.cs
+++ b/Project-Aurora/Project-Aurora/Profiles/GameStateParameterLookup.cs
@@ -5,126 +5,122 @@
using AuroraRgb.Utils;
using FastMember;
-namespace AuroraRgb.Profiles {
+namespace AuroraRgb.Profiles;
+
+///
+/// Data structure that holds a record of all game state parameters for a particular type of GameState.
+///
+public sealed class GameStateParameterLookup {
+
+ // Internal parameter store. Key = full path, Value = meta
+ private readonly Dictionary _lookup = new();
///
- /// Data structure that holds a record of all game state parameters for a particular type of GameState.
+ /// Creates a new by inspecting all properties on the given type.
///
- public sealed class GameStateParameterLookup {
-
- // List of types that are permitted to be recursively searched
- private static readonly Type[] RecursiveWhiteList = { typeof(Node), typeof(GameState), typeof(IEnumerable) };
-
- // Internal parameter store. Key = full path, Value = meta
- private readonly Dictionary _lookup = new();
-
- ///
- /// Creates a new by inspecting all properties on the given type.
- ///
- public GameStateParameterLookup(Type type) {
- // Recursive function for visiting all types on the given type
- // Will add relevant entries to lookup
- void Visit(string path, string name, Type type) {
- // If this is a variable that can be handled (such as a number or bool), add it to the lookup
- if (GSIPropertyTypeConverter.TypeToPropertyType(type) != GSIPropertyType.None)
- _lookup.Add(path, GameStateParameterLookupEntry.Property(name, path, type));
-
- else if (RecursiveWhiteList.Any(t => t.IsAssignableFrom(type))) {
- // Else if this not a handlable property, check if it's a node or list of nodes and if so make a folder and visit it's children
- if (path != "") // If it's the root folder, don't add it
- _lookup.Add(path, GameStateParameterLookupEntry.Folder(name, path));
-
- var accessor = TypeAccessor.Create(type);
- if (!accessor.GetMembersSupported) return;
- foreach (var member in accessor.GetMembers()) {
- if (member.Type == type) continue; // Ignore recursive types
- if (member.GetAttribute(typeof(GameStateIgnoreAttribute), true) != null) continue; // Ignore properties with [GameStateIgnore]
-
- var nextPath = (path + "/" + member.Name).TrimStart('/');
-
- // If the type is an Enumerable with a range attribute, visit for each item in that range
- if (member.Type.GetGenericInterfaceTypes(typeof(IEnumerable<>)) is { } ienumTypes && typeof(Node).IsAssignableFrom(ienumTypes[0]) && member.GetAttribute(typeof(RangeAttribute), true) is RangeAttribute range)
- for (var i = range.Start; i <= range.End; i++)
- Visit(nextPath + "/" + i, i.ToString(), ienumTypes[0]);
-
- // Recursively visit the next type (do this even if it is IEnumerable, as it might be a custom class that implements IEnumerable with extra properties)
- Visit(nextPath, member.Name, member.Type);
- }
+ public GameStateParameterLookup(Type type) {
+ // Recursive function for visiting all types on the given type
+ // Will add relevant entries to lookup
+ void Visit(string path, string name, Type type) {
+ // If this is a variable that can be handled (such as a number or bool), add it to the lookup
+ if (GSIPropertyTypeConverter.TypeToPropertyType(type) != GSIPropertyType.None)
+ _lookup.Add(path, GameStateParameterLookupEntry.Property(name, path, type));
+
+ else if (type.Namespace.Contains("AuroraRgb.")) {
+ // Else if this not a handlable property, check if it's a node or list of nodes and if so make a folder and visit it's children
+ if (path != "") // If it's the root folder, don't add it
+ _lookup.Add(path, GameStateParameterLookupEntry.Folder(name, path));
+
+ var accessor = TypeAccessor.Create(type);
+ if (!accessor.GetMembersSupported) return;
+ foreach (var member in accessor.GetMembers()) {
+ if (member.Type == type) continue; // Ignore recursive types
+ if (member.GetAttribute(typeof(GameStateIgnoreAttribute), true) != null) continue; // Ignore properties with [GameStateIgnore]
+
+ var nextPath = (path + "/" + member.Name).TrimStart('/');
+
+ // If the type is an Enumerable with a range attribute, visit for each item in that range
+ if (member.Type.GetGenericInterfaceTypes(typeof(IEnumerable<>)) is { } ienumTypes && typeof(Node).IsAssignableFrom(ienumTypes[0]) && member.GetAttribute(typeof(RangeAttribute), true) is RangeAttribute range)
+ for (var i = range.Start; i <= range.End; i++)
+ Visit(nextPath + "/" + i, i.ToString(), ienumTypes[0]);
+
+ // Recursively visit the next type (do this even if it is IEnumerable, as it might be a custom class that implements IEnumerable with extra properties)
+ Visit(nextPath, member.Name, member.Type);
}
}
-
- // Start the recursive function at the root.
- Visit("", "", type);
- }
-
- ///
- /// Attempts to get the definition for the folder or property at the given path.
- ///
- public GameStateParameterLookupEntry this[string path] =>
- _lookup.TryGetValue(path, out var entry) ? entry : null;
-
- ///
- /// Gets all the direct/first-level children of the folder at the given path.
- /// Optionally, only children ones that either are of the given type (in the case of properties) or that contain atleast one property of the given type (in the case of folders).
- ///
- /// Only children that are within the folder at the given path will be returned.
- /// If not , only children of this type and only folders that contain atleast one property of this type will be returned.
- public IEnumerable Children(string path = "", GSIPropertyType type = GSIPropertyType.None) =>
- from kvp in _lookup
- where GetFolderOf(kvp.Key) == path // only include anything in this folder
- where type == GSIPropertyType.None // if type is none, don't worry about type filtering
- || (kvp.Value.IsFolder && AllChildren(kvp.Key).Any(c => c.Type == type)) // return a folder if it contains atleast one child of type
- || (!kvp.Value.IsFolder && kvp.Value.Type == type) // return a property if it is of type
- select kvp.Value;
-
- /// Returns a list of all children of the given path, REGARDLESS of depth.
- private IEnumerable AllChildren(string path) {
- if (!path.EndsWith("/")) path += '/';
- return from kvp in _lookup where kvp.Key.StartsWith(path) select kvp.Value;
}
- ///
- /// Determines if the given path results in a property of the given type.
- ///
- /// The result will only be true if the parameter type is of this type. If None is passed, any parameter type is allowed.
- public bool IsValidParameter(string path, GSIPropertyType type = GSIPropertyType.None) =>
- _lookup.TryGetValue(path, out var entry) && !entry.IsFolder && (type == GSIPropertyType.None || entry.Type == type);
-
- ///
- /// Returns the folder that the given path is in.
- ///
- private string GetFolderOf(string path) => path.Contains('/') ? path.Substring(0, path.LastIndexOf('/')) : "";
+ // Start the recursive function at the root.
+ Visit("", "", type);
}
+ ///
+ /// Attempts to get the definition for the folder or property at the given path.
+ ///
+ public GameStateParameterLookupEntry this[string path] =>
+ _lookup.TryGetValue(path, out var entry) ? entry : null;
///
- /// Plain object that holds metadata about a single parameter or folder in the collection.
+ /// Gets all the direct/first-level children of the folder at the given path.
+ /// Optionally, only children ones that either are of the given type (in the case of properties) or that contain atleast one property of the given type (in the case of folders).
///
- public sealed class GameStateParameterLookupEntry {
- public string Name { get; private set; }
- public string Path { get; private set; }
- public bool IsFolder { get; private set; }
- public Type ClrType { get; private set; }
- public GSIPropertyType Type { get; private set; }
-
- public string DisplayName => Name.CamelCaseToSpaceCase();
-
- private GameStateParameterLookupEntry() { }
-
- internal static GameStateParameterLookupEntry Folder(string name, string path) => new GameStateParameterLookupEntry {
- Name = name,
- Path = path,
- IsFolder = true,
- ClrType = null,
- Type = GSIPropertyType.None
- };
-
- internal static GameStateParameterLookupEntry Property(string name, string path, Type type) => new GameStateParameterLookupEntry {
- Name = name,
- Path = path,
- IsFolder = false,
- ClrType = type,
- Type = GSIPropertyTypeConverter.TypeToPropertyType(type)
- };
+ /// Only children that are within the folder at the given path will be returned.
+ /// If not , only children of this type and only folders that contain atleast one property of this type will be returned.
+ public IEnumerable Children(string path = "", GSIPropertyType type = GSIPropertyType.None) =>
+ from kvp in _lookup
+ where GetFolderOf(kvp.Key) == path // only include anything in this folder
+ where type == GSIPropertyType.None // if type is none, don't worry about type filtering
+ || (kvp.Value.IsFolder && AllChildren(kvp.Key).Any(c => c.Type == type)) // return a folder if it contains atleast one child of type
+ || (!kvp.Value.IsFolder && kvp.Value.Type == type) // return a property if it is of type
+ select kvp.Value;
+
+ /// Returns a list of all children of the given path, REGARDLESS of depth.
+ private IEnumerable AllChildren(string path) {
+ if (!path.EndsWith("/")) path += '/';
+ return from kvp in _lookup where kvp.Key.StartsWith(path) select kvp.Value;
}
+
+ ///
+ /// Determines if the given path results in a property of the given type.
+ ///
+ /// The result will only be true if the parameter type is of this type. If None is passed, any parameter type is allowed.
+ public bool IsValidParameter(string path, GSIPropertyType type = GSIPropertyType.None) =>
+ _lookup.TryGetValue(path, out var entry) && !entry.IsFolder && (type == GSIPropertyType.None || entry.Type == type);
+
+ ///
+ /// Returns the folder that the given path is in.
+ ///
+ private string GetFolderOf(string path) => path.Contains('/') ? path.Substring(0, path.LastIndexOf('/')) : "";
}
+
+
+///
+/// Plain object that holds metadata about a single parameter or folder in the collection.
+///
+public sealed class GameStateParameterLookupEntry {
+ public string Name { get; private set; }
+ public string Path { get; private set; }
+ public bool IsFolder { get; private set; }
+ public Type ClrType { get; private set; }
+ public GSIPropertyType Type { get; private set; }
+
+ public string DisplayName => Name.CamelCaseToSpaceCase();
+
+ private GameStateParameterLookupEntry() { }
+
+ internal static GameStateParameterLookupEntry Folder(string name, string path) => new GameStateParameterLookupEntry {
+ Name = name,
+ Path = path,
+ IsFolder = true,
+ ClrType = null,
+ Type = GSIPropertyType.None
+ };
+
+ internal static GameStateParameterLookupEntry Property(string name, string path, Type type) => new GameStateParameterLookupEntry {
+ Name = name,
+ Path = path,
+ IsFolder = false,
+ ClrType = type,
+ Type = GSIPropertyTypeConverter.TypeToPropertyType(type)
+ };
+}
\ No newline at end of file