Skip to content

Commit

Permalink
Merge pull request #319 from Aragas/dev
Browse files Browse the repository at this point in the history
v5.2.0
  • Loading branch information
Aragas authored Nov 12, 2022
2 parents 4252b26 + db89e67 commit bbb8d97
Show file tree
Hide file tree
Showing 41 changed files with 359 additions and 597 deletions.
6 changes: 3 additions & 3 deletions build/common.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

<PropertyGroup>
<GameVersion>1.0.0</GameVersion>
<Version>5.1.1</Version>
<Version>5.2.0</Version>
<HarmonyVersion>2.2.2</HarmonyVersion>
<ButterLibVersion>2.5.1</ButterLibVersion>
<UIExtenderExVersion>2.3.1</UIExtenderExVersion>
<BuildResourcesVersion>1.0.1.80</BuildResourcesVersion>
<BUTRSharedVersion>3.0.0.121</BUTRSharedVersion>
<BUTRDependencyInjectionVersion>1.0.0.30</BUTRDependencyInjectionVersion>
<BUTRModuleManagerVersion>4.0.149</BUTRModuleManagerVersion>
<BUTRDependencyInjectionVersion>2.0.0.38</BUTRDependencyInjectionVersion>
<BUTRModuleManagerVersion>4.0.150</BUTRModuleManagerVersion>
<HarmonyExtensionsVersion>3.1.0.67</HarmonyExtensionsVersion>
<HarmonyAnalyzerVersion>1.0.1.44</HarmonyAnalyzerVersion>
<LangVersion>9.0</LangVersion>
Expand Down
5 changes: 5 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
---------------------------------------------------------------------------------------------------
Version: 5.2.0
Game Versions: v1.0.0,v1.0.1
* UI fixes. Dropdowns are handled correct now in a lot of usage cases.
* Huge thanks to bm001 for reporting those issues!
---------------------------------------------------------------------------------------------------
Version: 5.1.1
Game Versions: v1.0.0,v1.0.1
* Updated ButterLib
Expand Down
4 changes: 3 additions & 1 deletion docs/articles/MCMv5/mcmv5-migrating-from-mcmv4.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@
* `DropdownDefault<>` was renamed to `Dropdown<>`
* Preset system was changed:
* `GetAvailablePresets` was renamed to `GetBuiltInPresets`
* The signature changed. Instead of a dictionary with a lambda - constructor inside a class `MemorySettingsPreset` is used with a similar signature. Check MCMv5 docs for the new usage.
* The signature changed. Instead of a dictionary with a lambda - constructor inside a class `MemorySettingsPreset` is used with a similar signature. Check MCMv5 docs for the new usage.

* Implementation SubModule was renamed from `MCM.Implementation.MCMImplementationSubModule` to `MCM.Internal.MCMImplementationSubModule`
2 changes: 1 addition & 1 deletion docs/articles/MCMv5/mcmv5.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ By including MCMv5 you will be able to save/load settings programmatically, with
<SubModule>
<Name value="MCMv5 Basic Implementation" />
<DLLName value="MCMv5.dll" />
<SubModuleClassType value="MCM.Implementation.MCMImplementationSubModule" />
<SubModuleClassType value="MCM.Internal.MCMImplementationSubModule" />
<Tags />
</SubModule>
</SubModules>
Expand Down
8 changes: 8 additions & 0 deletions src/MCM.Abstractions/Base/BaseSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;

Expand Down Expand Up @@ -42,6 +43,13 @@ public abstract class BaseSettings : INotifyPropertyChanged
public virtual int UIVersion => 1;
public virtual char SubGroupDelimiter => '/';

internal List<SettingsPropertyGroupDefinition> SettingPropertyGroups { get; }

public BaseSettings()
{
SettingPropertyGroups = this.CreateSettingPropertyGroups().ToList();
}

public virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

public virtual BaseSettings CreateNew()
Expand Down
29 changes: 13 additions & 16 deletions src/MCM.Abstractions/Base/Global/ExternalGlobalSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml;
Expand All @@ -14,23 +15,19 @@ namespace MCM.Abstractions.Base.Global
{
public sealed class ExternalGlobalSettings : FluentGlobalSettings
{
private static SettingsPropertyDefinition FromXml(IPropertyGroupDefinition group, PropertyBaseXmlModel xmlModel, char subGroupDelimiter)
private static SettingsPropertyDefinition FromXml(IPropertyGroupDefinition group, PropertyBaseXmlModel xmlModel, char subGroupDelimiter) => xmlModel switch
{
return xmlModel switch
{
PropertyBoolXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<bool>(model.Value), subGroupDelimiter),
PropertyDropdownXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<Dropdown<string>>(new Dropdown<string>(model.Values, model.SelectedIndex)), subGroupDelimiter),
PropertyFloatingIntegerXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<float>((float) model.Value), subGroupDelimiter),
PropertyIntegerXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<int>((int) model.Value), subGroupDelimiter),
PropertyTextXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<string>(model.Value), subGroupDelimiter),
_ => throw new Exception()
};
}
PropertyBoolXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<bool>(model.Value), subGroupDelimiter),
PropertyDropdownXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<Dropdown<string>>(new Dropdown<string>(model.Values, model.SelectedIndex)), subGroupDelimiter),
PropertyFloatingIntegerXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<float>((float) model.Value), subGroupDelimiter),
PropertyIntegerXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<int>((int) model.Value), subGroupDelimiter),
PropertyTextXmlModel model =>
new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(model), group, new StorageRef<string>(model.Value), subGroupDelimiter),
};

public static ExternalGlobalSettings? CreateFromXmlFile(string filePath, PropertyChangedEventHandler? propertyChanged = null)
{
Expand Down
12 changes: 8 additions & 4 deletions src/MCM.Abstractions/Extensions/BaseSettingsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ public static IEnumerable<SettingsPropertyGroupDefinition> GetUnsortedSettingPro
{
if (settings is IFluentSettings fluentSettings)
return fluentSettings.SettingPropertyGroups;

var discoverers = GenericServiceProvider.GetService<IEnumerable<ISettingsPropertyDiscoverer>>() ?? Enumerable.Empty<ISettingsPropertyDiscoverer>();
var discoverer = discoverers.FirstOrDefault(x => x.DiscoveryTypes.Any(y => y == settings.DiscoveryType));
return SettingsUtils.GetSettingsPropertyGroups(settings.SubGroupDelimiter, discoverer?.GetProperties(settings) ?? Enumerable.Empty<ISettingsPropertyDefinition>());
return settings.SettingPropertyGroups;
}

public static IEnumerable<ISettingsPropertyDefinition> GetAllSettingPropertyDefinitions(this BaseSettings settings) =>
Expand All @@ -32,5 +29,12 @@ public static IEnumerable<SettingsPropertyGroupDefinition> GetAllSettingProperty

public static IEnumerable<ISettingsPreset> GetExternalPresets(this BaseSettings settings) =>
GenericServiceProvider.GetService<BaseSettingsProvider>()?.GetPresets(settings.Id) ?? Enumerable.Empty<ISettingsPreset>();

internal static IEnumerable<SettingsPropertyGroupDefinition> CreateSettingPropertyGroups(this BaseSettings baseSettings)
{
var discoverers = GenericServiceProvider.GetService<IEnumerable<ISettingsPropertyDiscoverer>>() ?? Enumerable.Empty<ISettingsPropertyDiscoverer>();
var discoverer = discoverers.FirstOrDefault(x => x.DiscoveryTypes.Any(y => y == baseSettings.DiscoveryType));
return SettingsUtils.GetSettingsPropertyGroups(baseSettings.SubGroupDelimiter, discoverer?.GetProperties(baseSettings) ?? Enumerable.Empty<ISettingsPropertyDefinition>());
}
}
}
2 changes: 2 additions & 0 deletions src/MCM.Abstractions/FluentBuilder/BaseSettingsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public abstract class BaseSettingsBuilder : ISettingsBuilder
public abstract ISettingsBuilder CreateGroup(string name, Action<ISettingsPropertyGroupBuilder> builder);
public abstract ISettingsBuilder CreatePreset(string id, string name, Action<ISettingsPresetBuilder> builder);

public abstract ISettingsBuilder WithoutDefaultPreset();

public abstract FluentGlobalSettings BuildAsGlobal();
public abstract FluentPerSaveSettings BuildAsPerSave();
public abstract FluentPerCampaignSettings BuildAsPerCampaign();
Expand Down
2 changes: 2 additions & 0 deletions src/MCM.Abstractions/FluentBuilder/ISettingsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public interface ISettingsBuilder
/// <returns>The settings builder.</returns>
ISettingsBuilder CreatePreset(string id, string name, Action<ISettingsPresetBuilder> builder);

ISettingsBuilder WithoutDefaultPreset();

/// <summary>
/// Returns a Global setting instance.
/// Use Register and Unregister for MCM to use it.
Expand Down
8 changes: 2 additions & 6 deletions src/MCM.Abstractions/Models/SettingsPropertyDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

using System;
using System.Collections.Generic;
using System.Linq;

namespace MCM.Abstractions
{
Expand Down Expand Up @@ -149,11 +148,8 @@ public SettingsPropertyDefinition(IEnumerable<IPropertyDefinitionBase> propertyD
public SettingsPropertyDefinition Clone(bool keepRefs = true)
{
var localPropValue = PropertyReference.Value;
return new SettingsPropertyDefinition(
SettingsUtils.GetPropertyDefinitionWrappers(this),
new PropertyGroupDefinitionWrapper(this),
keepRefs ? PropertyReference : new StorageRef(localPropValue),
SubGroupDelimiter);
var value = keepRefs ? PropertyReference : new StorageRef(localPropValue is ICloneable cloneable ? cloneable.Clone() : localPropValue);
return new SettingsPropertyDefinition(SettingsUtils.GetPropertyDefinitionWrappers(this), new PropertyGroupDefinitionWrapper(this), value, SubGroupDelimiter);
}
}
}
2 changes: 1 addition & 1 deletion src/MCM.Bannerlord/MCMImplementationSubModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,4 @@ static void MoveDirectory(string source, string target)
catch (Exception) { }
}
}
}
}
3 changes: 2 additions & 1 deletion src/MCM.Bannerlord/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Contains internal code that provides implementations for Bannerlord API
Contains internal code that provides implementations for Bannerlord API
TODO: v6 - rename namespance to Bannerlord or keep Internal?
40 changes: 33 additions & 7 deletions src/MCM.Common/Dropdown.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,54 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;

namespace MCM.Common
{
public sealed class Dropdown<T> : List<T>, IEqualityComparer<Dropdown<T>>
public sealed class Dropdown<T> : List<T>, IEqualityComparer<Dropdown<T>>, INotifyPropertyChanged, ICloneable
{
public static Dropdown<T> Empty => new(Enumerable.Empty<T>(), 0);

public int SelectedIndex { get; set; }
private int _selectedIndex;
private T _selectedValue;

public event PropertyChangedEventHandler? PropertyChanged;

public int SelectedIndex { get => _selectedIndex; set => SetField(ref _selectedIndex, value, nameof(SelectedIndex)); }

public T SelectedValue
{
get => this[SelectedIndex];
set
{
var index = IndexOf(value);
if (index == -1)
return;
SelectedIndex = index;
if (SetField(ref _selectedValue, value, nameof(SelectedValue)))
{
var index = IndexOf(value);
if (index == -1)
return;
SelectedIndex = index;
}
}
}

public Dropdown(IEnumerable<T> values, int selectedIndex) : base(values)
{
SelectedIndex = selectedIndex;
if (SelectedIndex != 0 && SelectedIndex >= Count)
throw new Exception();
Debug.Fail($"Invalid 'SelectedIndex' set for Dropdown! {selectedIndex}, max is {Count}");
}

private void OnPropertyChanged([CallerMemberName] string? propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

private bool SetField<TVal>(ref TVal field, TVal value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<TVal>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}

/// <inheritdoc/>
Expand All @@ -36,6 +58,7 @@ public Dropdown(IEnumerable<T> values, int selectedIndex) : base(values)

/// <inheritdoc/>
public override int GetHashCode() => GetHashCode(this);

/// <inheritdoc/>
public override bool Equals(object? obj)
{
Expand All @@ -44,5 +67,8 @@ public override bool Equals(object? obj)

return ReferenceEquals(this, obj);
}

/// <inheritdoc />
public object Clone() => new Dropdown<T>(this, SelectedIndex);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ public override ISettingsBuilder CreateGroup(string name, Action<ISettingsProper
/// <inheritdoc/>
public override ISettingsBuilder CreatePreset(string id, string name, Action<ISettingsPresetBuilder> builder)
{
if (!Presets.ContainsKey(name))
Presets[name] = new DefaultSettingsPresetBuilder(id, name);
builder.Invoke(Presets[name]);
if (!Presets.ContainsKey(id))
Presets[id] = new DefaultSettingsPresetBuilder(id, name);
builder.Invoke(Presets[id]);
return this;
}

public ISettingsBuilder WithoutDefaultPreset()
public override ISettingsBuilder WithoutDefaultPreset()
{
Presets.Remove(BaseSettings.DefaultPresetId);
return this;
Expand Down
18 changes: 3 additions & 15 deletions src/MCM.UI/Actions/SetSelectedIndexAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,18 @@ namespace MCM.UI.Actions
{
internal sealed class SetSelectedIndexAction : IAction
{
private IRef SelectedIndexContext { get; }
public IRef Context { get; }
public object? Value { get; }
public object? Original { get; }

public SetSelectedIndexAction(IRef context, object value)
{
Context = context;

SelectedIndexContext = new ProxyRef<int>(
() => Context.Value is not null ? new SelectedIndexWrapper(Context.Value).SelectedIndex : 0,
o =>
{
if (Context.Value is not null)
{
var wrapper = new SelectedIndexWrapper(Context.Value);
wrapper.SelectedIndex = o;
}
});
Value = new SelectedIndexWrapper(value).SelectedIndex;
Original = SelectedIndexContext.Value;
Original = new SelectedIndexWrapper(context.Value).SelectedIndex;
}

public void DoAction() => SelectedIndexContext.Value = Value;
public void UndoAction() => SelectedIndexContext.Value = Original;
public void DoAction() => new SelectedIndexWrapper(Context.Value) { SelectedIndex = (int?) Value ?? -1 };
public void UndoAction() => new SelectedIndexWrapper(Context.Value) { SelectedIndex = (int?) Original ?? -1 };
}
}
9 changes: 6 additions & 3 deletions src/MCM.UI/ButterLib/ButterLibSettingsContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public ButterLibSettingsContainer(ILogger<ButterLibSettingsContainer> logger)
{
RootFolder = Path.Combine(PlatformFileHelperPCExtended.GetDirectoryFullPath(EngineFilePaths.ConfigsPath), "ModSettings");

var prop = new StorageRef<Dropdown<string>>(new(new[]
var minLogLevelValues = new string[]
{
$"{{=2Tp85Cpa}}{LogLevel.Trace}",
$"{{=Es0LPYu1}}{LogLevel.Debug}",
Expand All @@ -34,16 +34,19 @@ public ButterLibSettingsContainer(ILogger<ButterLibSettingsContainer> logger)
$"{{=7tpjjYSV}}{LogLevel.Error}",
$"{{=CarGIPlL}}{LogLevel.Critical}",
$"{{=T3FtC5hh}}{LogLevel.None}"
}, 2));
};
var minLogLevelProp = new StorageRef<Dropdown<string>>(new Dropdown<string>(minLogLevelValues, 2));
var displayName = new TextObject("{=ButterLibSettings_Name}ButterLib {VERSION}", new()
{
{ "VERSION", typeof(ButterLibSubModule).Assembly.GetName().Version?.ToString(3) ?? "ERROR" }
}).ToString();
var settings = BaseSettingsBuilder.Create("Options", displayName)?.SetFolderName("ButterLib").SetFormat("json2")
.CreateGroup("{=ButterLibSettings_Name_Logging}Logging", builder =>
builder.AddDropdown("MinLogLevel", "{=ButterLibSettings_Name_LogLevel}Log Level", 0, prop, dBuilder =>
builder.AddDropdown("MinLogLevel", "{=ButterLibSettings_Name_LogLevel}Log Level", 0, minLogLevelProp, dBuilder =>
dBuilder.SetOrder(1).SetRequireRestart(true).SetHintText("{=ButterLibSettings_Name_LogLevelDesc}Level of logs to write.")))
.AddButterLibSubSystems()
.CreatePreset(BaseSettings.DefaultPresetId, BaseSettings.DefaultPresetName, pBuilder =>
pBuilder.SetPropertyValue("MinLogLevel", new Dropdown<string>(minLogLevelValues, 2)))
.BuildAsGlobal();
RegisterSettings(settings);
}
Expand Down
Loading

0 comments on commit bbb8d97

Please sign in to comment.