Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#3110 Provide search transformers in the API #3112

Draft
wants to merge 1 commit into
base: 1.19.3
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CommonApi/src/main/java/mezz/jei/api/IModPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import mezz.jei.api.helpers.IPlatformFluidHelper;
import mezz.jei.api.registration.IRuntimeRegistration;
import mezz.jei.api.registration.ISearchRegistration;
import net.minecraft.resources.ResourceLocation;

import mezz.jei.api.registration.IAdvancedRegistration;
Expand Down Expand Up @@ -81,6 +82,15 @@ default void registerRecipeTransferHandlers(IRecipeTransferRegistration registra

}

/**
* Register special handlers related to searching ingredients.
*
* @since 12.2.0
*/
default void registerSearch(ISearchRegistration registration) {

}

/**
* Register recipe catalysts.
* Recipe Catalysts are ingredients that are needed in order to craft other things.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import mezz.jei.api.runtime.IIngredientVisibility;
import mezz.jei.api.runtime.IRecipesGui;
import mezz.jei.api.runtime.IScreenHelper;
import mezz.jei.api.search.ILanguageTransformer;

import java.util.Collection;

/**
* Allows mods to override the runtime classes for JEI with their own implementation.
Expand Down Expand Up @@ -88,4 +91,12 @@ public interface IRuntimeRegistration {
* This is used by JEI's GUI and can be used by other mods that want to use the same information from JEI.
*/
IEditModeConfig getEditModeConfig();

/**
* Get the language transformers registered by plugins with {@link ISearchRegistration#addLanguageTransformer}.
*
* @see ILanguageTransformer
* @since 12.2.0
*/
Collection<ILanguageTransformer> getLanguageTransformers();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package mezz.jei.api.registration;

import mezz.jei.api.IModPlugin;
import mezz.jei.api.helpers.IJeiHelpers;
import mezz.jei.api.search.ILanguageTransformer;

/**
* The {@link ISearchRegistration} instance is passed to your mod plugin in {@link IModPlugin#registerSearch(ISearchRegistration)}.
*
* @since 12.2.0
*/
public interface ISearchRegistration {
/**
* {@link IJeiHelpers} provides helpers and tools for addon mods.
*
* @since 12.2.0
*/
IJeiHelpers getJeiHelpers();

/**
* Register your own {@link ILanguageTransformer} here.
*
* @since 12.2.0
*/
void addLanguageTransformer(ILanguageTransformer languageTransformer);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package mezz.jei.api.search;

import net.minecraft.resources.ResourceLocation;

/**
* A language transformer lets you change string tokens that are added to the search tree.
*
* This is useful for some languages where there may be multiple ways
* to type the same thing, and the transformer can change the text.
* For example, "nihao" can be transformed to match "你好".
*
* @since 12.2.0
*/
public interface ILanguageTransformer {
/**
* Get the unique ID for this language transformer.
*/
ResourceLocation getId();

/**
* Change the token into something else.
*
* This is called before inserting any ingredients into the search tree,
* and also for looking up ingredients in the search tree.
*
* In order to work, this must always be consistent.
* For an input string, it must always return the same output
* string every time it is called.
*/
String transformToken(String token);
}
7 changes: 7 additions & 0 deletions CommonApi/src/main/java/mezz/jei/api/search/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package mezz.jei.api.search;

import net.minecraft.MethodsReturnNonnullByDefault;

import javax.annotation.ParametersAreNonnullByDefault;
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

/**
* A Generalized Suffix Tree, based on the Ukkonen's paper "On-line construction of suffix trees"
* http://www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf
* <a href="http://www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf">SuffixT1withFigs.pdf</a>
* <p>
* Allows for fast storage and fast(er) retrieval by creating a tree-based index out of a set of strings.
* Unlike common suffix trees, which are generally used to build an index out of one (very) long string,
Expand Down
5 changes: 4 additions & 1 deletion Forge/src/test/java/mezz/jei/test/IngredientFilterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import mezz.jei.api.runtime.IEditModeConfig;
import mezz.jei.api.runtime.IIngredientManager;
import mezz.jei.api.runtime.IIngredientVisibility;
import mezz.jei.api.search.ILanguageTransformer;
import mezz.jei.common.util.Translator;
import mezz.jei.common.config.IWorldConfig;
import mezz.jei.gui.config.IClientConfig;
Expand Down Expand Up @@ -86,6 +87,7 @@ public void setup() {
IIngredientSorter ingredientListSorter = (a, b) -> Comparator.comparing(IListElementInfo::getModNameForSorting);
this.ingredientVisibility = new IngredientVisibility(blacklist, worldConfig, editModeConfig, ingredientManager);
this.filterTextSource = new FilterTextSource();
List<ILanguageTransformer> languageTransformers = List.of();
this.ingredientFilter = new IngredientFilter(
filterTextSource,
clientConfig,
Expand All @@ -95,7 +97,8 @@ public void setup() {
baseList,
modIdHelper,
ingredientVisibility,
colorHelper
colorHelper,
languageTransformers
);

this.ingredientManager.registerIngredientListener(ingredientFilter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import mezz.jei.api.ingredients.subtypes.UidContext;
import mezz.jei.api.runtime.IIngredientManager;
import mezz.jei.api.runtime.IIngredientVisibility;
import mezz.jei.api.search.ILanguageTransformer;
import mezz.jei.common.config.DebugConfig;
import mezz.jei.common.util.Translator;
import mezz.jei.gui.config.IClientConfig;
Expand Down Expand Up @@ -67,7 +68,8 @@ public IngredientFilter(
NonNullList<IListElement<?>> ingredients,
IModIdHelper modIdHelper,
IIngredientVisibility ingredientVisibility,
IColorHelper colorHelper
IColorHelper colorHelper,
Collection<ILanguageTransformer> languageTransformers
) {
this.filterTextSource = filterTextSource;
this.ingredientManager = ingredientManager;
Expand All @@ -77,9 +79,9 @@ public IngredientFilter(
this.elementPrefixParser = new ElementPrefixParser(ingredientManager, config, colorHelper);

if (clientConfig.isLowMemorySlowSearchEnabled()) {
this.elementSearch = new ElementSearchLowMem();
this.elementSearch = new ElementSearchLowMem(languageTransformers);
} else {
this.elementSearch = new ElementSearch(this.elementPrefixParser);
this.elementSearch = new ElementSearch(this.elementPrefixParser, languageTransformers);
}

LOGGER.info("Adding {} ingredients", ingredients.size());
Expand Down
18 changes: 16 additions & 2 deletions Gui/src/main/java/mezz/jei/gui/search/ElementSearch.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package mezz.jei.gui.search;

import mezz.jei.api.search.ILanguageTransformer;
import mezz.jei.core.search.CombinedSearchables;
import mezz.jei.core.search.ISearchStorage;
import mezz.jei.core.search.ISearchable;
Expand All @@ -9,10 +10,12 @@
import mezz.jei.gui.ingredients.IListElementInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Unmodifiable;

import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

Expand All @@ -21,8 +24,11 @@ public class ElementSearch implements IElementSearch {

private final Map<PrefixInfo<IListElementInfo<?>>, PrefixedSearchable<IListElementInfo<?>>> prefixedSearchables = new IdentityHashMap<>();
private final CombinedSearchables<IListElementInfo<?>> combinedSearchables = new CombinedSearchables<>();
@Unmodifiable
private final List<ILanguageTransformer> languageTransformers;

public ElementSearch(ElementPrefixParser elementPrefixParser) {
public ElementSearch(ElementPrefixParser elementPrefixParser, Collection<ILanguageTransformer> languageTransformers) {
this.languageTransformers = List.copyOf(languageTransformers);
for (PrefixInfo<IListElementInfo<?>> prefixInfo : elementPrefixParser.allPrefixInfos()) {
ISearchStorage<IListElementInfo<?>> storage = prefixInfo.createStorage();
var prefixedSearchable = new PrefixedSearchable<>(storage, prefixInfo);
Expand All @@ -33,7 +39,7 @@ public ElementSearch(ElementPrefixParser elementPrefixParser) {

@Override
public Set<IListElementInfo<?>> getSearchResults(ElementPrefixParser.TokenInfo tokenInfo) {
String token = tokenInfo.token();
String token = transform(tokenInfo.token());
if (token.isEmpty()) {
return Set.of();
}
Expand Down Expand Up @@ -62,6 +68,7 @@ public void add(IListElementInfo<?> info) {
Collection<String> strings = prefixedSearchable.getStrings(info);
ISearchStorage<IListElementInfo<?>> searchable = prefixedSearchable.getSearchStorage();
for (String string : strings) {
string = transform(string);
searchable.put(string, info);
}
}
Expand All @@ -84,4 +91,11 @@ public void logStatistics() {
}
});
}

private String transform(String string) {
for (ILanguageTransformer languageTransformer : languageTransformers) {
string = languageTransformer.transformToken(string);
}
return string;
}
}
19 changes: 16 additions & 3 deletions Gui/src/main/java/mezz/jei/gui/search/ElementSearchLowMem.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package mezz.jei.gui.search;

import mezz.jei.api.search.ILanguageTransformer;
import mezz.jei.core.search.PrefixInfo;
import mezz.jei.gui.ingredients.IListElement;
import mezz.jei.gui.ingredients.IListElementInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Unmodifiable;

import java.util.ArrayList;
import java.util.Collection;
Expand All @@ -17,14 +19,17 @@ public class ElementSearchLowMem implements IElementSearch {
private static final Logger LOGGER = LogManager.getLogger();

private final List<IListElementInfo<?>> elementInfoList;
@Unmodifiable
private final List<ILanguageTransformer> languageTransformers;

public ElementSearchLowMem() {
public ElementSearchLowMem(Collection<ILanguageTransformer> languageTransformers) {
this.languageTransformers = List.copyOf(languageTransformers);
this.elementInfoList = new ArrayList<>();
}

@Override
public Set<IListElementInfo<?>> getSearchResults(ElementPrefixParser.TokenInfo tokenInfo) {
String token = tokenInfo.token();
String token = transform(tokenInfo.token());
if (token.isEmpty()) {
return Set.of();
}
Expand All @@ -35,11 +40,19 @@ public Set<IListElementInfo<?>> getSearchResults(ElementPrefixParser.TokenInfo t
.collect(Collectors.toSet());
}

private static boolean matches(String word, PrefixInfo<IListElementInfo<?>> prefixInfo, IListElementInfo<?> elementInfo) {
private String transform(String string) {
for (ILanguageTransformer languageTransformer : languageTransformers) {
string = languageTransformer.transformToken(string);
}
return string;
}

private boolean matches(String word, PrefixInfo<IListElementInfo<?>> prefixInfo, IListElementInfo<?> elementInfo) {
IListElement<?> element = elementInfo.getElement();
if (element.isVisible()) {
Collection<String> strings = prefixInfo.getStrings(elementInfo);
for (String string : strings) {
string = transform(string);
if (string.contains(word)) {
return true;
}
Expand Down
6 changes: 5 additions & 1 deletion Gui/src/main/java/mezz/jei/gui/startup/JeiGuiStarter.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import mezz.jei.api.runtime.IIngredientManager;
import mezz.jei.api.runtime.IIngredientVisibility;
import mezz.jei.api.runtime.IScreenHelper;
import mezz.jei.api.search.ILanguageTransformer;
import mezz.jei.common.Internal;
import mezz.jei.common.gui.textures.Textures;
import mezz.jei.common.input.IInternalKeyMappings;
Expand Down Expand Up @@ -54,6 +55,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.Collection;
import java.util.List;

public class JeiGuiStarter {
Expand All @@ -73,6 +75,7 @@ public static JeiEventHandlers start(IRuntimeRegistration registration) {
IIngredientVisibility ingredientVisibility = registration.getIngredientVisibility();
IIngredientManager ingredientManager = registration.getIngredientManager();
IEditModeConfig editModeConfig = registration.getEditModeConfig();
Collection<ILanguageTransformer> languageTransformers = registration.getLanguageTransformers();

IJeiHelpers jeiHelpers = registration.getJeiHelpers();
IColorHelper colorHelper = jeiHelpers.getColorHelper();
Expand Down Expand Up @@ -113,7 +116,8 @@ public static JeiEventHandlers start(IRuntimeRegistration registration) {
ingredientList,
modIdHelper,
ingredientVisibility,
colorHelper
colorHelper,
languageTransformers
);
ingredientManager.registerIngredientListener(ingredientFilter);
ingredientVisibility.registerListener(ingredientFilter::onIngredientVisibilityChanged);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public <V> Collection<V> getAllIngredients(IIngredientType<V> ingredientType) {
.getAllIngredients();
}

@SuppressWarnings("removal")
@Override
public <V> IIngredientHelper<V> getIngredientHelper(V ingredient) {
return getIngredientTypeChecked(ingredient)
Expand All @@ -52,7 +51,6 @@ public <V> IIngredientHelper<V> getIngredientHelper(IIngredientType<V> ingredien
.getIngredientHelper();
}

@SuppressWarnings("removal")
@Override
public <V> IIngredientRenderer<V> getIngredientRenderer(V ingredient) {
return getIngredientTypeChecked(ingredient)
Expand Down
10 changes: 9 additions & 1 deletion Library/src/main/java/mezz/jei/library/load/PluginLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
import mezz.jei.common.gui.textures.Textures;
import mezz.jei.common.platform.IPlatformFluidHelperInternal;
import mezz.jei.common.platform.Services;
import mezz.jei.core.util.LoggedTimer;
import mezz.jei.common.util.StackHelper;
import mezz.jei.core.util.LoggedTimer;
import mezz.jei.library.config.IModIdFormatConfig;
import mezz.jei.library.config.RecipeCategorySortingConfig;
import mezz.jei.library.focus.FocusFactory;
Expand All @@ -35,6 +35,7 @@
import mezz.jei.library.load.registration.RecipeCategoryRegistration;
import mezz.jei.library.load.registration.RecipeRegistration;
import mezz.jei.library.load.registration.RecipeTransferRegistration;
import mezz.jei.library.load.registration.SearchRegistration;
import mezz.jei.library.load.registration.SubtypeRegistration;
import mezz.jei.library.load.registration.VanillaCategoryExtensionRegistration;
import mezz.jei.library.plugins.vanilla.VanillaPlugin;
Expand Down Expand Up @@ -82,6 +83,13 @@ public PluginLoader(StartData data, IModIdFormatConfig modIdFormatConfig, IColor
this.jeiHelpers = new JeiHelpers(guiHelper, stackHelper, modIdHelper, focusFactory, colorHelper, ingredientManager);
}

public SearchRegistration registerSearch() {
List<IModPlugin> plugins = data.plugins();
SearchRegistration searchRegistration = new SearchRegistration(getJeiHelpers());
PluginCaller.callOnPlugins("Registering search", plugins, p -> p.registerSearch(searchRegistration));
return searchRegistration;
}

@Unmodifiable
private List<IRecipeCategory<?>> createRecipeCategories(List<IModPlugin> plugins, VanillaPlugin vanillaPlugin) {
RecipeCategoryRegistration recipeCategoryRegistration = new RecipeCategoryRegistration(jeiHelpers);
Expand Down
Loading