SettingsList implementation.

Merge conflict resolution.
This commit is contained in:
Maplewheels
2026-03-22 01:54:54 -04:00
parent cf3a50d6b5
commit 7c8dd452cf
2 changed files with 121 additions and 2 deletions

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Toolkit.Diagnostics;
namespace Barotrauma.LuaCs.Data;
public class SettingList<T> : SettingEntry<T>, ISettingList<T> where T : IEquatable<T>, IConvertible
{
public class LFactory : ISettingBase.IFactory<ISettingList<T>>
{
public ISettingList<T> CreateInstance(IConfigInfo configInfo, Func<OneOf<string, XElement, object>, bool> valueChangePredicate)
{
Guard.IsNotNull(configInfo, nameof(configInfo));
return new SettingList<T>(configInfo, valueChangePredicate);
}
}
public SettingList(IConfigInfo configInfo, Func<OneOf<string, XElement, object>, bool> valueChangePredicate) : base(configInfo, valueChangePredicate)
{
if (!(
typeof(T).IsEnum ||
typeof(T).IsPrimitive ||
typeof(T) == typeof(string)))
{
ThrowHelper.ThrowArgumentException($"{nameof(ISettingBase<T>)}: The type of {nameof(T)} is not an allowed type.");
}
ValueChangePredicate = valueChangePredicate;
var valuesElements = ConfigInfo.Element.GetChildElement("Values")?.GetChildElements("Value")?.ToImmutableArray();
Guard.IsNotNull(valuesElements, this.InternalName);
if (valuesElements.Value.IsEmpty)
{
ThrowHelper.ThrowArgumentNullException($"{this.InternalName}: Could not find any values in list!");
}
foreach (var element in valuesElements.Value)
{
if (!TryConvert(element, out var v1))
{
ThrowHelper.ThrowArgumentException($"{this.InternalName}: Error while parsing list values");
}
_valuesList.Add(v1);
}
if (TryConvert(ConfigInfo.Element, out var v) && _valuesList.Contains(v))
{
Value = v;
DefaultValue = v;
}
else
{
Value = _valuesList[0];
DefaultValue = _valuesList[0];
}
bool TryConvert(XElement element, out T value)
{
try
{
value = (T)Convert.ChangeType(element.GetAttributeString("Value", null), typeof(T));
return true;
}
catch (Exception e) when (e is InvalidCastException or ArgumentNullException)
{
value = default(T);
return false;
}
}
}
private readonly List<T> _valuesList = new();
public override bool TrySetValue(T value)
{
if (!_valuesList.Contains(value))
{
return false;
}
return base.TrySetValue(value);
}
public bool TrySetValueByIndex(int index)
{
throw new NotImplementedException();
}
public IReadOnlyList<T> Options => _valuesList.AsReadOnly();
public IReadOnlyList<string> StringOptions => _valuesList.Select(e => e.ToString()).ToImmutableArray();
}

View File

@@ -22,8 +22,6 @@ public class SettingsEntryRegistrar : ISettingsRegistrationProvider
public void RegisterTypeProviders(IConfigService configService, Func<OneOf<string, XElement, object>, bool> valueChangePredicate)
{
// TODO: Replace this with a proper IFactory lookup pattern.
// ISettingBase<T>
RegisterSettingEntry<bool>(configService, "bool", valueChangePredicate);
RegisterSettingEntry<byte>(configService, "byte", valueChangePredicate);
RegisterSettingEntry<sbyte>(configService, "sbyte", valueChangePredicate);
@@ -58,8 +56,31 @@ public class SettingsEntryRegistrar : ISettingsRegistrationProvider
IsValueChangeAllowed(cfgInfo.Info, val, valueChangePredicate));
});
#endif
RegisterSettingList<bool>(configService, "listBool", valueChangePredicate);
RegisterSettingList<byte>(configService, "listByte", valueChangePredicate);
RegisterSettingList<sbyte>(configService, "listSbyte", valueChangePredicate);
RegisterSettingList<short>(configService, "listShort", valueChangePredicate);
RegisterSettingList<ushort>(configService, "listUshort", valueChangePredicate);
RegisterSettingList<int>(configService, "listInt", valueChangePredicate);
RegisterSettingList<uint>(configService, "listUint", valueChangePredicate);
RegisterSettingList<long>(configService, "listLong", valueChangePredicate);
RegisterSettingList<ulong>(configService, "listUlong", valueChangePredicate);
RegisterSettingList<string>(configService, "listString", valueChangePredicate);
RegisterSettingList<float>(configService, "listFloat", valueChangePredicate);
RegisterSettingList<float>(configService, "listSingle", valueChangePredicate);
RegisterSettingList<double>(configService, "listDouble", valueChangePredicate);
}
private void RegisterSettingList<T>(IConfigService configService, string typeName, Func<OneOf<string, XElement, object>, bool> valueChangePredicate) where T : IEquatable<T>, IConvertible
{
configService.RegisterSettingTypeInitializer(typeName, cfgInfo =>
{
return new SettingList<T>.LFactory().CreateInstance(cfgInfo.Info, (val) =>
IsValueChangeAllowed(cfgInfo.Info, val, valueChangePredicate));
});
}
private void RegisterSettingEntry<T>(IConfigService configService, string typeName, Func<OneOf<string, XElement, object>, bool> valueChangePredicate) where T : IEquatable<T>, IConvertible
{
configService.RegisterSettingTypeInitializer(typeName, cfgInfo =>