Skip to content

Commit

Permalink
Consolidate enum generation and config key syncing
Browse files Browse the repository at this point in the history
  • Loading branch information
Nytra committed Dec 23, 2024
1 parent 9be5c84 commit 56ea063
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ private static async IAsyncEnumerable<DataFeedItem> EnumerateConfigAsync(Enumera
}
}

private static async IAsyncEnumerable<DataFeedItem> GenerateEnumItemsAsync<T>(IReadOnlyList<string> path, IReadOnlyList<string> groupKeys, IDefiningConfigKey<T> configKey)
private static async IAsyncEnumerable<DataFeedItem> GenerateEnumItemsAsync<T>(IReadOnlyList<string> path, IReadOnlyList<string> groupKeys, IDefiningConfigKey configKey)
where T : Enum
{
await Task.CompletedTask;

if (configKey.ValueType.GetCustomAttribute<FlagsAttribute>() is null)
if (typeof(T).GetCustomAttribute<FlagsAttribute>() is null)
{
var enumField = new DataFeedEnum<T>();
enumField.InitBase(path, groupKeys, configKey);
Expand All @@ -99,11 +99,11 @@ private static async IAsyncEnumerable<DataFeedItem> GenerateEnumItemsAsync<T>(IR
yield break;
}

var items = (IEnumerable<DataFeedItem>)_generateFlagsEnumItems
var items = (IAsyncEnumerable<DataFeedItem>)_generateFlagsEnumItems
.MakeGenericMethod(typeof(T))
.Invoke(null, [path, groupKeys, configKey]);

foreach (var item in items)
await foreach (var item in items)
{
if (item is DataFeedGroup)
{
Expand Down Expand Up @@ -152,20 +152,18 @@ private static IAsyncEnumerable<DataFeedItem> GenerateItemsForConfigKey<T>(Enume

if (configKey.ValueType.IsEnum)
{
var flagsEnumItems = (IAsyncEnumerable<DataFeedItem>)_generateEnumItemsAsync
var enumItems = (IAsyncEnumerable<DataFeedItem>)_generateEnumItemsAsync
.MakeGenericMethod(configKey.ValueType)
.Invoke(null, [path, groupKeys, configKey]);

return flagsEnumItems;
return enumItems;
}

if (configKey.ValueType.IsNullable())
{
var nullableType = configKey.ValueType.GetGenericArguments()[0];
if (nullableType.IsEnum)
{
//return GenerateNullableEnumItemsAsync(path, groupKeys, configKey, nullableType);

var nullableEnumItems = (IAsyncEnumerable<DataFeedItem>)_generateNullableEnumItemsAsync
.MakeGenericMethod(nullableType)
.Invoke(null, [path, groupKeys, configKey]);
Expand Down Expand Up @@ -211,44 +209,12 @@ private static async IAsyncEnumerable<DataFeedItem> GenerateNullableEnumItemsAsy
nullableToggle.InitSetupValue(field => field.SyncWithNullableConfigKeyHasValue(configKey));
yield return nullableToggle;

if (typeof(T).GetCustomAttribute<FlagsAttribute>() is null)
{
var enumField = new DataFeedEnum<T>();
enumField.InitBase(configKey.FullId, path, nullableGroupKeys, configKey.GetLocaleString("Name"), configKey.GetLocaleString("Description"));
enumField.InitSetupValue(field =>
{
var slot = field.FindNearestParent<Slot>();

if (slot.GetComponentInParents<FeedItemInterface>() is FeedItemInterface feedItemInterface)
{
// Adding the config key's full id to make it easier to create standalone facets
feedItemInterface.Slot.AttachComponent<Comment>().Text.Value = configKey.FullId;
}

field.SyncWithNullableConfigKeyValue(configKey, SettingsHelpers.ConfigKeyChangeLabel);
});
yield return enumField;
}
else
{
var items = (IEnumerable<DataFeedItem>)_generateFlagsEnumItems
var enumItems = (IAsyncEnumerable<DataFeedItem>)_generateEnumItemsAsync
.MakeGenericMethod(typeof(T))
.Invoke(null, [path, groupKeys, configKey]);
.Invoke(null, [path, nullableGroupKeys, configKey]);

foreach (var item in items)
{
if (item is DataFeedGroup)
{
item.ItemKey = configKey.FullId + ".Flags";
item.GroupingParameters = nullableGroupKeys;
}
else if (item is DataFeedToggle)
{
item.GroupingParameters = nullableGroupKeys.Concat([configKey.FullId + ".Flags"]).ToArray();
}
yield return item;
}
}
await foreach (var item in enumItems)
yield return item;
}

private static async IAsyncEnumerable<DataFeedItem> GenerateFlagsEnumFields<T>(IReadOnlyList<string> path, IReadOnlyList<string> groupKeys, IDefiningConfigKey configKey)
Expand All @@ -261,7 +227,6 @@ private static async IAsyncEnumerable<DataFeedItem> GenerateFlagsEnumFields<T>(I
flagsEnumGroup.InitDescription(configKey.GetLocaleKey("Description").AsLocaleKey());
yield return flagsEnumGroup;

//var flagsGrouping = new[] { configKey.Section.Id, configKey.FullId };
var flagsGrouping = groupKeys.Concat(configKey.FullId).ToArray();

var enumType = typeof(T);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public static bool IsInjectableEditorType(this Type type)
/// <typeparam name="T">The type of the field and config item's value.</typeparam>
/// <param name="field">The field to synchronize with the <paramref name="configKey"/>.</param>
/// <param name="configKey">The config key to synchronize with the <paramref name="field"/>.</param>
public static void SetupConfigKeyField<T>(this IField<T> field, IDefiningConfigKey<T> configKey)
public static void SetupConfigKeyField<T>(this IField<T> field, IDefiningConfigKey configKey)
{
var slot = field.FindNearestParent<Slot>();

Expand Down
96 changes: 50 additions & 46 deletions MonkeyLoader.Resonite.Integration/FieldExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ public static string GetReferenceLabel(this IWorldElement? target)
/// <param name="allowWriteBack">Whether changes of the <paramref name="field"/> should be written back to the config key.</param>
/// <returns>The delegate subscribed to the <paramref name="field"/>'s <see cref="IChangeable.Changed">Changed</see> event.</returns>
public static Action<IChangeable> SyncWithConfigKey<T>(this IField<T> field,
IDefiningConfigKey<T> configKey, string? eventLabel = null, bool allowWriteBack = true)
IDefiningConfigKey configKey, string? eventLabel = null, bool allowWriteBack = true)
{
field.Value = configKey.GetValue()!;
field.Value = (T)(configKey.GetValue() ?? default(T)!);
eventLabel ??= field.GetWriteBackEventLabel();

var parent = field.FindNearestParent<Component>();
Expand All @@ -90,14 +90,18 @@ void ParentDestroyedHandler(IDestroyable _)

void FieldChangedHandler(IChangeable _)
{
if (Equals(field.Value, configKey.GetValue()) && (!allowWriteBack || !configKey.TrySetValue(field.Value, eventLabel)))
field.World.RunSynchronously(() => field.Value = configKey.GetValue()!);
if (!Equals(field.Value, configKey.GetValue()) &&
!(configKey.ValueType.IsNullable() && configKey.ValueType.GetGenericArguments()[0].IsEnum && configKey.GetValue() is null && Equals(field.Value, default(T))) &&
(!allowWriteBack || !configKey.TrySetValue(field.Value, eventLabel)))
{
field.World.RunSynchronously(() => field.Value = (T)(configKey.GetValue() ?? default(T)!));
}
}

void ConfigKeyChangedHandler(object sender, ConfigKeyChangedEventArgs<T> args)
void ConfigKeyChangedHandler(object sender, IConfigKeyChangedEventArgs args)
{
if (!Equals(field.Value, configKey.GetValue()))
field.World.RunSynchronously(() => field.Value = configKey.GetValue()!);
field.World.RunSynchronously(() => field.Value = (T)(configKey.GetValue() ?? default(T)!));
}

field.Changed += FieldChangedHandler;
Expand Down Expand Up @@ -162,46 +166,46 @@ void ConfigKeyChangedHandler(object sender, ConfigKeyChangedEventArgs<T?> args)
/// the <paramref name="field"/> is set to <c>default(<typeparamref name="T"/>)</c>.
/// </summary>
/// <inheritdoc cref="SyncWithConfigKey{T}(IField{T}, IDefiningConfigKey{T}, string?, bool)"/>
public static Action<IChangeable> SyncWithNullableConfigKeyValue<T>(this IField<T> field,
IDefiningConfigKey<T?> configKey, string? eventLabel = null, bool allowWriteBack = true)
where T : unmanaged
{
// support for nullables requires this to never be null
field.Value = configKey.GetValue() ?? default;
eventLabel ??= field.GetWriteBackEventLabel();

var parent = field.FindNearestParent<Component>();

void ParentDestroyedHandler(IDestroyable _)
{
parent.Destroyed -= ParentDestroyedHandler;

field.Changed -= FieldChangedHandler;
configKey.Changed -= ConfigKeyChangedHandler;
}

void FieldChangedHandler(IChangeable _)
{
var keyValue = configKey.GetValue() ?? default;

if (!Equals(field.Value, keyValue) && (!allowWriteBack || !configKey.TrySetValue(field.Value, eventLabel)))
field.World.RunSynchronously(() => field.Value = keyValue);
}

void ConfigKeyChangedHandler(object sender, ConfigKeyChangedEventArgs<T?> args)
{
var keyValue = configKey.GetValue() ?? default;

if (!Equals(field.Value, keyValue))
field.World.RunSynchronously(() => field.Value = keyValue);
}

field.Changed += FieldChangedHandler;
configKey.Changed += ConfigKeyChangedHandler;
parent.Destroyed += ParentDestroyedHandler;

return FieldChangedHandler;
}
//public static Action<IChangeable> SyncWithNullableConfigKeyValue<T>(this IField<T> field,
// IDefiningConfigKey<T?> configKey, string? eventLabel = null, bool allowWriteBack = true)
// where T : unmanaged
//{
// // support for nullables requires this to never be null
// field.Value = configKey.GetValue() ?? default;
// eventLabel ??= field.GetWriteBackEventLabel();

// var parent = field.FindNearestParent<Component>();

// void ParentDestroyedHandler(IDestroyable _)
// {
// parent.Destroyed -= ParentDestroyedHandler;

// field.Changed -= FieldChangedHandler;
// configKey.Changed -= ConfigKeyChangedHandler;
// }

// void FieldChangedHandler(IChangeable _)
// {
// var keyValue = configKey.GetValue() ?? default;

// if (!Equals(field.Value, keyValue) && (!allowWriteBack || !configKey.TrySetValue(field.Value, eventLabel)))
// field.World.RunSynchronously(() => field.Value = keyValue);
// }

// void ConfigKeyChangedHandler(object sender, ConfigKeyChangedEventArgs<T?> args)
// {
// var keyValue = configKey.GetValue() ?? default;

// if (!Equals(field.Value, keyValue))
// field.World.RunSynchronously(() => field.Value = keyValue);
// }

// field.Changed += FieldChangedHandler;
// configKey.Changed += ConfigKeyChangedHandler;
// parent.Destroyed += ParentDestroyedHandler;

// return FieldChangedHandler;
//}

private static string GetWriteBackEventLabel(this IField field)
=> $"SyncedField.WriteBack.{field.World.GetIdentifier()}";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public sealed class TooltipConfig : SingletonConfigSection<TooltipConfig>
new ConfigKeyRange<float>(.5f, 4)
};

private static readonly DefiningConfigKey<ShadowType> _testKey0 = new("testKey0", "Test key0.", () => ShadowType.Hard);
private static readonly DefiningConfigKey<ShadowType?> _testKey = new("testKey", "Test key.", () => ShadowType.Soft);
private static readonly DefiningConfigKey<MappingTarget> _testKey3 = new("testKey3", "Test key3.", () => MappingTarget.NONE);
private static readonly DefiningConfigKey<MappingTarget?> _testKey2 = new("testKey2", "Test key2.", () => null);

/// <summary>
/// Gets the background color for tooltips.
/// </summary>
Expand Down

0 comments on commit 56ea063

Please sign in to comment.