Exlll / ConfigLib

A Minecraft library for saving, loading, updating, and commenting YAML configuration files
MIT License
135 stars 17 forks source link

Enums as Keys in Maps #6

Closed Joo200 closed 2 years ago

Joo200 commented 6 years ago

I need a Map<Material, Double> in my configuration. Maybe you can add Enums as Map keys, thanks :)

I tried the following:

public class ChairsConfig extends BukkitYamlConfiguration {
    public ChairsConfig(Path path) {
        super(path);
        this.loadAndSave();
        if(validChairs.isEmpty()) {
            validChairs.put(Material.SPRUCE_STAIRS, 0.7);
            validChairs.put(Material.JUNGLE_STAIRS, 0.7);
            validChairs.put(Material.OAK_STAIRS, 0.7);
            validChairs.put(Material.BIRCH_STAIRS, 0.7);
            validChairs.put(Material.SANDSTONE_STAIRS, 0.7);
            validChairs.put(Material.COBBLESTONE_STAIRS, 0.7);
            validChairs.put(Material.BRICK_STAIRS, 0.7);
            validChairs.put(Material.NETHER_BRICK_STAIRS, 0.7);
            validChairs.put(Material.QUARTZ_STAIRS, 0.7);
            validChairs.put(Material.ACACIA_STAIRS, 0.7);
            validChairs.put(Material.DARK_OAK_STAIRS, 0.7);
            validChairs.put(Material.RED_SANDSTONE_STAIRS, 0.7);
            validChairs.put(Material.PURPUR_STAIRS, 0.7);
            this.save();
        }
    }

    @Comment("Set the blocks you want to be able to sit down on and sitting height. Use material_name:sitting_height")
    @ElementType(Material.class)
    public Map<Material, Double> validChairs = new HashMap<>();
}

The error after server start:

[16:32:13] [Server thread/ERROR]: Error occurred while enabling Chairs v4.2 (Is it up to date?)
de.exlll.configlib.ConfigurationException: The keys of map 'validChairs' must be simple types.
    at de.exlll.configlib.Validator.checkMapKeysSimple(Validator.java:90) ~[?:?]
    at de.exlll.configlib.Validator.checkMapKeysAndValues(Validator.java:82) ~[?:?]
    at de.exlll.configlib.Converters$MapConverter.preConvertTo(Converters.java:323) ~[?:?]
    at de.exlll.configlib.Converters.convertTo(Converters.java:41) ~[?:?]
    at de.exlll.configlib.FieldMapper.toConvertibleObject(FieldMapper.java:36) ~[?:?]
    at de.exlll.configlib.FieldMapper.instanceToMap(FieldMapper.java:22) ~[?:?]
    at de.exlll.configlib.Configuration.save(Configuration.java:51) ~[?:?]
    at com.cnaude.chairs.config.ChairsConfig.<init>(ChairsConfig.java:42) ~[?:?]
    at com.cnaude.chairs.core.Chairs.onEnable(Chairs.java:55) ~[?:?]
    at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264) ~[spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:339) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:403) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at org.bukkit.craftbukkit.v1_13_R2.CraftServer.enablePlugin(CraftServer.java:427) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at org.bukkit.craftbukkit.v1_13_R2.CraftServer.enablePlugins(CraftServer.java:341) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at net.minecraft.server.v1_13_R2.MinecraftServer.l(MinecraftServer.java:582) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at net.minecraft.server.v1_13_R2.MinecraftServer.a(MinecraftServer.java:545) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at net.minecraft.server.v1_13_R2.MinecraftServer.a(MinecraftServer.java:423) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at net.minecraft.server.v1_13_R2.DedicatedServer.init(DedicatedServer.java:288) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at net.minecraft.server.v1_13_R2.MinecraftServer.run(MinecraftServer.java:698) [spigot-1.13.1.jar:git-Spigot-2440e18-d0bb0a1]
    at java.lang.Thread.run(Unknown Source) [?:?]
Exlll commented 6 years ago

Hi,

implementing a general solution to this problem will take some time. In the meantime you can write your own Converter implementation or convert the map using an additional field and the postLoad hook.

final class MaterialMapConverter implements
        Converter<Map<Material, Double>, Map<String, Double>> {

    @Override
    public Map<String, Double> convertTo(
            Map<Material, Double> element, ConversionInfo info
    ) {
        return element.entrySet().stream()
                .collect(toMap(
                        o -> o.getKey().toString(),
                        Map.Entry::getValue
                ));
    }

    @Override
    public Map<Material, Double> convertFrom(
            Map<String, Double> element, ConversionInfo info
    ) {
        return element.entrySet().stream()
                .collect(toMap(
                        o -> Material.getMaterial(o.getKey()),
                        Map.Entry::getValue
                ));
    }
}
@Convert(MaterialMapConverter.class)
public Map<Material, Double> validChairs = new HashMap<>();
Exlll commented 2 years ago

Using enums as map keys now works out of the box with version 3. The ElementType annotation is also not necessary anymore (and, therefore, gone). Only took 4 years. :tipping_hand_man: