aboutsummaryrefslogtreecommitdiff
path: root/runtime-engine/initialization/src/main/java/me
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2022-08-05 01:30:08 +0800
committershedaniel <daniel@shedaniel.me>2022-08-26 10:53:55 +0900
commit8c13c015031a0de865d2e767cd8e879754f803e2 (patch)
tree2bb6fa6578b63d1c216b863a6c4206295c044b36 /runtime-engine/initialization/src/main/java/me
parent8f5d3ef632f3d1a733c98ce5607c9fd5a0fd7567 (diff)
downloadRoughlyEnoughItems-8c13c015031a0de865d2e767cd8e879754f803e2.tar.gz
RoughlyEnoughItems-8c13c015031a0de865d2e767cd8e879754f803e2.tar.bz2
RoughlyEnoughItems-8c13c015031a0de865d2e767cd8e879754f803e2.zip
More work
Diffstat (limited to 'runtime-engine/initialization/src/main/java/me')
-rw-r--r--runtime-engine/initialization/src/main/java/me/shedaniel/rei/impl/client/init/CoreClientInitialization.java159
-rw-r--r--runtime-engine/initialization/src/main/java/me/shedaniel/rei/impl/common/init/CoreInitialization.java113
2 files changed, 272 insertions, 0 deletions
diff --git a/runtime-engine/initialization/src/main/java/me/shedaniel/rei/impl/client/init/CoreClientInitialization.java b/runtime-engine/initialization/src/main/java/me/shedaniel/rei/impl/client/init/CoreClientInitialization.java
new file mode 100644
index 000000000..44df96bc4
--- /dev/null
+++ b/runtime-engine/initialization/src/main/java/me/shedaniel/rei/impl/client/init/CoreClientInitialization.java
@@ -0,0 +1,159 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.init;
+
+import dev.architectury.event.Event;
+import dev.architectury.event.EventFactory;
+import dev.architectury.event.EventResult;
+import dev.architectury.event.events.client.ClientGuiEvent;
+import dev.architectury.event.events.client.ClientRecipeUpdateEvent;
+import me.shedaniel.rei.api.client.REIRuntime;
+import me.shedaniel.rei.api.client.config.ConfigManager;
+import me.shedaniel.rei.api.client.config.ConfigObject;
+import me.shedaniel.rei.api.client.config.addon.ConfigAddonRegistry;
+import me.shedaniel.rei.api.client.entry.renderer.EntryRendererRegistry;
+import me.shedaniel.rei.api.client.favorites.FavoriteEntryType;
+import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
+import me.shedaniel.rei.api.client.registry.category.CategoryRegistry;
+import me.shedaniel.rei.api.client.registry.display.DisplayRegistry;
+import me.shedaniel.rei.api.client.registry.entry.CollapsibleEntryRegistry;
+import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
+import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry;
+import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry;
+import me.shedaniel.rei.api.client.search.SearchProvider;
+import me.shedaniel.rei.api.client.search.method.InputMethodRegistry;
+import me.shedaniel.rei.api.client.subsets.SubsetsRegistry;
+import me.shedaniel.rei.api.client.view.Views;
+import me.shedaniel.rei.api.common.plugins.PluginManager;
+import me.shedaniel.rei.api.common.plugins.PluginView;
+import me.shedaniel.rei.api.common.plugins.REIPluginProvider;
+import me.shedaniel.rei.api.common.registry.ReloadStage;
+import me.shedaniel.rei.impl.client.ClientInternals;
+import me.shedaniel.rei.impl.common.InternalLogger;
+import me.shedaniel.rei.impl.common.init.CoreInitialization;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
+import org.apache.commons.lang3.mutable.MutableLong;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.concurrent.*;
+
+@ApiStatus.Internal
+public class CoreClientInitialization {
+ public static final Event<ClientRecipeUpdateEvent> PRE_UPDATE_RECIPES = EventFactory.createLoop();
+ private static final ExecutorService RELOAD_PLUGINS = Executors.newSingleThreadScheduledExecutor(task -> {
+ Thread thread = new Thread(task, "REI-ReloadPlugins");
+ thread.setDaemon(true);
+ thread.setUncaughtExceptionHandler(($, exception) -> {
+ InternalLogger.getInstance().throwException(exception);
+ });
+ return thread;
+ });
+ private static final List<Future<?>> RELOAD_TASKS = new CopyOnWriteArrayList<>();
+
+ public void onInitializeClient() {
+ attachClientInternals();
+ loadTestPlugins();
+
+ MutableLong startReload = new MutableLong(-1);
+ MutableLong endReload = new MutableLong(-1);
+ PRE_UPDATE_RECIPES.register(recipeManager -> {
+ PluginReloaderImpl.PERFORMANCE_LOGGER.clear();
+ CoreInitialization.reloadPlugins(startReload, ReloadStage.START);
+ });
+ ClientRecipeUpdateEvent.EVENT.register(recipeManager -> {
+ CoreInitialization.reloadPlugins(endReload, ReloadStage.END);
+ });
+ ClientGuiEvent.INIT_PRE.register((screen, access) -> {
+ List<ReloadStage> stages = PluginManager.getInstance().view().getObservedStages();
+
+ if (Minecraft.getInstance().level != null && Minecraft.getInstance().player != null && stages.contains(ReloadStage.START)
+ && !stages.contains(ReloadStage.END) && !PluginManager.areAnyReloading() && screen instanceof AbstractContainerScreen) {
+ for (Future<?> task : RELOAD_TASKS) {
+ if (!task.isDone()) {
+ return EventResult.pass();
+ }
+ }
+
+ InternalLogger.getInstance().error("Detected missing stage: END! This is possibly due to issues during client recipe reload! REI will force a reload of the recipes now!");
+ CoreInitialization.reloadPlugins(endReload, ReloadStage.END);
+ }
+
+ return EventResult.pass();
+ });
+ }
+
+ public static void attachClientInternals() {
+ PluginManager<REIClientPlugin> manager = ClientInternals.getPluginManager();
+ manager.registerReloadable(EntryRendererRegistry.class);
+ manager.registerReloadable(Views.class);
+ manager.registerReloadable(InputMethodRegistry.class);
+ manager.registerReloadable(SearchProvider.class);
+ manager.registerReloadable(ConfigManager.class);
+ manager.registerReloadable(EntryRegistry.class);
+ manager.registerReloadable(CollapsibleEntryRegistry.class);
+ manager.registerReloadable(CategoryRegistry.class);
+ manager.registerReloadable(DisplayRegistry.class);
+ manager.registerReloadable(ScreenRegistry.class);
+ manager.registerReloadable(FavoriteEntryType.Registry.class);
+ manager.registerReloadable(SubsetsRegistry.class);
+ manager.registerReloadable(TransferHandlerRegistry.class);
+ manager.registerReloadable(REIRuntime.class);
+ manager.registerReloadable(ConfigAddonRegistry.class);
+ }
+
+ private void loadTestPlugins() {
+ if (System.getProperty("rei.test", "false").equals("true")) {
+ try {
+ PluginView.getClientInstance().registerPlugin((REIPluginProvider<? extends REIClientPlugin>) Class.forName("me.shedaniel.rei.plugin.test.REITestPlugin")
+ .getDeclaredConstructor()
+ .newInstance());
+ } catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public static boolean reloadPluginsClient(@Nullable ReloadStage start) {
+ if (ConfigObject.getInstance().doesRegisterRecipesInAnotherThread()) {
+ Future<?>[] futures = new Future<?>[1];
+ CompletableFuture<Void> future = CompletableFuture.runAsync(() -> CoreInitialization._reloadPlugins(start), RELOAD_PLUGINS)
+ .whenComplete((unused, throwable) -> {
+ // Remove the future from the list of futures
+ if (futures[0] != null) {
+ RELOAD_TASKS.remove(futures[0]);
+ futures[0] = null;
+ }
+ });
+ futures[0] = future;
+ RELOAD_TASKS.add(future);
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/runtime-engine/initialization/src/main/java/me/shedaniel/rei/impl/common/init/CoreInitialization.java b/runtime-engine/initialization/src/main/java/me/shedaniel/rei/impl/common/init/CoreInitialization.java
new file mode 100644
index 000000000..c5945ead1
--- /dev/null
+++ b/runtime-engine/initialization/src/main/java/me/shedaniel/rei/impl/common/init/CoreInitialization.java
@@ -0,0 +1,113 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.common.init;
+
+import dev.architectury.platform.Platform;
+import dev.architectury.registry.ReloadListenerRegistry;
+import dev.architectury.utils.Env;
+import me.shedaniel.rei.api.common.display.DisplaySerializerRegistry;
+import me.shedaniel.rei.api.common.entry.comparison.FluidComparatorRegistry;
+import me.shedaniel.rei.api.common.entry.comparison.ItemComparatorRegistry;
+import me.shedaniel.rei.api.common.entry.settings.EntrySettingsAdapterRegistry;
+import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry;
+import me.shedaniel.rei.api.common.fluid.FluidSupportProvider;
+import me.shedaniel.rei.api.common.plugins.PluginManager;
+import me.shedaniel.rei.api.common.plugins.REIPlugin;
+import me.shedaniel.rei.api.common.plugins.REIServerPlugin;
+import me.shedaniel.rei.api.common.registry.RecipeManagerContext;
+import me.shedaniel.rei.api.common.registry.ReloadStage;
+import me.shedaniel.rei.api.common.transfer.info.MenuInfoRegistry;
+import me.shedaniel.rei.impl.common.Internals;
+import me.shedaniel.rei.impl.client.init.CoreClientInitialization;
+import me.shedaniel.rei.impl.common.InternalLogger;
+import net.minecraft.server.packs.PackType;
+import net.minecraft.util.Unit;
+import org.apache.commons.lang3.mutable.MutableLong;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable;
+
+@ApiStatus.Internal
+public class CoreInitialization {
+ public void onInitialize() {
+ attachCommonInternals();
+
+ if (Platform.getEnvironment() == Env.SERVER) {
+ MutableLong lastReload = new MutableLong(-1);
+ ReloadListenerRegistry.register(PackType.SERVER_DATA, (preparationBarrier, resourceManager, profilerFiller, profilerFiller2, executor, executor2) -> {
+ return preparationBarrier.wait(Unit.INSTANCE).thenRunAsync(PluginManager::reloadAll, executor2);
+ });
+ }
+ }
+
+ public static void attachCommonInternals() {
+ PluginManager<REIPlugin<?>> manager = PluginManager.getInstance();
+ manager.registerReloadable(EntryTypeRegistry.class);
+ manager.registerReloadable(EntrySettingsAdapterRegistry.class);
+ manager.registerReloadable(RecipeManagerContext.class);
+ manager.registerReloadable(ItemComparatorRegistry.class);
+ manager.registerReloadable(FluidComparatorRegistry.class);
+ manager.registerReloadable(DisplaySerializerRegistry.class);
+ manager.registerReloadable(FluidSupportProvider.class);
+ PluginManager<REIServerPlugin> serverManager = PluginManager.getServerInstance();
+ serverManager.registerReloadable(MenuInfoRegistry.class);
+ Internals.attachInstanceSupplier((Runnable) () -> reloadPlugins(null, null), "reloadREI");
+ }
+
+ public static void _reloadPlugins(@Nullable ReloadStage stage) {
+ if (stage == null) {
+ for (ReloadStage reloadStage : ReloadStage.values()) {
+ _reloadPlugins(reloadStage);
+ }
+ return;
+ }
+ try {
+ for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) {
+ instance.view().pre(stage);
+ }
+ for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) {
+ instance.startReload(stage);
+ }
+ for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) {
+ instance.view().post(stage);
+ }
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ }
+ }
+
+ public static void reloadPlugins(MutableLong lastReload, @Nullable ReloadStage start) {
+ if (lastReload != null) {
+ if (lastReload.getValue() > 0 && System.currentTimeMillis() - lastReload.getValue() <= 5000) {
+ InternalLogger.getInstance().warn("Suppressing Reload Plugins of stage " + start);
+ return;
+ }
+ lastReload.setValue(System.currentTimeMillis());
+ }
+ if (start == null) PluginReloaderImpl.PERFORMANCE_LOGGER.clear();
+ if (Platform.getEnvironment() == Env.CLIENT) {
+ if (CoreClientInitialization.reloadPluginsClient(start)) return;
+ }
+ _reloadPlugins(start);
+ }
+}