diff options
author | nea <romangraef@gmail.com> | 2022-07-26 14:34:31 +0200 |
---|---|---|
committer | nea <romangraef@gmail.com> | 2022-07-26 14:37:44 +0200 |
commit | 39769a4aafb1b793c8041bcf0dcf437799717b13 (patch) | |
tree | 672824bf0deb4abc64440b8716f37456fe0ca59b /src/main/java/io/github | |
parent | f38206401e76303f04c7d82f24cbd1fa034d354f (diff) | |
download | neurepoparsing-39769a4aafb1b793c8041bcf0dcf437799717b13.tar.gz neurepoparsing-39769a4aafb1b793c8041bcf0dcf437799717b13.tar.bz2 neurepoparsing-39769a4aafb1b793c8041bcf0dcf437799717b13.zip |
stuff
Diffstat (limited to 'src/main/java/io/github')
8 files changed, 144 insertions, 6 deletions
diff --git a/src/main/java/io/github/moulberry/repo/NEURepoFile.java b/src/main/java/io/github/moulberry/repo/NEURepoFile.java index df25d43..613c614 100644 --- a/src/main/java/io/github/moulberry/repo/NEURepoFile.java +++ b/src/main/java/io/github/moulberry/repo/NEURepoFile.java @@ -11,7 +11,6 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.LinkOption; import java.nio.file.Path; @AllArgsConstructor(access = AccessLevel.PACKAGE) diff --git a/src/main/java/io/github/moulberry/repo/NEURepository.java b/src/main/java/io/github/moulberry/repo/NEURepository.java index d1d49f4..b5f942c 100644 --- a/src/main/java/io/github/moulberry/repo/NEURepository.java +++ b/src/main/java/io/github/moulberry/repo/NEURepository.java @@ -3,7 +3,8 @@ package io.github.moulberry.repo; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; -import io.github.moulberry.repo.data.Coordinate; +import com.google.gson.typeadapters.RuntimeTypeAdapterFactory; +import io.github.moulberry.repo.data.*; import lombok.Getter; import lombok.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -15,23 +16,69 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; - +/** + * The base object for a structured in memory representation of the NEU repository files. + */ public final class NEURepository { final Gson gson = new GsonBuilder() .setPrettyPrinting() .registerTypeAdapter(new TypeToken<Coordinate>() { }.getType(), new Coordinate.CoordinateSerializer()) + .registerTypeAdapterFactory( + RuntimeTypeAdapterFactory.of(NEURecipe.class, "type") + .registerSubtype(NEUForgeRecipe.class, "forge") + .registerSubtype(NEUTradeRecipe.class, "trade") + .registerSubtype(NEUCraftingRecipe.class, "crafting") + .registerSubtype(NEUMobDropRecipe.class, "drops") + .setDefaultTypeTag("crafting") + ) .create(); + /** + * The base path of this repository. This is the folder containing the {@code .git} folder.. + */ @Getter final Path baseFolder; + /** + * All constants loaded in the {@code constant} folder of the repository. + */ @Getter final NEUConstants constants; + /** + * All {@link IReloadable}s linked to this repository. Those can be either content that needs to be reloaded, caches + * that need to be marked as dirty, or other. + */ @Getter final List<IReloadable> reloadables = new ArrayList<>(); + /** + * All items loaded in the {@code items} folder of the repository. + */ @Getter final NEUItems items; + /** + * If the current state of the repository is unstable. Unstable means that either the repository is + * {@link #isIncomplete} or the repository is currently being {@link #reload()}ed and therefore may have mismatched + * versions of different objects. + */ + @Getter + boolean isUnstable = true; + /** + * If the current state of the repository is incomplete. Incomplete means that either there hasn't been a + * {@link #reload()} yet, or the last reload completed exceptionally. + */ + @Getter + boolean isIncomplete = true; + + /** + * Create an in memory loaded repository of the given file path. This function doesn't do any loading, instead + * {@link #reload()} has to be manually called by the caller of this function. Consecutive calls with the same + * arguments will result in distinct objects, a common instance should be manually maintained. + * + * @param baseFolder the base folder of the repository. (should contain {@code README.md}, among other files) + * + * @return a {@link NEURepository} instance corresponding to this path. + */ public static NEURepository of(@NonNull Path baseFolder) { return new NEURepository(baseFolder); } @@ -45,34 +92,70 @@ public final class NEURepository { registerReloadListener(this.items); } + /** + * Registers a {@link IReloadable} to be called whenever {@link #reload()} is invoked. Reloaders are called in the + * order that they are registered (with internal reloadables like {@link NEUItems} and {@link NEUConstants} always + * being reloaded first). + */ public void registerReloadListener(IReloadable reloadable) { reloadables.add(reloadable); } - public void reload() throws NEURepositoryException { + /** + * Reloads the repository from disk. During reloading the state of the repository may be unstable. However, every + * individual state (like the collection of all items, the collection fo all fairy souls) are updated atomically, + * therefore it is advised to store those objects if consecutive queries should be executed in the same repository + * context. + * + * @throws NEURepositoryException if there is an exception during loading, every other reloadable will still be + * reloaded (which may result in an inconsistent loaded state), and all exceptions + * will collectively be thrown after all reloads have finished using + * {@link Throwable#addSuppressed} + */ + public synchronized void reload() throws NEURepositoryException { List<NEURepositoryException> storedExceptions = new ArrayList<>(); + isUnstable = true; for (IReloadable reloadable : reloadables) { try { reloadable.reload(this); } catch (NEURepositoryException e) { storedExceptions.add(e); + } catch (Exception e) { + storedExceptions.add(new NEURepositoryException("<unknown>", "Invalid non NEU exception thrown during repository reload", e)); } } for (int i = 1; i < storedExceptions.size(); i++) { storedExceptions.get(0).addSuppressed(storedExceptions.get(i)); } if (storedExceptions.size() > 0) { + isIncomplete = true; throw storedExceptions.get(0); } + isUnstable = false; + isIncomplete = false; } - + /** + * Obtain a {@link NEURepoFile} that is guaranteed to exist. + * + * @param path the relative path of the file you want + * + * @throws NEURepositoryException if the file does not exist. this exception should be propagated. if you instead + * want to react to a non existance of the file, use {@link #file} instead. + */ public NEURepoFile requireFile(@NonNull String path) throws NEURepositoryException { NEURepoFile file = file(path); if (file == null) throw new NEURepositoryException(path, "this file is required", null); return file; } + /** + * Obtain a {@link NEURepoFile}. + * + * @param path the relative path of the file you want + * + * @return the file as a repo file, or {@code null} if it doesn't exist. + */ @Nullable public NEURepoFile file(@NonNull String path) { Path fsPath = baseFolder.resolve(path); @@ -82,7 +165,8 @@ public final class NEURepository { } /** - * @return a stream of {@link NEURepoFile}s below this path. This stream needs to be closed + * @return a stream of {@link NEURepoFile}s contained within this relative path. This stream needs to be manually + * closed. */ public Stream<NEURepoFile> tree(@NonNull String path) throws NEURepositoryException { Path fsPath = baseFolder.resolve(path); diff --git a/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java new file mode 100644 index 0000000..cf025d4 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java @@ -0,0 +1,4 @@ +package io.github.moulberry.repo.data; + +public class NEUCraftingRecipe implements NEURecipe { +} diff --git a/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java new file mode 100644 index 0000000..6dbed06 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java @@ -0,0 +1,5 @@ +package io.github.moulberry.repo.data; + + +public class NEUForgeRecipe implements NEURecipe { +} diff --git a/src/main/java/io/github/moulberry/repo/data/NEUItem.java b/src/main/java/io/github/moulberry/repo/data/NEUItem.java index 7503544..61d08aa 100644 --- a/src/main/java/io/github/moulberry/repo/data/NEUItem.java +++ b/src/main/java/io/github/moulberry/repo/data/NEUItem.java @@ -1,8 +1,10 @@ package io.github.moulberry.repo.data; import com.google.gson.annotations.SerializedName; +import lombok.AccessLevel; import lombok.Getter; +import java.util.ArrayList; import java.util.List; @Getter @@ -21,5 +23,37 @@ public class NEUItem { String modver; String infoType; List<String> info; + boolean vanilla = false; + + @SerializedName("recipe") + @Getter(value = AccessLevel.PRIVATE) + NEURecipe singletonRecipe = null; + @SerializedName("recipes") + @Getter(value = AccessLevel.PRIVATE) + List<NEURecipe> recipeList = new ArrayList<>(); + + + transient volatile List<NEURecipe> recipes; + + /** + * Returns directly associated recipes. This does not necessarily contain all recipes that result in this item, nor + * does this list have to contain any recipe that results in this item. To obtain such a list fulfilling those + * criteria, you will need to collect all recipes associated with all items, and filter those manually. + */ + public List<NEURecipe> getRecipes() { + if (recipes == null) { + synchronized (this) { + if (recipes == null) { + List<NEURecipe> newRecipes = new ArrayList<>(recipeList.size() + (singletonRecipe == null ? 0 : 1)); + newRecipes.addAll(recipeList); + if (singletonRecipe != null) + newRecipes.add(singletonRecipe); + recipes = newRecipes; + } + } + } + return recipes; + } + } diff --git a/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java new file mode 100644 index 0000000..6b5dfeb --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java @@ -0,0 +1,4 @@ +package io.github.moulberry.repo.data; + +public class NEUMobDropRecipe implements NEURecipe { +} diff --git a/src/main/java/io/github/moulberry/repo/data/NEURecipe.java b/src/main/java/io/github/moulberry/repo/data/NEURecipe.java new file mode 100644 index 0000000..4a49f17 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/NEURecipe.java @@ -0,0 +1,4 @@ +package io.github.moulberry.repo.data; + +public interface NEURecipe { +} diff --git a/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java new file mode 100644 index 0000000..7fd22f7 --- /dev/null +++ b/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java @@ -0,0 +1,4 @@ +package io.github.moulberry.repo.data; + +public class NEUTradeRecipe implements NEURecipe { +} |