diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-11-07 21:21:49 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2022-11-07 21:42:03 +0800 |
| commit | 0be6613cad5eb71d4828118329f0d8f462c5a498 (patch) | |
| tree | 053bf10968f2de936a8d89dd362bdf3d13596a50 /api/src/main/java | |
| parent | 0ef0f8b21df4b9a603aaa2ab4a35d395ef6437c1 (diff) | |
| parent | 46d2c64c4303bc007055268075ea9be4e9852e5e (diff) | |
| download | RoughlyEnoughItems-0be6613cad5eb71d4828118329f0d8f462c5a498.tar.gz RoughlyEnoughItems-0be6613cad5eb71d4828118329f0d8f462c5a498.tar.bz2 RoughlyEnoughItems-0be6613cad5eb71d4828118329f0d8f462c5a498.zip | |
Merge commit '46d2c64c4303bc007055268075ea9be4e9852e5e' into modularity
Diffstat (limited to 'api/src/main/java')
9 files changed, 444 insertions, 2 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java new file mode 100644 index 000000000..d46709af9 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java @@ -0,0 +1,56 @@ +/* + * 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.api.client.entry.filtering; + +import me.shedaniel.rei.api.common.entry.EntryStack; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import org.jetbrains.annotations.ApiStatus; + +import java.util.Collection; + +@ApiStatus.Experimental +@Environment(EnvType.CLIENT) +public interface FilteringContext { + /** + * Returns the list of stacks that are previously marked as <b>shown</b> from other filtering rules. + * + * @return the list of stacks that are previously marked as shown from other filtering rules. + */ + Collection<EntryStack<?>> getShownStacks(); + + /** + * Returns the list of stacks that have not been processed by any filtering rules. + * + * @return the list of stacks that have not been processed by any filtering rules. + */ + Collection<EntryStack<?>> getUnsetStacks(); + + /** + * Returns the list of stacks that are previously marked as <b>hidden</b> from other filtering rules. + * + * @return the list of stacks that are previously marked as hidden from other filtering rules. + */ + Collection<EntryStack<?>> getHiddenStacks(); +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringResult.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringResult.java new file mode 100644 index 000000000..d523a650f --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringResult.java @@ -0,0 +1,40 @@ +/* + * 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.api.client.entry.filtering; + +import me.shedaniel.rei.api.common.entry.EntryStack; +import org.jetbrains.annotations.ApiStatus; + +import java.util.Collection; + +@ApiStatus.Experimental +public interface FilteringResult { + FilteringResult hide(EntryStack<?> stack); + + FilteringResult hide(Collection<? extends EntryStack<?>> stacks); + + FilteringResult show(EntryStack<?> stack); + + FilteringResult show(Collection<? extends EntryStack<?>> stacks); +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringResultFactory.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringResultFactory.java new file mode 100644 index 000000000..fa391362a --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringResultFactory.java @@ -0,0 +1,29 @@ +/* + * 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.api.client.entry.filtering; + +@FunctionalInterface +public interface FilteringResultFactory { + FilteringResult create(); +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java index cbc13636e..67fa66b0c 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java @@ -27,8 +27,40 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.jetbrains.annotations.ApiStatus; +/** + * A filtering rule type that is used to filter the entries on the entry panel, + * dictate what shows up in slots, or hide the entire display if all ingredients are filtered. + * + * @param <Cache> the type of the cache + */ @ApiStatus.Experimental @Environment(EnvType.CLIENT) -public interface FilteringRule { - boolean isManual(); +public interface FilteringRule<Cache> { + /** + * Returns the type of this filtering rule. + * + * @return the type of this filtering rule + */ + FilteringRuleType<? extends FilteringRule<Cache>> getType(); + + /** + * Prepares the cache for this filtering rule. + * + * @param async whether the cache should be prepared asynchronously + * @return the cache + */ + default Cache prepareCache(boolean async) { + return null; + } + + /** + * Processes the specified entry with the specified cache. + * + * @param context the context of this filtering + * @param resultFactory the result factory + * @param cache the cache + * @param async whether the stacks should be processed asynchronously + * @return the result of the processing + */ + FilteringResult processFilteredStacks(FilteringContext context, FilteringResultFactory resultFactory, Cache cache, boolean async); } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRuleType.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRuleType.java new file mode 100644 index 000000000..7891ebbc5 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRuleType.java @@ -0,0 +1,148 @@ +/* + * 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.api.client.entry.filtering; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; +import java.util.function.Function; + +/** + * A type of filtering rule. A filtering rule will filter the entries on the entry panel, + * dictate what shows up in slots, or hide the entire display if all ingredients are filtered. + * + * @param <T> the type of the filtering rule + */ +@ApiStatus.Experimental +@Environment(EnvType.CLIENT) +public interface FilteringRuleType<T extends FilteringRule<?>> { + /** + * Serializes the specified filtering rule to a compound tag. + * + * @param rule the filtering rule + * @param tag the compound tag + * @return the serialized compound tag + */ + static CompoundTag save(FilteringRule<?> rule, CompoundTag tag) { + tag.putString("id", rule.getType().getId().toString()); + tag.put("rule", ((FilteringRuleType<FilteringRule<?>>) rule.getType()).saveTo(rule, new CompoundTag())); + return tag; + } + + /** + * Serializes the specified filtering rule to a compound tag. + * + * @param rule the filtering rule + * @param tag the compound tag + * @return the serialized compound tag + */ + CompoundTag saveTo(T rule, CompoundTag tag); + + /** + * Deserializes the specified compound tag to a filtering rule. + * + * @param tag the compound tag + * @return the deserialized filtering rule + */ + @Nullable + static FilteringRule<?> read(CompoundTag tag) { + FilteringRuleType<?> type = FilteringRuleTypeRegistry.getInstance().get(ResourceLocation.tryParse(tag.getString("id"))); + if (type == null) return null; + return type.readFrom(tag.getCompound("rule")); + } + + /** + * Deserializes the specified compound tag to a filtering rule. + * + * @param tag the compound tag + * @return the deserialized filtering rule + */ + T readFrom(CompoundTag tag); + + /** + * Returns a function to create the configuration screen for this filtering rule type. + * The parent of the newly created screen is passed as the argument of the function. + * <p> + * If the function returns {@code null}, the filtering rule will not be configurable + * graphically. + * + * @param rule the filtering rule + * @return the screen function, or {@code null} if the filtering rule is not configurable + */ + @Nullable + default Function<Screen, Screen> createEntryScreen(T rule) { + return null; + } + + /** + * Returns the name of the filtering rule. + * + * @param rule the filtering rule + * @return the name of the filtering rule + */ + default Component getTitle(T rule) { + return Component.nullToEmpty(getId().toString()); + } + + /** + * Returns the description of the filtering rule. + * + * @param rule the filtering rule + * @return the description of the filtering rule + */ + default Component getSubtitle(T rule) { + return Component.nullToEmpty(null); + } + + /** + * Returns the id of the filtering rule type. + * + * @return the id of the filtering rule type + */ + default ResourceLocation getId() { + return Objects.requireNonNull(FilteringRuleTypeRegistry.getInstance().getId(this), "Id of " + this); + } + + /** + * Constructs a new filtering rule of this type. + * + * @return the new filtering rule + */ + T createNew(); + + /** + * Returns whether this filtering rule type is always enforced, + * and only one filtering rule of this type can be present in a filtering rule list. + * + * @return whether this filtering rule type is always enforced + */ + boolean isSingular(); +}
\ No newline at end of file diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRuleTypeRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRuleTypeRegistry.java new file mode 100644 index 000000000..781b31f88 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRuleTypeRegistry.java @@ -0,0 +1,77 @@ +/* + * 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.api.client.entry.filtering; + +import me.shedaniel.rei.api.client.entry.filtering.base.BasicFilteringRule; +import me.shedaniel.rei.impl.client.ClientInternals; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +@ApiStatus.Experimental +@Environment(EnvType.CLIENT) +public interface FilteringRuleTypeRegistry extends List<FilteringRuleType<?>> { + static FilteringRuleTypeRegistry getInstance() { + return ClientInternals.getFilteringRuleTypeRegistry(); + } + + /** + * Returns the filtering rule type with the specified id, or {@code null} if none exists. + * + * @param id the id of the filtering rule type + * @return the filtering rule type with the specified id, or {@code null} if none exists + */ + @Nullable + FilteringRuleType<?> get(ResourceLocation id); + + /** + * Returns the id of the specified filtering rule type, or {@code null} if none exists. + * + * @param rule the filtering rule type + * @return the id of the specified filtering rule type, or {@code null} if none exists + */ + @Nullable + ResourceLocation getId(FilteringRuleType<?> rule); + + /** + * Registers the specified filtering rule type. + * + * @param id the id of the filtering rule type + * @param rule the filtering rule type + */ + void register(ResourceLocation id, FilteringRuleType<?> rule); + + /** + * Returns the basic filtering rule that can be used to filter entries, + * without registering a new filtering rule type, for external + * plugins. + * + * @return the base filtering rule + */ + BasicFilteringRule<?> basic(); +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java new file mode 100644 index 000000000..26b2986c2 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java @@ -0,0 +1,44 @@ +/* + * 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.api.client.entry.filtering.base; + +import me.shedaniel.rei.api.client.entry.filtering.FilteringResult; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRule; +import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.common.registry.Reloadable; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import org.jetbrains.annotations.ApiStatus; + +/** + * The basic filtering rule that can be used to filter entries, + * without registering a new filtering rule type, for external + * plugins. + * + * @param <Cache> the cache type + */ +@ApiStatus.Experimental +@Environment(EnvType.CLIENT) +public interface BasicFilteringRule<Cache> extends Reloadable<REIClientPlugin>, FilteringRule<Cache>, FilteringResult { +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/plugins/REIClientPlugin.java b/api/src/main/java/me/shedaniel/rei/api/client/plugins/REIClientPlugin.java index deeca9ff3..c8045aff6 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/plugins/REIClientPlugin.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/plugins/REIClientPlugin.java @@ -24,6 +24,7 @@ package me.shedaniel.rei.api.client.plugins; import me.shedaniel.rei.api.client.config.addon.ConfigAddonRegistry; +import me.shedaniel.rei.api.client.entry.filtering.base.BasicFilteringRule; import me.shedaniel.rei.api.client.entry.renderer.EntryRendererRegistry; import me.shedaniel.rei.api.client.favorites.FavoriteEntryType; import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; @@ -98,6 +99,15 @@ public interface REIClientPlugin extends REIPlugin<REIClientPlugin> { } /** + * Registers basic entry filtering. + * + * @param rule the filtering rule + */ + @ApiStatus.OverrideOnly + default void registerBasicEntryFiltering(BasicFilteringRule<?> rule) { + } + + /** * Registers entries to collapse on the entry panel. * * @param registry the collapsible entry registry diff --git a/api/src/main/java/me/shedaniel/rei/impl/client/ClientInternals.java b/api/src/main/java/me/shedaniel/rei/impl/client/ClientInternals.java index c2b2ad0ea..183452028 100644 --- a/api/src/main/java/me/shedaniel/rei/impl/client/ClientInternals.java +++ b/api/src/main/java/me/shedaniel/rei/impl/client/ClientInternals.java @@ -26,6 +26,7 @@ package me.shedaniel.rei.impl.client; import com.mojang.serialization.DataResult; import me.shedaniel.math.Point; import me.shedaniel.rei.api.client.ClientHelper; +import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleTypeRegistry; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.gui.widgets.TooltipContext; @@ -69,6 +70,7 @@ public final class ClientInternals { private static final TooltipQueue TOOLTIP_QUEUE = resolveService(TooltipQueue.class); private static final TooltipRenderer TOOLTIP_RENDERER = resolveService(TooltipRenderer.class); private static final OverlayProvider SCREEN_OVERLAY_PROVIDER = resolveService(OverlayProvider.class); + private static final FilteringRuleTypeRegistry FILTERING_RULE_TYPE_REGISTRY = resolveService(FilteringRuleTypeRegistry.class); private static Function<CompoundTag, DataResult<FavoriteEntry>> favoriteEntryFromJson = (object) -> throwNotSetup(); private static Function<Boolean, ClickArea.Result> clickAreaHandlerResult = (result) -> throwNotSetup(); private static BiFunction<@Nullable Point, Collection<Tooltip.Entry>, Tooltip> tooltipProvider = (point, texts) -> throwNotSetup(); @@ -208,6 +210,10 @@ public final class ClientInternals { return preFilteredEntryList.get(); } + public static FilteringRuleTypeRegistry getFilteringRuleTypeRegistry() { + return FILTERING_RULE_TYPE_REGISTRY; + } + public static void crash(ReportedException exception, String component) { crashHandler.accept(exception, component); } |
