aboutsummaryrefslogtreecommitdiff
path: root/runtime/src
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2021-10-20 18:41:27 +0800
committershedaniel <daniel@shedaniel.me>2021-10-22 01:41:12 +0800
commit843a29c5fcf8d20f7073438d9fbed7039dead719 (patch)
treecfe93852c0ba236dfa7989470bab7e63c602d7a2 /runtime/src
parenta95ce0972205bff98687c7d2bb1654e331c7e41f (diff)
downloadRoughlyEnoughItems-843a29c5fcf8d20f7073438d9fbed7039dead719.tar.gz
RoughlyEnoughItems-843a29c5fcf8d20f7073438d9fbed7039dead719.tar.bz2
RoughlyEnoughItems-843a29c5fcf8d20f7073438d9fbed7039dead719.zip
Fix modifying stacks at runtime, fixes support for JEITweaker
Diffstat (limited to 'runtime/src')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java15
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/EntryComparatorRegistryImpl.java6
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java71
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/logging/FileLogger.java68
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/logging/Log4JLogger.java44
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/logging/Logger.java108
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/logging/MultiLogger.java48
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/plugins/PluginManagerImpl.java71
9 files changed, 380 insertions, 53 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
index 6bab2c9d8..119841487 100644
--- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
+++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
@@ -23,6 +23,7 @@
package me.shedaniel.rei;
+import com.google.common.collect.ImmutableList;
import dev.architectury.platform.Platform;
import dev.architectury.registry.ReloadListenerRegistry;
import dev.architectury.utils.Env;
@@ -50,6 +51,10 @@ import me.shedaniel.rei.impl.common.entry.comparison.ItemComparatorRegistryImpl;
import me.shedaniel.rei.impl.common.entry.comparison.NbtHasherProviderImpl;
import me.shedaniel.rei.impl.common.entry.type.EntryTypeRegistryImpl;
import me.shedaniel.rei.impl.common.fluid.FluidSupportProviderImpl;
+import me.shedaniel.rei.impl.common.logging.FileLogger;
+import me.shedaniel.rei.impl.common.logging.Log4JLogger;
+import me.shedaniel.rei.impl.common.logging.Logger;
+import me.shedaniel.rei.impl.common.logging.MultiLogger;
import me.shedaniel.rei.impl.common.plugins.PluginManagerImpl;
import me.shedaniel.rei.impl.common.registry.RecipeManagerContextImpl;
import me.shedaniel.rei.impl.common.transfer.MenuInfoRegistryImpl;
@@ -58,7 +63,6 @@ import net.minecraft.server.packs.PackType;
import net.minecraft.util.Unit;
import org.apache.commons.lang3.mutable.MutableLong;
import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.ApiStatus;
import java.util.function.Function;
@@ -67,7 +71,10 @@ import java.util.function.UnaryOperator;
@ApiStatus.Internal
public class RoughlyEnoughItemsCore {
@ApiStatus.Internal
- public static final Logger LOGGER = LogManager.getFormatterLogger("REI");
+ public static final Logger LOGGER = new MultiLogger(ImmutableList.of(
+ new FileLogger(Platform.getGameFolder().resolve("logs/rei.log")),
+ new Log4JLogger(LogManager.getFormatterLogger("REI"))
+ ));
static {
attachCommonInternals();
@@ -123,13 +130,13 @@ public class RoughlyEnoughItemsCore {
}
try {
for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) {
- instance.view().pre();
+ instance.view().pre(stage);
}
for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) {
instance.startReload(stage);
}
for (PluginManager<? extends REIPlugin<?>> instance : PluginManager.getActiveInstances()) {
- instance.view().post();
+ instance.view().post(stage);
}
} catch (Throwable throwable) {
throwable.printStackTrace();
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java
index 3bf154c6b..1d52db2d9 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java
@@ -46,7 +46,7 @@ public class FilteringContextImpl implements FilteringContext {
public final Map<FilteringContextType, Set<HashedEntryStackWrapper>> stacks;
private final Map<FilteringContextType, Collection<EntryStack<?>>> cachedStacks;
- public FilteringContextImpl(List<EntryStack<?>> allStacks) {
+ public FilteringContextImpl(Collection<EntryStack<?>> allStacks) {
this.stacks = Maps.newHashMap();
this.cachedStacks = Maps.newHashMap();
for (FilteringContextType type : FilteringContextType.values()) {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/EntryComparatorRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/EntryComparatorRegistryImpl.java
index 38fe8e118..5a3cd7f59 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/EntryComparatorRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/EntryComparatorRegistryImpl.java
@@ -23,12 +23,11 @@
package me.shedaniel.rei.impl.common.entry.comparison;
+import me.shedaniel.rei.RoughlyEnoughItemsCore;
import me.shedaniel.rei.api.common.entry.comparison.ComparisonContext;
import me.shedaniel.rei.api.common.entry.comparison.EntryComparator;
import me.shedaniel.rei.api.common.entry.comparison.EntryComparatorRegistry;
import me.shedaniel.rei.api.common.registry.ReloadStage;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.ApiStatus;
import java.util.IdentityHashMap;
@@ -36,14 +35,13 @@ import java.util.Map;
@ApiStatus.Internal
public abstract class EntryComparatorRegistryImpl<T, S> implements EntryComparatorRegistry<T, S> {
- private static final Logger LOGGER = LogManager.getLogger(EntryComparatorRegistryImpl.class);
private final Map<S, EntryComparator<T>> comparators = new IdentityHashMap<>();
@Override
public void register(EntryComparator<T> comparator, S entry) {
EntryComparator<T> put = this.comparators.put(entry, comparator);
if (put != null) {
- LOGGER.warn("[REI] Overriding " + put + "entry comparator with " + comparator + "for " + entry + "! This may result in unwanted comparisons!");
+ RoughlyEnoughItemsCore.LOGGER.warn("[REI] Overriding " + put + "entry comparator with " + comparator + "for " + entry + "! This may result in unwanted comparisons!");
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java
index a52ee508a..024067b13 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java
@@ -34,10 +34,12 @@ import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.registry.ReloadStage;
import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.api.common.util.EntryStacks;
+import me.shedaniel.rei.impl.client.REIRuntimeImpl;
import me.shedaniel.rei.impl.client.config.ConfigObjectImpl;
import me.shedaniel.rei.impl.client.entry.filtering.FilteringContextImpl;
import me.shedaniel.rei.impl.client.entry.filtering.FilteringContextType;
import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule;
+import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl;
import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@@ -46,6 +48,7 @@ import net.minecraft.core.Registry;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
+import org.apache.commons.lang3.mutable.MutableLong;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@@ -58,8 +61,8 @@ import java.util.stream.Stream;
@ApiStatus.Internal
@Environment(EnvType.CLIENT)
public class EntryRegistryImpl implements EntryRegistry {
- private final List<EntryStack<?>> preFilteredList = Lists.newCopyOnWriteArrayList();
- private final List<EntryStack<?>> entries = Lists.newCopyOnWriteArrayList();
+ private List<EntryStack<?>> preFilteredList = Lists.newCopyOnWriteArrayList();
+ private List<EntryStack<?>> entries = Lists.newCopyOnWriteArrayList();
@Nullable
private List<HashedEntryStackWrapper> reloadingRegistry;
private boolean reloading;
@@ -76,22 +79,17 @@ public class EntryRegistryImpl implements EntryRegistry {
@Override
public void startReload() {
- entries.clear();
- if (reloadingRegistry != null) {
- reloadingRegistry.clear();
- }
+ entries = Lists.newCopyOnWriteArrayList();
reloadingRegistry = Lists.newArrayListWithCapacity(Registry.ITEM.keySet().size() + 100);
- preFilteredList.clear();
+ preFilteredList = Lists.newCopyOnWriteArrayList();
reloading = true;
}
@Override
public void endReload() {
reloading = false;
- preFilteredList.clear();
- reloadingRegistry.removeIf(HashedEntryStackWrapper::isEmpty);
- entries.clear();
- entries.addAll(CollectionUtils.map(reloadingRegistry, HashedEntryStackWrapper::unwrap));
+ preFilteredList = Lists.newCopyOnWriteArrayList();
+ entries = Lists.newCopyOnWriteArrayList(CollectionUtils.filterAndMap(reloadingRegistry, ((Predicate<HashedEntryStackWrapper>) HashedEntryStackWrapper::isEmpty).negate(), HashedEntryStackWrapper::unwrap));
reloadingRegistry = null;
refilter();
}
@@ -127,15 +125,13 @@ public class EntryRegistryImpl implements EntryRegistry {
Set<HashedEntryStackWrapper> hiddenStacks = context.stacks.get(FilteringContextType.HIDDEN);
if (hiddenStacks.isEmpty()) {
- preFilteredList.clear();
- preFilteredList.addAll(entries);
+ preFilteredList = Lists.newCopyOnWriteArrayList(entries);
} else {
- preFilteredList.clear();
- preFilteredList.addAll(entries.parallelStream()
+ preFilteredList = entries.parallelStream()
.map(HashedEntryStackWrapper::new)
.filter(not(hiddenStacks::contains))
.map(HashedEntryStackWrapper::unwrap)
- .collect(Collectors.toList()));
+ .collect(Collectors.toCollection(Lists::newCopyOnWriteArrayList));
}
RoughlyEnoughItemsCore.LOGGER.debug("Refiltered %d entries with %d rules in %s.", entries.size() - preFilteredList.size(), rules.size(), stopwatch.stop().toString());
@@ -168,6 +164,8 @@ public class EntryRegistryImpl implements EntryRegistry {
reloadingRegistry.add(index, new HashedEntryStackWrapper(stack));
} else reloadingRegistry.add(new HashedEntryStackWrapper(stack));
} else {
+ preFilteredList.addAll(refilterNew(Collections.singletonList(stack)));
+ queueSearchUpdate();
if (afterEntry != null) {
int index = entries.lastIndexOf(afterEntry);
entries.add(index, stack);
@@ -183,6 +181,8 @@ public class EntryRegistryImpl implements EntryRegistry {
reloadingRegistry.addAll(index, CollectionUtils.mapParallel(stacks, HashedEntryStackWrapper::new));
} else reloadingRegistry.addAll(CollectionUtils.mapParallel(stacks, HashedEntryStackWrapper::new));
} else {
+ preFilteredList.addAll(refilterNew((Collection<EntryStack<?>>) stacks));
+ queueSearchUpdate();
if (afterEntry != null) {
int index = entries.lastIndexOf(afterEntry);
entries.addAll(index, stacks);
@@ -190,6 +190,41 @@ public class EntryRegistryImpl implements EntryRegistry {
}
}
+ private void queueSearchUpdate() {
+ if (REIRuntimeImpl.getSearchField() != null) {
+ ScreenOverlayImpl.getEntryListWidget().updateSearch(REIRuntimeImpl.getSearchField().getText(), true);
+ }
+ }
+
+ private MutableLong lastRefilterWarning = new MutableLong(-1);
+
+ private Collection<EntryStack<?>> refilterNew(Collection<EntryStack<?>> entries) {
+ if (lastRefilterWarning != null) {
+ if (lastRefilterWarning.getValue() > 0 && System.currentTimeMillis() - lastRefilterWarning.getValue() > 5000) {
+ RoughlyEnoughItemsCore.LOGGER.warn("Detected runtime EntryRegistry modification, this can be extremely dangerous, or be extremely inefficient!");
+ }
+ lastRefilterWarning.setValue(System.currentTimeMillis());
+ }
+
+ FilteringContextImpl context = new FilteringContextImpl(entries);
+ List<FilteringRule<?>> rules = ((ConfigObjectImpl) ConfigObject.getInstance()).getFilteringRules();
+ for (int i = rules.size() - 1; i >= 0; i--) {
+ FilteringRule<?> rule = rules.get(i);
+ context.handleResult(rule.processFilteredStacks(context));
+ }
+
+ Set<HashedEntryStackWrapper> hiddenStacks = context.stacks.get(FilteringContextType.HIDDEN);
+ if (hiddenStacks.isEmpty()) {
+ return entries;
+ } else {
+ return entries.parallelStream()
+ .map(HashedEntryStackWrapper::new)
+ .filter(not(hiddenStacks::contains))
+ .map(HashedEntryStackWrapper::unwrap)
+ .collect(Collectors.toList());
+ }
+ }
+
@Override
public boolean alreadyContain(EntryStack<?> stack) {
if (reloading) {
@@ -203,6 +238,7 @@ public class EntryRegistryImpl implements EntryRegistry {
if (reloading) {
return reloadingRegistry.remove(new HashedEntryStackWrapper(stack));
} else {
+ preFilteredList.remove(stack);
return entries.remove(stack);
}
}
@@ -212,6 +248,7 @@ public class EntryRegistryImpl implements EntryRegistry {
if (reloading) {
return reloadingRegistry.removeIf(wrapper -> ((Predicate<EntryStack<?>>) predicate).test(wrapper.unwrap()));
} else {
+ preFilteredList.removeIf((Predicate<EntryStack<?>>) predicate);
return entries.removeIf((Predicate<EntryStack<?>>) predicate);
}
}
@@ -221,6 +258,7 @@ public class EntryRegistryImpl implements EntryRegistry {
if (reloading) {
return reloadingRegistry.removeIf(wrapper -> predicate.test(wrapper.hashExact()));
} else {
+ preFilteredList.removeIf(stack -> predicate.test(EntryStacks.hashExact(stack)));
return entries.removeIf(stack -> predicate.test(EntryStacks.hashExact(stack)));
}
}
@@ -230,6 +268,7 @@ public class EntryRegistryImpl implements EntryRegistry {
if (reloading) {
return reloadingRegistry.removeIf(wrapper -> predicate.test(EntryStacks.hashFuzzy(wrapper.unwrap())));
} else {
+ preFilteredList.removeIf(stack -> predicate.test(EntryStacks.hashFuzzy(stack)));
return entries.removeIf(stack -> predicate.test(EntryStacks.hashFuzzy(stack)));
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/FileLogger.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/FileLogger.java
new file mode 100644
index 000000000..13428d377
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/FileLogger.java
@@ -0,0 +1,68 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.logging;
+
+import org.apache.logging.log4j.Level;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class FileLogger implements Logger {
+ private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
+ private final Writer writer;
+
+ public FileLogger(Path file) {
+ try {
+ if (file.getParent() != null) Files.createDirectories(file.getParent());
+ file.toFile().createNewFile();
+ this.writer = new OutputStreamWriter(new FileOutputStream(file.toFile()), StandardCharsets.UTF_8);
+ } catch (IOException exception) {
+ throw new UncheckedIOException(exception);
+ }
+ }
+
+ @Override
+ public void log(Level level, String message) {
+ message = String.format("[%s] [%s/%s] %s", DATE_TIME_FORMATTER.format(LocalDateTime.now()), Thread.currentThread().getName(), level, message);
+
+ try {
+ writer.write(message);
+ writer.write("\n");
+ writer.flush();
+ } catch (IOException exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ @Override
+ public void log(Level level, String message, Throwable throwable) {
+ log(level, message);
+ throwable.printStackTrace(new PrintWriter(writer, true));
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/Log4JLogger.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/Log4JLogger.java
new file mode 100644
index 000000000..6faef4dc4
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/Log4JLogger.java
@@ -0,0 +1,44 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.logging;
+
+import org.apache.logging.log4j.Level;
+
+public class Log4JLogger implements Logger {
+ private final org.apache.logging.log4j.Logger logger;
+
+ public Log4JLogger(org.apache.logging.log4j.Logger logger) {
+ this.logger = logger;
+ }
+
+ @Override
+ public void log(Level level, String message) {
+ logger.log(level, message);
+ }
+
+ @Override
+ public void log(Level level, String message, Throwable throwable) {
+ logger.log(level, message, throwable);
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/Logger.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/Logger.java
new file mode 100644
index 000000000..dcc0ef098
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/Logger.java
@@ -0,0 +1,108 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.logging;
+
+import org.apache.logging.log4j.Level;
+
+public interface Logger {
+ void log(Level level, String message);
+
+ void log(Level level, String message, Throwable throwable);
+
+ default void log(Level level, String message, Object... args) {
+ log(level, String.format(message, args));
+ }
+
+ default void fatal(String message) {
+ log(Level.FATAL, message);
+ }
+
+ default void fatal(String message, Throwable throwable) {
+ log(Level.FATAL, message, throwable);
+ }
+
+ default void fatal(String message, Object... args) {
+ log(Level.FATAL, String.format(message, args));
+ }
+
+ default void error(String message) {
+ log(Level.ERROR, message);
+ }
+
+ default void error(String message, Throwable throwable) {
+ log(Level.ERROR, message, throwable);
+ }
+
+ default void error(String message, Object... args) {
+ log(Level.ERROR, String.format(message, args));
+ }
+
+ default void warn(String message) {
+ log(Level.WARN, message);
+ }
+
+ default void warn(String message, Throwable throwable) {
+ log(Level.WARN, message, throwable);
+ }
+
+ default void warn(String message, Object... args) {
+ log(Level.WARN, String.format(message, args));
+ }
+
+ default void info(String message) {
+ log(Level.INFO, message);
+ }
+
+ default void info(String message, Throwable throwable) {
+ log(Level.INFO, message, throwable);
+ }
+
+ default void info(String message, Object... args) {
+ log(Level.INFO, String.format(message, args));
+ }
+
+ default void debug(String message) {
+ log(Level.DEBUG, message);
+ }
+
+ default void debug(String message, Throwable throwable) {
+ log(Level.DEBUG, message, throwable);
+ }
+
+ default void debug(String message, Object... args) {
+ log(Level.DEBUG, String.format(message, args));
+ }
+
+ default void trace(String message) {
+ log(Level.TRACE, message);
+ }
+
+ default void trace(String message, Throwable throwable) {
+ log(Level.TRACE, message, throwable);
+ }
+
+ default void trace(String message, Object... args) {
+ log(Level.TRACE, String.format(message, args));
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/MultiLogger.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/MultiLogger.java
new file mode 100644
index 000000000..d333d4ba2
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/logging/MultiLogger.java
@@ -0,0 +1,48 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.logging;
+
+import org.apache.logging.log4j.Level;
+
+public class MultiLogger implements Logger {
+ private final Iterable<Logger> loggers;
+
+ public MultiLogger(Iterable<Logger> loggers) {
+ this.loggers = loggers;
+ }
+
+ @Override
+ public void log(Level level, String message) {
+ for (Logger logger : loggers) {
+ logger.log(level, message);
+ }
+ }
+
+ @Override
+ public void log(Level level, String message, Throwable throwable) {
+ for (Logger logger : loggers) {
+ logger.log(level, message, throwable);
+ }
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/plugins/PluginManagerImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/plugins/PluginManagerImpl.java
index 5969aada1..d49081816 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/common/plugins/PluginManagerImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/plugins/PluginManagerImpl.java
@@ -123,12 +123,14 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager<
}
private static class SectionClosable implements Closeable {
+ private ReloadStage stage;
private MutablePair<Stopwatch, String> sectionData;
- public SectionClosable(MutablePair<Stopwatch, String> sectionData, String section) {
- this.sectionData = sectionData;
+ public SectionClosable(ReloadStage stage, String section) {
+ this.stage = stage;
+ this.sectionData = new MutablePair<>(Stopwatch.createUnstarted(), "");
sectionData.setRight(section);
- RoughlyEnoughItemsCore.LOGGER.debug("Reloading Section: \"%s\"", section);
+ RoughlyEnoughItemsCore.LOGGER.debug("[" + stage + "] Reloading Section: \"%s\"", section);
sectionData.getLeft().reset().start();
}
@@ -136,18 +138,18 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager<
public void close() {
sectionData.getLeft().stop();
String section = sectionData.getRight();
- RoughlyEnoughItemsCore.LOGGER.debug("Reloading Section: \"%s\" done in %s", section, sectionData.getLeft().toString());
+ RoughlyEnoughItemsCore.LOGGER.debug("[" + stage + "] Reloading Section: \"%s\" done in %s", section, sectionData.getLeft().toString());
sectionData.getLeft().reset();
}
}
- private SectionClosable section(MutablePair<Stopwatch, String> sectionData, String section) {
- return new SectionClosable(sectionData, section);
+ private SectionClosable section(ReloadStage stage, String section) {
+ return new SectionClosable(stage, section);
}
- private void pluginSection(MutablePair<Stopwatch, String> sectionData, String sectionName, List<P> list, @Nullable Reloadable<?> reloadable, Consumer<P> consumer) {
+ private void pluginSection(ReloadStage stage, String sectionName, List<P> list, @Nullable Reloadable<?> reloadable, Consumer<P> consumer) {
for (P plugin : list) {
- try (SectionClosable section = section(sectionData, sectionName + " for " + plugin.getPluginProviderName())) {
+ try (SectionClosable section = section(stage, sectionName + plugin.getPluginProviderName() + "/")) {
if (reloadable == null || !plugin.shouldBeForcefullyDoneOnMainThread(reloadable)) {
consumer.accept(plugin);
} else if (Platform.getEnvironment() == Env.CLIENT) {
@@ -173,21 +175,29 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager<
}
@Override
- public void pre() {
+ public void pre(ReloadStage stage) {
List<P> plugins = new ArrayList<>(getPlugins().toList());
plugins.sort(Comparator.comparingDouble(P::getPriority).reversed());
Collections.reverse(plugins);
- MutablePair<Stopwatch, String> sectionData = new MutablePair<>(Stopwatch.createUnstarted(), "");
- pluginSection(sectionData, "pre-register", plugins, null, REIPlugin::preRegister);
+ try (SectionClosable preRegister = section(stage, "pre-register/")) {
+ pluginSection(stage, "pre-register/", plugins, null, plugin -> {
+ plugin.preRegister();
+ ((REIPlugin<P>) plugin).preStage(this, stage);
+ });
+ }
}
@Override
- public void post() {
+ public void post(ReloadStage stage) {
List<P> plugins = new ArrayList<>(getPlugins().toList());
plugins.sort(Comparator.comparingDouble(P::getPriority).reversed());
Collections.reverse(plugins);
- MutablePair<Stopwatch, String> sectionData = new MutablePair<>(Stopwatch.createUnstarted(), "");
- pluginSection(sectionData, "post-register", plugins, null, REIPlugin::postRegister);
+ try (SectionClosable postRegister = section(stage, "post-register/")) {
+ pluginSection(stage, "post-register/", plugins, null, plugin -> {
+ plugin.postRegister();
+ ((REIPlugin<P>) plugin).postStage(this, stage);
+ });
+ }
}
private static String name(Class<?> clazz) {
@@ -201,14 +211,15 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager<
try {
reloading = true;
long startTime = Util.getMillis();
- MutablePair<Stopwatch, String> sectionData = new MutablePair<>(Stopwatch.createUnstarted(), "");
- for (Reloadable<P> reloadable : reloadables) {
- Class<?> reloadableClass = reloadable.getClass();
- try (SectionClosable startReload = section(sectionData, "start-reload-" + name(reloadableClass))) {
- reloadable.startReload(stage);
- } catch (Throwable throwable) {
- throwable.printStackTrace();
+ try (SectionClosable startReloadAll = section(stage, "start-reload/")) {
+ for (Reloadable<P> reloadable : reloadables) {
+ Class<?> reloadableClass = reloadable.getClass();
+ try (SectionClosable startReload = section(stage, "start-reload/" + name(reloadableClass) + "/")) {
+ reloadable.startReload(stage);
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ }
}
}
@@ -219,15 +230,19 @@ public class PluginManagerImpl<P extends REIPlugin<?>> implements PluginManager<
for (Reloadable<P> reloadable : getReloadables()) {
Class<?> reloadableClass = reloadable.getClass();
- pluginSection(sectionData, "reloadable-plugin-" + name(reloadableClass), plugins, reloadable, plugin -> reloadable.acceptPlugin(plugin, stage));
+ try (SectionClosable reloadablePlugin = section(stage, "reloadable-plugin/" + name(reloadableClass) + "/")) {
+ pluginSection(stage, "reloadable-plugin/" + name(reloadableClass) + "/", plugins, reloadable, plugin -> reloadable.acceptPlugin(plugin, stage));
+ }
}
- for (Reloadable<P> reloadable : reloadables) {
- Class<?> reloadableClass = reloadable.getClass();
- try (SectionClosable endReload = section(sectionData, "end-reload-" + name(reloadableClass))) {
- reloadable.endReload(stage);
- } catch (Throwable throwable) {
- throwable.printStackTrace();
+ try (SectionClosable endReloadAll = section(stage, "end-reload/")) {
+ for (Reloadable<P>