diff options
Diffstat (limited to 'runtime/src')
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> reloadable : reloadables) { + Class<?> reloadableClass = reloadable.getClass(); + try (SectionClosable endReload = section(stage, "end-reload/" + name(reloadableClass) + "/")) { + reloadable.endReload(stage); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } } } |
