diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-07-27 23:25:27 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2022-08-26 10:52:27 +0900 |
| commit | 05069aa62b09f02a8cd6e526ec58a30347a56500 (patch) | |
| tree | acb90d01f0a06de7c6b540eefeeee8259016f8ac /api/src/main | |
| parent | 685861c91bbb8a8a882da51381d392f1310d061d (diff) | |
| download | RoughlyEnoughItems-05069aa62b09f02a8cd6e526ec58a30347a56500.tar.gz RoughlyEnoughItems-05069aa62b09f02a8cd6e526ec58a30347a56500.tar.bz2 RoughlyEnoughItems-05069aa62b09f02a8cd6e526ec58a30347a56500.zip | |
WIP Module
Diffstat (limited to 'api/src/main')
12 files changed, 238 insertions, 50 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/EntryRenderer.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/EntryRenderer.java index c51309603..2aa203aa9 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/EntryRenderer.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/renderer/EntryRenderer.java @@ -29,7 +29,7 @@ import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.gui.widgets.TooltipContext; import me.shedaniel.rei.api.common.entry.EntryStack; -import me.shedaniel.rei.impl.ClientInternals; +import me.shedaniel.rei.api.common.entry.type.BuiltinEntryTypes; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.jetbrains.annotations.ApiStatus; @@ -46,7 +46,7 @@ import org.jetbrains.annotations.Nullable; @Environment(EnvType.CLIENT) public interface EntryRenderer<T> extends EntryRendererProvider<T> { static <T> EntryRenderer<T> empty() { - return ClientInternals.getEmptyEntryRenderer(); + return (EntryRenderer<T>) BuiltinEntryTypes.EMPTY.getDefinition().getRenderer(); } @Environment(EnvType.CLIENT) diff --git a/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntryType.java b/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntryType.java index 35a5e8f96..d80c567b0 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntryType.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntryType.java @@ -80,7 +80,7 @@ public interface FavoriteEntryType<T extends FavoriteEntry> { default void add(FavoriteEntry... entries) { add(false, entries); } - + @ApiStatus.Experimental void add(boolean defaultFavorited, FavoriteEntry... entries); diff --git a/api/src/main/java/me/shedaniel/rei/api/client/overlay/OverlayListWidget.java b/api/src/main/java/me/shedaniel/rei/api/client/overlay/OverlayListWidget.java index 1fa784806..57e7e8999 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/overlay/OverlayListWidget.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/overlay/OverlayListWidget.java @@ -54,4 +54,6 @@ public interface OverlayListWidget { * @return whether the mouse is within the overlay list widget */ boolean containsMouse(Point point); + + void queueReloadSearch(); } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/CollapsibleEntry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/CollapsibleEntry.java new file mode 100644 index 000000000..a3623970a --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/CollapsibleEntry.java @@ -0,0 +1,42 @@ +/* + * 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.registry.entry; + +import me.shedaniel.rei.api.common.entry.EntryStack; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Experimental +public interface CollapsibleEntry { + ResourceLocation getId(); + + Component getName(); + + boolean matches(EntryStack<?> stack, long hashExact); + + boolean isExpanded(); + + void setExpanded(boolean expanded); +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/CollapsibleEntryRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/CollapsibleEntryRegistry.java index c24ca5e2a..4de3468eb 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/CollapsibleEntryRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/CollapsibleEntryRegistry.java @@ -44,7 +44,7 @@ import java.util.function.Predicate; * and collect tags together. */ @ApiStatus.Experimental -public interface CollapsibleEntryRegistry extends Reloadable<REIClientPlugin> { +public interface CollapsibleEntryRegistry extends Reloadable<REIClientPlugin>, List<CollapsibleEntry> { /** * @return the {@link CollapsibleEntryRegistry} instance */ diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java index 63ed14d72..49dec73bb 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java @@ -83,7 +83,9 @@ public interface EntryRegistry extends Reloadable<REIClientPlugin> { * @return the unmodifiable list of filtered entry stacks, * only available <b>after</b> plugins reload. */ - List<EntryStack<?>> getPreFilteredList(); + default List<EntryStack<?>> getPreFilteredList() { + return PreFilteredEntryList.getInstance().getList(); + } /** * Applies the filtering rules to the entry list, is rather computational expensive. @@ -154,7 +156,9 @@ public interface EntryRegistry extends Reloadable<REIClientPlugin> { // TODO Re-evaluate the need for this @ApiStatus.Internal - Collection<EntryStack<?>> refilterNew(boolean warn, Collection<EntryStack<?>> entries); + default Collection<EntryStack<?>> refilterNew(boolean warn, Collection<EntryStack<?>> entries) { + return PreFilteredEntryList.getInstance().refilterNew(warn, entries); + } /** * Checks if a stack is already registered. diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/PreFilteredEntryList.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/PreFilteredEntryList.java new file mode 100644 index 000000000..f9bd53422 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/PreFilteredEntryList.java @@ -0,0 +1,51 @@ +/* + * 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.registry.entry; + +import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.registry.Reloadable; +import me.shedaniel.rei.impl.ClientInternals; +import me.shedaniel.rei.impl.Internals; +import org.jetbrains.annotations.ApiStatus; + +import java.util.Collection; +import java.util.List; + +@ApiStatus.Experimental +public interface PreFilteredEntryList extends Reloadable<REIClientPlugin> { + static PreFilteredEntryList getInstance() { + return ClientInternals.getPreFilteredEntryList(); + } + + // TODO Re-evaluate the need for this + @ApiStatus.Internal + Collection<EntryStack<?>> refilterNew(boolean warn, Collection<EntryStack<?>> entries); + + /** + * @return the unmodifiable list of filtered entry stacks, + * only available <b>after</b> plugins reload. + */ + List<EntryStack<?>> getList(); +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java b/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java index 80b4987df..0bc7f8fff 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java @@ -23,9 +23,12 @@ package me.shedaniel.rei.api.client.search; +import it.unimi.dsi.fastutil.ints.IntIntPair; import me.shedaniel.rei.api.common.entry.EntryStack; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.network.chat.Style; +import org.jetbrains.annotations.ApiStatus; import java.util.Collection; import java.util.function.Predicate; @@ -80,4 +83,21 @@ public interface SearchFilter extends Predicate<EntryStack<?>> { */ default void prepareFilter(Collection<EntryStack<?>> stacks) { } + + /** + * Processes the decoration of the search filter. + * + * @param sink the decoration sink + */ + @ApiStatus.Experimental + default void processDecoration(ParseDecorationSink sink) { + } + + interface ParseDecorationSink { + void addQuote(int index); + + void addSplitter(int index); + + void addPart(IntIntPair range, Style style, boolean usingGrammar, Collection<IntIntPair> grammarRanges, int index); + } } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/search/SearchProvider.java b/api/src/main/java/me/shedaniel/rei/api/client/search/SearchProvider.java index a337e5e17..9ec3af0b1 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/search/SearchProvider.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/search/SearchProvider.java @@ -58,4 +58,18 @@ public interface SearchProvider extends Reloadable<REIClientPlugin> { */ @ApiStatus.Experimental SearchFilter createFilter(String filter, InputMethod<?> inputMethod); + + /** + * Clears the search cache. + */ + @ApiStatus.Experimental + void clearCache(); + + /** + * Returns whether the search provider has cached. + * + * @return whether the search provider has cached + */ + @ApiStatus.Experimental + boolean hasCache(); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/registry/ParentReloadable.java b/api/src/main/java/me/shedaniel/rei/api/common/registry/ParentReloadable.java index 44039e240..e91f19245 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/registry/ParentReloadable.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/registry/ParentReloadable.java @@ -24,6 +24,7 @@ package me.shedaniel.rei.api.common.registry; import me.shedaniel.rei.api.common.plugins.REIPlugin; +import me.shedaniel.rei.impl.Internals; import java.util.List; @@ -32,6 +33,10 @@ public interface ParentReloadable<P extends REIPlugin<?>> extends Reloadable<P> void registerReloadable(Reloadable<? extends P> reloadable); + default <R extends Reloadable<? extends P>> void registerReloadable(Class<R> reloadableClass) { + registerReloadable(Internals.resolveService(reloadableClass)); + } + @Override default void startReload() { for (ReloadStage stage : ReloadStage.values()) { diff --git a/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java b/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java index 36456399b..60c6399fd 100644 --- a/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java +++ b/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java @@ -28,18 +28,17 @@ import com.mojang.serialization.DataResult; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.ClientHelper; -import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.gui.DrawableConsumer; import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.client.gui.widgets.*; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.client.registry.entry.PreFilteredEntryList; import me.shedaniel.rei.api.client.registry.screen.ClickArea; import me.shedaniel.rei.api.client.view.ViewSearchBuilder; import me.shedaniel.rei.api.common.entry.EntryIngredient; import me.shedaniel.rei.api.common.plugins.PluginManager; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; +import net.minecraft.ReportedException; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.nbt.CompoundTag; @@ -55,19 +54,17 @@ import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; import java.util.Collection; import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Supplier; +import java.util.function.*; @ApiStatus.Internal public final class ClientInternals { - private static Supplier<ClientHelper> clientHelper = ClientInternals::throwNotSetup; - private static Supplier<WidgetsProvider> widgetsProvider = ClientInternals::throwNotSetup; - private static Supplier<ViewSearchBuilder> viewSearchBuilder = ClientInternals::throwNotSetup; - private static Supplier<PluginManager<REIClientPlugin>> clientPluginManager = ClientInternals::throwNotSetup; - private static Supplier<EntryRenderer<?>> emptyEntryRenderer = ClientInternals::throwNotSetup; - private static BiFunction<Supplier<DataResult<FavoriteEntry>>, Supplier<CompoundTag>, FavoriteEntry> delegateFavoriteEntry = (supplier, toJson) -> throwNotSetup(); + private static final ClientHelper CLIENT_HELPER = resolveService(ClientHelper.class); + private static final WidgetsProvider WIDGETS_PROVIDER = resolveService(WidgetsProvider.class); + private static final ViewSearchBuilder VIEW_SEARCH_BUILDER = resolveService(ViewSearchBuilder.class); + private static final PluginManager<REIClientPlugin> CLIENT_PLUGIN_MANAGER = Internals.createPluginManager( + REIClientPlugin.class, + UnaryOperator.identity()); + private static final DelegatingFavoriteEntryProvider DELEGATE_FAVORITE_ENTRY = resolveService(DelegatingFavoriteEntryProvider.class); private static Function<CompoundTag, DataResult<FavoriteEntry>> favoriteEntryFromJson = (object) -> throwNotSetup(); private static Function<Boolean, ClickArea.Result> clickAreaHandlerResult = (result) -> throwNotSetup(); private static BiConsumer<List<ClientTooltipComponent>, TooltipComponent> clientTooltipComponentProvider = (tooltip, result) -> throwNotSetup(); @@ -77,6 +74,16 @@ public final class ClientInternals { private static Supplier<List<String>> jeiCompatMods = ClientInternals::throwNotSetup; private static Supplier<Object> builtinClientPlugin = ClientInternals::throwNotSetup; private static Function<List<EntryIngredient>, TooltipComponent> missingTooltip = (stacks) -> throwNotSetup(); + private static BiConsumer<ReportedException, String> crashHandler = (exception, component) -> throwNotSetup(); + private static Supplier<PreFilteredEntryList> preFilteredEntryList = ClientInternals::throwNotSetup; + + public static <T> T resolveService(Class<T> serviceClass) { + return Internals.resolveService(serviceClass); + } + + public static <T> List<T> resolveServices(Class<T> serviceClass) { + return Internals.resolveServices(serviceClass); + } private static <T> T throwNotSetup() { throw new AssertionError("REI Internals have not been initialized!"); @@ -108,15 +115,15 @@ public final class ClientInternals { } public static ClientHelper getClientHelper() { - return clientHelper.get(); + return CLIENT_HELPER; } public static WidgetsProvider getWidgetsProvider() { - return widgetsProvider.get(); + return WIDGETS_PROVIDER; } public static ViewSearchBuilder createViewSearchBuilder() { - return viewSearchBuilder.get(); + return VIEW_SEARCH_BUILDER; } public static Object getBuiltinPlugin() { @@ -144,30 +151,33 @@ public final class ClientInternals { } public static FavoriteEntry delegateFavoriteEntry(Supplier<DataResult<FavoriteEntry>> supplier, Supplier<CompoundTag> toJoin) { - return delegateFavoriteEntry.apply(supplier, toJoin); + return DELEGATE_FAVORITE_ENTRY.delegate(supplier, toJoin); } public static DataResult<FavoriteEntry> favoriteEntryFromJson(CompoundTag tag) { return favoriteEntryFromJson.apply(tag); } - public static <T> EntryRenderer<T> getEmptyEntryRenderer() { - return emptyEntryRenderer.get().cast(); - } - public static List<String> getJeiCompatMods() { return jeiCompatMods.get(); } public static PluginManager<REIClientPlugin> getPluginManager() { - return clientPluginManager.get(); + return CLIENT_PLUGIN_MANAGER; } public static TooltipComponent createMissingTooltip(List<EntryIngredient> stacks) { return missingTooltip.apply(stacks); } - @Environment(EnvType.CLIENT) + public static PreFilteredEntryList getPreFilteredEntryList() { + return preFilteredEntryList.get(); + } + + public static void crash(ReportedException exception, String component) { + crashHandler.accept(exception, component); + } + public interface WidgetsProvider { boolean isRenderingPanel(Panel panel); @@ -207,4 +217,8 @@ public final class ClientInternals { WidgetWithBounds wrapPadded(int padLeft, int padRight, int padTop, int padBottom, WidgetWithBounds widget); } + + public interface DelegatingFavoriteEntryProvider { + FavoriteEntry delegate(Supplier<DataResult<FavoriteEntry>> result, Supplier<CompoundTag> tag); + } } diff --git a/api/src/main/java/me/shedaniel/rei/impl/Internals.java b/api/src/main/java/me/shedaniel/rei/impl/Internals.java index 1e64c2c57..dd24614e6 100644 --- a/api/src/main/java/me/shedaniel/rei/impl/Internals.java +++ b/api/src/main/java/me/shedaniel/rei/impl/Internals.java @@ -31,9 +31,9 @@ import me.shedaniel.rei.api.common.entry.comparison.EntryComparator; import me.shedaniel.rei.api.common.entry.type.EntryDefinition; import me.shedaniel.rei.api.common.entry.type.EntryType; import me.shedaniel.rei.api.common.plugins.PluginManager; +import me.shedaniel.rei.api.common.plugins.PluginView; import me.shedaniel.rei.api.common.plugins.REIPlugin; import me.shedaniel.rei.api.common.plugins.REIServerPlugin; -import me.shedaniel.rei.api.common.transfer.info.MenuInfoRegistry; import me.shedaniel.rei.impl.common.InternalLogger; import net.minecraft.nbt.Tag; import net.minecraft.resources.ResourceLocation; @@ -41,31 +41,51 @@ import net.minecraft.util.Unit; import org.jetbrains.annotations.ApiStatus; import java.lang.reflect.Field; -import java.util.function.Function; +import java.util.List; +import java.util.ServiceLoader; import java.util.function.Supplier; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; @ApiStatus.Internal public final class Internals { - private static Supplier<EntryStackProvider> entryStackProvider = Internals::throwNotSetup; - private static Supplier<EntryIngredientProvider> entryIngredientProvider = Internals::throwNotSetup; - private static Function<ResourceLocation, EntryType<?>> entryTypeDeferred = (object) -> throwNotSetup(); - private static Supplier<PluginManager<REIPlugin<?>>> commonPluginManager = Internals::throwNotSetup; - private static Supplier<PluginManager<REIServerPlugin>> serverPluginManager = Internals::throwNotSetup; - private static Supplier<NbtHasherProvider> nbtHasherProvider = Internals::throwNotSetup; - private static Function<String, CategoryIdentifier<?>> categoryIdentifier = (object) -> throwNotSetup(); - private static Supplier<MenuInfoRegistry> stubMenuInfoRegistry = Internals::throwNotSetup; + private static final EntryStackProvider ENTRY_STACK_PROVIDER = resolveService(EntryStackProvider.class); + private static final EntryIngredientProvider ENTRY_INGREDIENT_PROVIDER = resolveService(EntryIngredientProvider.class); + private static final DeferringEntryTypeProvider ENTRY_TYPE_DEFERRED = resolveService(DeferringEntryTypeProvider.class); + private static final PluginManagerConstructor PLUGIN_MANAGER_CONSTRUCTOR = resolveService(PluginManagerConstructor.class); + private static final PluginManager<REIPlugin<?>> COMMON_PLUGIN_MANAGER = createPluginManager( + (Class<REIPlugin<?>>) (Class<?>) REIPlugin.class, + UnaryOperator.identity()); + private static final PluginManager<REIServerPlugin> SERVER_PLUGIN_MANAGER = createPluginManager( + REIServerPlugin.class, + view -> view.then(COMMON_PLUGIN_MANAGER.view())); + private static final NbtHasherProvider NBT_HASHER_PROVIDER = resolveService(NbtHasherProvider.class); + private static final CategoryIdentifierConstructor CATEGORY_IDENTIFIER_CONSTRUCTOR = resolveService(CategoryIdentifierConstructor.class); private static Supplier<InternalLogger> logger = Internals::throwNotSetup; private static <T> T throwNotSetup() { throw new AssertionError("REI Internals have not been initialized!"); } - @ApiStatus.Internal - public static <T> void attachInstance(T instance, Class<T> clazz) { - attachInstanceSupplier(instance, clazz.getSimpleName()); + public static <T> T resolveService(Class<T> serviceClass) { + ServiceLoader<T> loader = ServiceLoader.load(serviceClass); + List<ServiceLoader.Provider<T>> providers = loader.stream().toList(); + if (providers.isEmpty()) { + throw new IllegalArgumentException("No service providers found for class " + serviceClass.getName()); + } else if (providers.size() > 1) { + throw new IllegalArgumentException("Multiple service providers found for class " + serviceClass.getName() + ": " + + providers.stream().map(provider -> provider.type().getName()) + .collect(Collectors.joining(", "))); + } else { + return providers.get(0).get(); + } + } + + public static <T> List<T> resolveServices(Class<T> serviceClass) { + ServiceLoader<T> loader = ServiceLoader.load(serviceClass); + return loader.stream().map(ServiceLoader.Provider::get).toList(); } - @ApiStatus.Internal public static <T> void attachInstanceSupplier(T instance, String name) { attachInstance((Supplier<T>) () -> instance, name); } @@ -86,31 +106,35 @@ public final class Internals { } public static EntryStackProvider getEntryStackProvider() { - return entryStackProvider.get(); + return ENTRY_STACK_PROVIDER; } public static EntryIngredientProvider getEntryIngredientProvider() { - return entryIngredientProvider.get(); + return ENTRY_INGREDIENT_PROVIDER; } public static EntryType<?> deferEntryType(ResourceLocation id) { - return entryTypeDeferred.apply(id); + return ENTRY_TYPE_DEFERRED.get(id); + } + + public static <P extends REIPlugin<?>> PluginManager<P> createPluginManager(Class<P> clazz, UnaryOperator<PluginView<P>> constructor) { + return PLUGIN_MANAGER_CONSTRUCTOR.create(clazz, constructor); } public static PluginManager<REIPlugin<?>> getPluginManager() { - return commonPluginManager.get(); + return COMMON_PLUGIN_MANAGER; } public static PluginManager<REIServerPlugin> getServerPluginManager() { - return serverPluginManager.get(); + return SERVER_PLUGIN_MANAGER; } public static EntryComparator<Tag> getNbtHasher(String[] ignoredKeys) { - return nbtHasherProvider.get().provide(ignoredKeys); + return NBT_HASHER_PROVIDER.provide(ignoredKeys); } public static <T extends Display> CategoryIdentifier<T> getCategoryIdentifier(String location) { - return (CategoryIdentifier<T>) categoryIdentifier.apply(location); + return CATEGORY_IDENTIFIER_CONSTRUCTOR.create(location); } public static InternalLogger getInternalLogger() { @@ -137,7 +161,19 @@ public final class Internals { EntryIngredient.Builder builder(int initialCapacity); } + public interface PluginManagerConstructor { + <P extends REIPlugin<?>> PluginManager<P> create(Class<P> clazz, UnaryOperator<PluginView<P>> constructor); + } + public interface NbtHasherProvider { EntryComparator<Tag> provide(String... ignoredKeys); } + + public interface DeferringEntryTypeProvider { + EntryType<?> get(ResourceLocation id); + } + + public interface CategoryIdentifierConstructor { + <T extends Display> CategoryIdentifier<T> create(String location); + } } |
