diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-10-20 18:41:27 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-10-22 01:41:12 +0800 |
| commit | 843a29c5fcf8d20f7073438d9fbed7039dead719 (patch) | |
| tree | cfe93852c0ba236dfa7989470bab7e63c602d7a2 | |
| parent | a95ce0972205bff98687c7d2bb1654e331c7e41f (diff) | |
| download | RoughlyEnoughItems-843a29c5fcf8d20f7073438d9fbed7039dead719.tar.gz RoughlyEnoughItems-843a29c5fcf8d20f7073438d9fbed7039dead719.tar.bz2 RoughlyEnoughItems-843a29c5fcf8d20f7073438d9fbed7039dead719.zip | |
Fix modifying stacks at runtime, fixes support for JEITweaker
11 files changed, 407 insertions, 59 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java b/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java index ddd74a367..be1d3ab26 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java @@ -24,6 +24,7 @@ package me.shedaniel.rei.api.common.plugins; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.impl.ClientInternals; import me.shedaniel.rei.impl.Internals; import net.fabricmc.api.EnvType; @@ -61,18 +62,18 @@ public interface PluginView<P extends REIPlugin<?>> { } @Override - public void pre() { - PluginView.this.pre(); + public void pre(ReloadStage stage) { + PluginView.this.pre(stage); } @Override - public void post() { - PluginView.this.post(); + public void post(ReloadStage stage) { + PluginView.this.post(stage); } }; } - void pre(); + void pre(ReloadStage stage); - void post(); + void post(ReloadStage stage); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java b/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java index 2599281e8..ef4444661 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java @@ -29,11 +29,13 @@ 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.type.EntryTypeRegistry; import me.shedaniel.rei.api.common.fluid.FluidSupportProvider; +import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.api.common.registry.Reloadable; import org.jetbrains.annotations.ApiStatus; import java.util.Collection; import java.util.Collections; +import java.util.Objects; /** * Base interface for a REI plugin. @@ -97,13 +99,31 @@ public interface REIPlugin<P extends REIPlugin<?>> extends Comparable<REIPlugin< } @ApiStatus.OverrideOnly + @Deprecated + @ApiStatus.ScheduledForRemoval default void preRegister() { } @ApiStatus.OverrideOnly + default void preStage(PluginManager<P> manager, ReloadStage stage) { + if (stage == ReloadStage.START && Objects.equals(manager, PluginManager.getInstance())) { + preRegister(); + } + } + + @ApiStatus.OverrideOnly + @Deprecated + @ApiStatus.ScheduledForRemoval default void postRegister() { } + @ApiStatus.OverrideOnly + default void postStage(PluginManager<P> manager, ReloadStage stage) { + if (stage == ReloadStage.END && (this instanceof REIServerPlugin ? Objects.equals(manager, PluginManager.getServerInstance()) : !Objects.equals(manager, PluginManager.getInstance()))) { + preRegister(); + } + } + @Override default Collection<P> provide() { return Collections.singletonList((P) this); 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); |
