Skip to content

Commit

Permalink
Fixup mod setting standalone facets, still not completely working wit…
Browse files Browse the repository at this point in the history
…h nullable HasValue
  • Loading branch information
Nytra committed Dec 24, 2024
1 parent 63309c9 commit 50e383e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,18 @@ private static async IAsyncEnumerable<DataFeedItem> GenerateNullableEnumItemsAsy

nullableToggle.InitBase(configKey.FullId + ".HasValue", path, nullableGroupKeys, Mod.GetLocaleString("NullableEnumHasValue.Name"));
nullableToggle.InitDescription(configKey.GetLocaleKey("HasValue").AsLocaleKey());
nullableToggle.InitSetupValue(field => field.SyncWithNullableConfigKeyHasValue(configKey));
nullableToggle.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.SyncWithNullableConfigKeyHasValue(configKey);
});
yield return nullableToggle;

var enumItems = (IAsyncEnumerable<DataFeedItem>)_generateEnumItemsAsync
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FrooxEngine;
using Elements.Core;
using FrooxEngine;
using FrooxEngine.UIX;
using HarmonyLib;
using MonkeyLoader.Configuration;
Expand All @@ -19,11 +20,29 @@ internal sealed class ModSettingStandaloneFacet : ResoniteMonkey<ModSettingStand
private const string ModSettingStandaloneFacetTag = "MonkeyLoaderStandaloneFacet";

private static readonly MethodInfo _syncWithConfigKeyWrapperMethod = AccessTools.Method(typeof(ModSettingStandaloneFacet), nameof(SyncWithConfigKeyWrapper));
private static readonly MethodInfo _syncWithNullableConfigKeyHasValueMethod = AccessTools.Method(typeof(FieldExtensions), "SyncWithNullableConfigKeyHasValue");

protected override IEnumerable<IFeaturePatch> GetFeaturePatches() => [];

private static IDefiningConfigKey? GetConfigKeyByFullId(string fullId)
{
foreach (var gamePack in Mod.Loader.GamePacks)
{
if (fullId.StartsWith(gamePack.Id))
{
var partialId = fullId.Remove(0, gamePack.Id.Length + 1);

if (!partialId.StartsWith("Config."))
partialId = "Config." + partialId;

Logger.Debug(() => "Partial Id: " + partialId);
if (gamePack.TryGet<IDefiningConfigKey>().ByPartialId(partialId, out var modConfigKey))
return modConfigKey;

break;
}
}

if (fullId.StartsWith(Mod.Loader.Id))
{
var partialId = fullId.Remove(0, Mod.Loader.Id.Length + 1);
Expand Down Expand Up @@ -73,8 +92,19 @@ internal sealed class ModSettingStandaloneFacet : ResoniteMonkey<ModSettingStand
return null;
}

private static void SyncWithConfigKeyWrapper<T>(IField field, IDefiningConfigKey key, string? eventLabel)
=> ((IField<T>)field).SyncWithConfigKey((IDefiningConfigKey<T>)key, eventLabel);
private static void SyncWithConfigKeyWrapper<T>(IField field, IDefiningConfigKey key, string? eventLabel) where T : unmanaged
{
if (typeof(T) == typeof(bool) && key.ValueType.IsNullable())
{
//((IField<bool>)field).SyncWithNullableConfigKeyHasValue((IDefiningConfigKey<T>)key, eventLabel);
var type = key.ValueType.GetGenericArguments()[0];
_syncWithNullableConfigKeyHasValueMethod.MakeGenericMethod(type).Invoke(null, [(IField<bool>)field, key, eventLabel, true]);
}
else
{
((IField<T>)field).SyncWithConfigKey(key, eventLabel);
}
}

[HarmonyPatch(typeof(Facet), nameof(Facet.OnLoading))]
[HarmonyPatchCategory(nameof(ModSettingStandaloneFacet))]
Expand Down Expand Up @@ -131,7 +161,8 @@ private class UIGrabInstancerPatch
[HarmonyPostfix]
private static void TryGrabPostfix(UIGrabInstancer __instance, IGrabbable? __result)
{
if (!__instance.World.IsUserspace() || __result is not Grabbable
if (!__instance.World.IsUserspace() ||
__result is not Grabbable
|| __result?.Slot.GetComponent<Facet>() is null
|| __instance.Slot.GetComponentInParents<FeedItemInterface>() is null
|| __instance.Slot.GetComponentInParents<SettingsDataFeed>() is null
Expand Down
18 changes: 12 additions & 6 deletions MonkeyLoader.Resonite.Integration/FieldExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Elements.Core;
using FrooxEngine;
using MonkeyLoader.Configuration;
using MonkeyLoader.Meta;
using MonkeyLoader.Resonite.Configuration;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -122,13 +123,17 @@ public static Action<IChangeable> SyncWithNullableConfigKeyHasValue<T>(this IFie
IDefiningConfigKey<T?> configKey, string? eventLabel = null, bool allowWriteBack = true)
where T : unmanaged
{
configKey.FindNearestParent<Mod>().Logger.Info(() => $"Syncing with nullable config key: {configKey.Id}");

field.Value = configKey.GetValue().HasValue;
eventLabel ??= field.GetWriteBackEventLabel();

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

void ParentDestroyedHandler(IDestroyable _)
{
configKey.FindNearestParent<Mod>().Logger.Info(() => $"Parent destroyed: {configKey.Id}");

parent.Destroyed -= ParentDestroyedHandler;

field.Changed -= FieldChangedHandler;
Expand All @@ -137,19 +142,20 @@ void ParentDestroyedHandler(IDestroyable _)

void FieldChangedHandler(IChangeable _)
{
configKey.FindNearestParent<Mod>().Logger.Info(() => $"Field changed: {configKey.Id} {field.Value} {configKey.GetValue().HasValue} {allowWriteBack}");

T? newValue = field.Value ? default : null;
var keyValue = configKey.GetValue().HasValue;

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

void ConfigKeyChangedHandler(object sender, ConfigKeyChangedEventArgs<T?> args)
{
var keyValue = configKey.GetValue().HasValue;
configKey.FindNearestParent<Mod>().Logger.Info(() => $"Config key changed: {configKey.Id} {field.Value} {configKey.GetValue().HasValue}");

if (field.Value != keyValue)
field.World.RunSynchronously(() => field.Value = keyValue);
if (field.Value != configKey.GetValue().HasValue)
field.World.RunSynchronously(() => field.Value = configKey.GetValue().HasValue);
}

field.Changed += FieldChangedHandler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public sealed class TooltipConfig : SingletonConfigSection<TooltipConfig>
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);
private static readonly DefiningConfigKey<float?> _testKey4 = new("testKey4", "Test key4.", () => null);

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

0 comments on commit 50e383e

Please sign in to comment.