From c8286c987943e51a508d6e82b00013c16986a725 Mon Sep 17 00:00:00 2001 From: Mari023 <38946771+Mari023@users.noreply.github.com> Date: Thu, 9 Jan 2025 14:42:11 +0100 Subject: [PATCH] use own config manager to preserve unknown terminal config values (see #317) --- .../api/terminal/AE2wtlibConfigManager.java | 124 ++++++++++++++++++ .../ae2wtlib/api/terminal/ItemWT.java | 20 +++ .../de/mari_023/ae2wtlib/wat/ItemWAT.java | 3 +- 3 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 ae2wtlib_api/src/main/java/de/mari_023/ae2wtlib/api/terminal/AE2wtlibConfigManager.java diff --git a/ae2wtlib_api/src/main/java/de/mari_023/ae2wtlib/api/terminal/AE2wtlibConfigManager.java b/ae2wtlib_api/src/main/java/de/mari_023/ae2wtlib/api/terminal/AE2wtlibConfigManager.java new file mode 100644 index 00000000..26bc64e5 --- /dev/null +++ b/ae2wtlib_api/src/main/java/de/mari_023/ae2wtlib/api/terminal/AE2wtlibConfigManager.java @@ -0,0 +1,124 @@ +package de.mari_023.ae2wtlib.api.terminal; + +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; + +import appeng.api.config.Setting; +import appeng.api.ids.AEComponents; +import appeng.api.util.IConfigManager; +import appeng.api.util.IConfigManagerBuilder; +import appeng.api.util.IConfigManagerListener; +import appeng.api.util.UnsupportedSettingException; + +public class AE2wtlibConfigManager implements IConfigManager { + private static final Logger LOG = LoggerFactory.getLogger(AE2wtlibConfigManager.class); + + private final Map, Enum> settings = new IdentityHashMap<>(); + @Nullable + private Map settingsMap; + private final IConfigManagerListener listener; + + public AE2wtlibConfigManager(IConfigManagerListener listener) { + this.listener = listener; + } + + @Override + public Set> getSettings() { + return settings.keySet(); + } + + public > void registerSetting(Setting setting, T defaultValue) { + settings.put(setting, defaultValue); + } + + @Override + public > T getSetting(Setting setting) { + var oldValue = settings.get(setting); + + if (oldValue == null) { + throw new UnsupportedSettingException("Setting " + setting.getName() + " is not supported."); + } + + return setting.getEnumClass().cast(oldValue); + } + + @Override + public > void putSetting(Setting setting, T newValue) { + if (!settings.containsKey(setting)) { + throw new UnsupportedSettingException("Setting " + setting.getName() + " is not supported."); + } + settings.put(setting, newValue); + listener.onSettingChanged(this, setting); + } + + @Override + public void writeToNBT(CompoundTag tagCompound, HolderLookup.Provider registries) { + throw new UnsupportedOperationException("Not implemented."); + } + + @Override + public boolean readFromNBT(CompoundTag tagCompound, HolderLookup.Provider registries) { + throw new UnsupportedOperationException("Not implemented."); + } + + @Override + public boolean importSettings(Map settings) { + settingsMap = settings; + boolean anythingRead = false; + for (var setting : this.settings.keySet()) { + String value = settings.get(setting.getName()); + if (value != null) { + try { + setting.setFromString(this, value); + anythingRead = true; + } catch (IllegalArgumentException e) { + LOG.warn("Failed to load setting {} from value '{}': {}", setting, value, e.getMessage()); + } + } + } + return anythingRead; + } + + @Override + public Map exportSettings() { + Map result = settingsMap == null ? new HashMap<>() : new HashMap<>(settingsMap); + for (var entry : settings.entrySet()) { + result.put(entry.getKey().getName(), settings.get(entry.getKey()).toString()); + } + return Map.copyOf(result); + } + + /** + * Get a builder for configuration manager that stores its settings in a wireless terminal. This is different from + * AE2's ConfigManager in that it keeps around unknown values instead of deleting them + */ + public static IConfigManagerBuilder builder(Supplier stack) { + var manager = new AE2wtlibConfigManager( + (mgr, settingName) -> stack.get().set(AEComponents.EXPORTED_SETTINGS, mgr.exportSettings())); + + return new IConfigManagerBuilder() { + @Override + public > IConfigManagerBuilder registerSetting(Setting setting, T defaultValue) { + manager.registerSetting(setting, defaultValue); + return this; + } + + @Override + public IConfigManager build() { + manager.importSettings(stack.get().getOrDefault(AEComponents.EXPORTED_SETTINGS, Map.of())); + return manager; + } + }; + } +} diff --git a/ae2wtlib_api/src/main/java/de/mari_023/ae2wtlib/api/terminal/ItemWT.java b/ae2wtlib_api/src/main/java/de/mari_023/ae2wtlib/api/terminal/ItemWT.java index 00895226..d877c02f 100644 --- a/ae2wtlib_api/src/main/java/de/mari_023/ae2wtlib/api/terminal/ItemWT.java +++ b/ae2wtlib_api/src/main/java/de/mari_023/ae2wtlib/api/terminal/ItemWT.java @@ -1,5 +1,7 @@ package de.mari_023.ae2wtlib.api.terminal; +import java.util.function.Supplier; + import org.jetbrains.annotations.Nullable; import net.minecraft.world.InteractionHand; @@ -12,6 +14,11 @@ import net.minecraft.world.level.Level; import net.minecraft.world.phys.BlockHitResult; +import appeng.api.config.Settings; +import appeng.api.config.SortDir; +import appeng.api.config.SortOrder; +import appeng.api.config.ViewItems; +import appeng.api.util.IConfigManager; import appeng.core.AEConfig; import appeng.helpers.WirelessTerminalMenuHost; import appeng.items.tools.powered.WirelessTerminalItem; @@ -66,4 +73,17 @@ public WirelessTerminalMenuHost getMenuHost(Player player, ItemMenuHostLocato public boolean isNotReplaceableByPickAction(ItemStack stack, Player player, int inventorySlot) { return true; } + + /** + * Return the config manager for the wireless terminal. + * + * @return config manager of wireless terminal + */ + public IConfigManager getConfigManager(Supplier target) { + return AE2wtlibConfigManager.builder(target) + .registerSetting(Settings.SORT_BY, SortOrder.NAME) + .registerSetting(Settings.VIEW_MODE, ViewItems.ALL) + .registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING) + .build(); + } } diff --git a/src/main/java/de/mari_023/ae2wtlib/wat/ItemWAT.java b/src/main/java/de/mari_023/ae2wtlib/wat/ItemWAT.java index fa4b9e51..60b8f82b 100644 --- a/src/main/java/de/mari_023/ae2wtlib/wat/ItemWAT.java +++ b/src/main/java/de/mari_023/ae2wtlib/wat/ItemWAT.java @@ -11,6 +11,7 @@ import appeng.api.util.IConfigManager; import appeng.menu.locator.ItemMenuHostLocator; +import de.mari_023.ae2wtlib.api.terminal.AE2wtlibConfigManager; import de.mari_023.ae2wtlib.api.terminal.ItemWT; public class ItemWAT extends ItemWT { @@ -20,7 +21,7 @@ public MenuType getMenuType(ItemMenuHostLocator locator, Player player) { } public IConfigManager getConfigManager(Supplier target) { - return IConfigManager.builder(target) + return AE2wtlibConfigManager.builder(target) .registerSetting(Settings.TERMINAL_SHOW_PATTERN_PROVIDERS, ShowPatternProviders.VISIBLE) .build(); }