internal static GameStateParameterLookupEntry Property(string name, string path, Type type) => new GameStateParameterLookupEntry { Name = name, Path = path, IsFolder = false, ClrType = type, Type = GSIPropertyTypeConverter.TypeToPropertyType(type) };
/// <summary> /// Creates a new <see cref="GameStateParameterLookup"/> by inspecting all properties on the given type. /// </summary> 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); } } } // Start the recursive function at the root. Visit("", "", type); }