Config.java 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package me.lortseam.completeconfig.data;
  2. import lombok.NonNull;
  3. import lombok.extern.log4j.Log4j2;
  4. import me.lortseam.completeconfig.api.ConfigContainer;
  5. import me.lortseam.completeconfig.data.text.TranslationIdentifier;
  6. import me.lortseam.completeconfig.io.ConfigSource;
  7. import net.fabricmc.loader.api.FabricLoader;
  8. import java.util.*;
  9. @Log4j2
  10. public class Config extends Collection {
  11. private static final Set<Config> configs = new HashSet<>();
  12. static {
  13. Runtime.getRuntime().addShutdownHook(new Thread(() -> {
  14. for (Config config : configs) {
  15. config.save();
  16. }
  17. }));
  18. }
  19. /**
  20. * Creates a new config builder for the specified mod.
  21. *
  22. * @param modID the ID of the mod creating the config
  23. */
  24. public static Builder builder(@NonNull String modID) {
  25. if (!FabricLoader.getInstance().isModLoaded(modID)) {
  26. throw new IllegalArgumentException("Mod " + modID + " is not loaded");
  27. }
  28. return new Builder(modID);
  29. }
  30. private final ConfigSource source;
  31. private Config(ConfigSource source, LinkedHashSet<ConfigContainer> children) {
  32. super(new TranslationIdentifier(source.getModID()));
  33. this.source = source;
  34. resolve(children);
  35. if (isEmpty()) {
  36. logger.warn("[CompleteConfig] Config of " + source + " is empty!");
  37. return;
  38. }
  39. source.load(this);
  40. configs.add(this);
  41. }
  42. public String getModID() {
  43. return source.getModID();
  44. }
  45. public TranslationIdentifier getTranslation() {
  46. return translation;
  47. }
  48. public void save() {
  49. source.save(this);
  50. }
  51. @Log4j2
  52. public final static class Builder {
  53. private final String modID;
  54. private String[] branch = new String[0];
  55. private final LinkedHashSet<ConfigContainer> children = new LinkedHashSet<>();
  56. private Builder(String modID) {
  57. this.modID = modID;
  58. }
  59. /**
  60. * Sets the branch. Every config of a mod needs a unique branch, therefore setting a branch is only required
  61. * when using more than one config.
  62. *
  63. * <p>The branch determines the location of the config's save file.
  64. *
  65. * @param branch the branch
  66. * @return this builder
  67. */
  68. public Builder setBranch(@NonNull String[] branch) {
  69. Arrays.stream(branch).forEach(Objects::requireNonNull);
  70. this.branch = branch;
  71. return this;
  72. }
  73. /**
  74. * Adds one or more containers to the config.
  75. *
  76. * @param containers one or more containers
  77. * @return this builder
  78. */
  79. public Builder add(@NonNull ConfigContainer... containers) {
  80. Arrays.stream(containers).forEach(Objects::requireNonNull);
  81. for (ConfigContainer container : containers) {
  82. if (!children.add(container)) {
  83. throw new IllegalArgumentException("Duplicate container");
  84. }
  85. }
  86. return this;
  87. }
  88. /**
  89. * Completes the config creation.
  90. *
  91. * @return the handler associated with the created config
  92. */
  93. public Config build() {
  94. if (children.isEmpty()) {
  95. logger.warn("[CompleteConfig] Mod " + modID + " tried to create an empty config!");
  96. return null;
  97. }
  98. return new Config(new ConfigSource(modID, branch), children);
  99. }
  100. }
  101. }