Changed option list attributes to only accept strings with zero or one format parameters

This commit is contained in:
David Higueros committed 2026-07-17 22:28:13 -06:00
1 parent ff3478be54
commit ff6c6114cf
4 files changed
+45 -20

No files matched your search

@@ -9,13 +9,13 @@ namespace MiraAPI.GameOptions.Attributes;
/// Attribute for creating a list of enum options.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ModdedEnumOptionListAttribute(Func<int, string> titler, Type enumType, string[]? values = null)
: ModdedOptionListAttribute(titler)
public class ModdedEnumOptionListAttribute(string title, Type enumType, string[]? values = null)
: ModdedOptionListAttribute(title)
{
internal override IModdedOptionList CreateOptionList(IList value, PropertyInfo property)
{
var optList = new ModdedOptionList<ModdedEnumOption>(
value.Count, idx => new(Titler(idx), (int)(value[idx] ?? 0), enumType, values));
value.Count, idx => new(GetFormattedTitle(idx), (int)(value[idx] ?? 0), enumType, values));
return optList;
}
@@ -31,7 +31,7 @@ public class ModdedEnumOptionListAttribute(Func<int, string> titler, Type enumTy
{
return HolderOptionList?[idx] is ModdedEnumOption opt
? Enum.ToObject(enumType, opt.Value)
: throw new InvalidOperationException($"HolderOption for option \"{Titler(idx)}\" with EnumType ${enumType.FullName} is not a ModdedEnumOption");
: throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" with EnumType ${enumType.FullName} is not a ModdedEnumOption");
}
}
@@ -40,13 +40,13 @@ public class ModdedEnumOptionListAttribute(Func<int, string> titler, Type enumTy
/// </summary>
/// <typeparam name="T">The enum type.</typeparam>
[AttributeUsage(AttributeTargets.Property)]
public class ModdedEnumOptionListAttribute<T>(Func<int, string> titler, string[]? values = null)
: ModdedOptionListAttribute(titler) where T : Enum
public class ModdedEnumOptionListAttribute<T>(string title, string[]? values = null)
: ModdedOptionListAttribute(title) where T : Enum
{
internal override IModdedOptionList CreateOptionList(IList value, PropertyInfo property)
{
var optList = new ModdedOptionList<ModdedEnumOption<T>>(
value.Count, idx => new(Titler(idx), (T)(value[idx] ?? 0), values));
value.Count, idx => new(GetFormattedTitle(idx), (T)(value[idx] ?? 0), values));
return optList;
}
@@ -62,6 +62,6 @@ public class ModdedEnumOptionListAttribute<T>(Func<int, string> titler, string[]
{
return HolderOptionList?[idx] is ModdedEnumOption<T> opt
? opt.Value
: throw new InvalidOperationException($"HolderOption for option \"{Titler(idx)}\" with EnumType ${typeof(T).FullName} is not a ModdedEnumOption");
: throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" with EnumType ${typeof(T).FullName} is not a ModdedEnumOption");
}
}
@@ -11,21 +11,21 @@ namespace MiraAPI.GameOptions.Attributes;
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ModdedNumberOptionListAttribute(
Func<int, string> titler,
string title,
float min,
float max,
float increment = 1,
MiraNumberSuffixes suffixType = MiraNumberSuffixes.None,
string? formatString = null,
bool zeroInfinity = false)
: ModdedOptionListAttribute(titler)
: ModdedOptionListAttribute(title)
{
internal override IModdedOptionList CreateOptionList(IList value, PropertyInfo property)
{
return new ModdedOptionList<ModdedNumberOption>(value.Count, idx =>
{
return new(
Titler(idx),
GetFormattedTitle(idx),
(float)(value[idx] ?? min + increment),
min,
max,
@@ -50,6 +50,6 @@ public class ModdedNumberOptionListAttribute(
{
return opt.Value;
}
throw new InvalidOperationException($"HolderOption for option \"{Titler(idx)}\" is not a ModdedNumberOption");
throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" is not a ModdedNumberOption");
}
}
@@ -1,24 +1,28 @@
using System;
using System.Collections;
using System.Reflection;
using System.Text.RegularExpressions;
namespace MiraAPI.GameOptions.Attributes;
/// <summary>
/// Represents an attribute that is used to define a list of modded options.
/// </summary>
/// <param name="titler">A function to title of the options.</param>
/// <param name="title">The title of the options.</param>
[AttributeUsage(AttributeTargets.Property)]
public abstract class ModdedOptionListAttribute(Func<int, string> titler) : PropertyOptionAttribute
public abstract class ModdedOptionListAttribute(string title) : PropertyOptionAttribute
{
internal IModdedOptionList? HolderOptionList { get; set; }
internal object? Value { get; set; }
/// <summary>
/// Gets the function to title of the options.
/// Gets the title of the options.
/// If the string contains a format parameter, e.g., <c>{0}</c>, then the option's index will be given to it.
/// The string cannot contain more than one parameter.
/// If no parameter is given, the title will simply append the index to the end of it.
/// </summary>
public Func<int, string> Titler => titler;
public string Title => title;
/// <summary>
/// Sets the value of all the options.
@@ -63,4 +67,25 @@ public abstract class ModdedOptionListAttribute(Func<int, string> titler) : Prop
public abstract object GetValue(int idx);
internal abstract IModdedOptionList? CreateOptionList(IList value, PropertyInfo property);
/// <summary>
/// Gets the <see cref="Title"/> formatted with the option's index.
/// </summary>
/// <param name="index">The option's index.</param>
/// <returns>The formatted option's title.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "I don't even know if this is worth it.")]
protected string GetFormattedTitle(int index)
{
Match match = Regex.Match(Title, @"\{(\d+)(?::[^}]+)?\}");
if (match.Success)
{
if (match.Groups.Count == 1 && match.Groups[0].Value == "0")
{
return string.Format(Title, index);
}
Error("ModdedOptionList Title cannot contain more than the first parameter for formatting.");
}
return Title + index;
}
}
@@ -8,14 +8,14 @@ namespace MiraAPI.GameOptions.Attributes;
/// <summary>
/// Attribute for a list of toggle options.
/// </summary>
/// <param name="titler">The function to get each option's title.</param>
/// <param name="title">The option's title.</param>
[AttributeUsage(AttributeTargets.Property)]
public class ModdedToggleOptionListAttribute(Func<int, string> titler) : ModdedOptionListAttribute(titler)
public class ModdedToggleOptionListAttribute(string title) : ModdedOptionListAttribute(title)
{
internal override IModdedOptionList CreateOptionList(IList value, PropertyInfo property)
{
var optList = new ModdedOptionList<ModdedToggleOption>(
value.Count, idx => new(Titler(idx), (bool)(value[idx] ?? false)));
value.Count, idx => new(GetFormattedTitle(idx), (bool)(value[idx] ?? false)));
return optList;
}
@@ -33,6 +33,6 @@ public class ModdedToggleOptionListAttribute(Func<int, string> titler) : ModdedO
{
return opt.Value;
}
throw new InvalidOperationException($"Holder option for {Titler(idx)} is not a ModdedToggleOption.");
throw new InvalidOperationException($"Holder option for {GetFormattedTitle(idx)} is not a ModdedToggleOption.");
}
}