Skip to content
Open
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
6 changes: 6 additions & 0 deletions xplat/src/main/java/dev/emi/emi/api/EmiApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import dev.emi.emi.api.search.EmiSearchManager;
import dev.emi.emi.search.EmiSearchManagerImpl;
import org.jetbrains.annotations.Nullable;

import com.google.common.collect.Lists;
Expand Down Expand Up @@ -65,6 +67,10 @@ public static void setSearchText(String text) {
EmiScreenManager.search.setText(text);
}

public static EmiSearchManager createSearchManager() {
return new EmiSearchManagerImpl();
}

public static boolean isSearchFocused() {
return EmiScreenManager.search.isFocused();
}
Expand Down
82 changes: 82 additions & 0 deletions xplat/src/main/java/dev/emi/emi/api/search/EmiSearchManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package dev.emi.emi.api.search;

import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.registry.EmiStackList;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
* A search manager controls searching for stacks using EMI infrastructure.
*/
public interface EmiSearchManager {
/**
* Search for ingredients matching the given query string.
*
* @param query the query string to use when searching
* @param ingredients the list of ingredients to search in
* @return a future that completes with the updated list
*/
SearchFuture search(String query, List<? extends EmiIngredient> ingredients);

/**
* Search for ingredients matching the given query string in the list of all known ingredients.
* @param query the query string to use when searching
* @return a future that completes with the updated list
*/
default SearchFuture search(String query) {
return search(query, EmiStackList.stacks);
}

interface SearchFuture extends Future<List<? extends EmiIngredient>> {
/**
* {@return the search results if the search has completed, or the original input list}
*/
List<? extends EmiIngredient> getNow();

SearchFuture whenCompleted(Consumer<List<? extends EmiIngredient>> consumer);

static SearchFuture completedFuture(List<? extends EmiIngredient> list) {
return new SearchFuture() {
@Override
public List<? extends EmiIngredient> getNow() {
return list;
}

@Override
public SearchFuture whenCompleted(Consumer<List<? extends EmiIngredient>> consumer) {
consumer.accept(list);
return this;
}

@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}

@Override
public boolean isCancelled() {
return false;
}

@Override
public boolean isDone() {
return true;
}

@Override
public List<? extends EmiIngredient> get() {
return list;
}

@Override
public List<? extends EmiIngredient> get(long timeout, @NotNull TimeUnit unit) {
return list;
}
};
}
}
}
2 changes: 1 addition & 1 deletion xplat/src/main/java/dev/emi/emi/mixin/ItemStackMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class ItemStackMixin {

@Inject(at = @At("RETURN"), method = "getTooltip")
private void getTooltip(PlayerEntity player, TooltipContext context, CallbackInfoReturnable<List<Text>> info) {
if (EmiConfig.appendItemModId && EmiConfig.appendModId && Thread.currentThread() != EmiSearch.searchThread) {
if (EmiConfig.appendItemModId && EmiConfig.appendModId && !EmiSearch.isSearchThread()) {
List<Text> text = info.getReturnValue();
String namespace = EmiPort.getItemRegistry().getId(((ItemStack) (Object) this).getItem()).getNamespace();
String mod = EmiUtil.getModName(namespace);
Expand Down
2 changes: 1 addition & 1 deletion xplat/src/main/java/dev/emi/emi/screen/ConfigScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void setActiveBind(EmiBind bind, int offset) {
@Override
public void close() {
EmiConfig.writeConfig();
EmiSearch.update();
EmiScreenManager.updateSearch();
MinecraftClient.getInstance().setScreen(last);
}

Expand Down
30 changes: 23 additions & 7 deletions xplat/src/main/java/dev/emi/emi/screen/EmiScreenManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

import java.util.List;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import dev.emi.emi.api.search.EmiSearchManager;
import dev.emi.emi.registry.EmiStackList;
import dev.emi.emi.search.EmiSearchManagerImpl;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;

Expand Down Expand Up @@ -65,7 +69,6 @@
import dev.emi.emi.screen.widget.EmiSearchWidget;
import dev.emi.emi.screen.widget.SidebarButtonWidget;
import dev.emi.emi.screen.widget.SizedButtonWidget;
import dev.emi.emi.search.EmiSearch;
import dev.emi.emi.search.EmiSearch.CompiledQuery;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element;
Expand Down Expand Up @@ -125,17 +128,30 @@ public class EmiScreenManager {
() -> true, (w) -> EmiApi.viewRecipeTree(),
List.of(EmiPort.translatable("tooltip.emi.recipe_tree")));

public static EmiSearchManagerImpl searchManager = new EmiSearchManagerImpl();
public static EmiSearchManager.SearchFuture lastSearch = EmiSearchManager.SearchFuture.completedFuture(EmiScreenManager.getSearchSource());
public static boolean searchChanged = true;


public static boolean isDisabled() {
return !EmiReloadManager.isLoaded() || !EmiConfig.enabled;
}

public static void updateSearch() {
if(lastSearch != null) {
lastSearch.cancel(true);
}
lastSearch = searchManager.search(search.getText(), EmiScreenManager.getSearchSource()).whenCompleted(l -> searchChanged = true);
}

public static void recalculate() {
updateCraftables();
SidebarPanel searchPanel = getSearchPanel();
if (searchPanel != null && searchPanel.space != null) {
if (searchedStacks != EmiSearch.stacks) {
if (searchChanged) {
searchPanel.space.batcher.repopulate();
searchedStacks = EmiSearch.stacks;
searchedStacks = lastSearch.getNow();
searchChanged = false;
}
}

Expand Down Expand Up @@ -238,7 +254,7 @@ private static void updateCraftables() {
if (searchPanel != null && searchPanel.space != null) {
searchPanel.space.batcher.repopulate();
if (searchPanel.getType() == SidebarType.CRAFTABLES) {
EmiSearch.update();
EmiScreenManager.updateSearch();
}
}
EmiFavorites.updateSynthetic(inv);
Expand Down Expand Up @@ -807,8 +823,8 @@ private static void renderExclusionAreas(EmiDrawContext context, int mouseX, int
@SuppressWarnings({"rawtypes", "unchecked"})
private static void renderSlotOverlays(EmiDrawContext context, int mouseX, int mouseY, float delta, EmiScreenBase base) {
CompiledQuery query = null;
if (EmiScreenManager.search.highlight) {
query = EmiSearch.compiledQuery;
if (EmiScreenManager.search.highlight && lastSearch instanceof EmiSearchManagerImpl.SearchWorker worker) {
query = worker.getCompiledQuery();
}
Set<Slot> ignoredSlots = Sets.newHashSet();
Set<EmiStack> synfavs = Sets.newHashSet();
Expand Down Expand Up @@ -1380,7 +1396,7 @@ public void setSidebarPage(int page) {
}
}
if (isSearch()) {
EmiSearch.search(search.getText());
searchManager.search(search.getText(), EmiScreenManager.getSearchSource());
}
if (space != null) {
space.batcher.repopulate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public EmiSearchWidget(TextRenderer textRenderer, int x, int y, int width, int h
styles.add(new Pair<Integer, Style>(string.length(), Style.EMPTY.withFormatting(Formatting.WHITE)));
}
this.styles = styles;
EmiSearch.search(string);
EmiScreenManager.updateSearch();
});
}

Expand Down
86 changes: 13 additions & 73 deletions xplat/src/main/java/dev/emi/emi/search/EmiSearch.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -32,14 +34,21 @@

public class EmiSearch {
public static final Pattern TOKENS = Pattern.compile("(-?[@#]?\\/(\\\\.|[^\\\\\\/])+\\/|[^\\s]+)");
private static volatile SearchWorker currentWorker = null;
public static volatile Thread searchThread = null;
public static volatile List<? extends EmiIngredient> stacks = EmiStackList.stacks;
public static volatile CompiledQuery compiledQuery;
private static Thread searchThread;
public static final Executor executor = Executors.newSingleThreadExecutor(task -> {
Thread t = new Thread(task, "EMI Search Thread");
t.setDaemon(true);
searchThread = t;
return t;
});
public static Set<EmiStack> bakedStacks;
public static SuffixArray<SearchStack> names, tooltips, mods;
public static SuffixArray<EmiStack> aliases;

public static boolean isSearchThread() {
return searchThread == Thread.currentThread();
}

public static void bake() {
SuffixArray<SearchStack> names = new SuffixArray<>();
SuffixArray<SearchStack> tooltips = new SuffixArray<>();
Expand Down Expand Up @@ -110,31 +119,6 @@ public static void bake() {
EmiSearch.bakedStacks = bakedStacks;
}

public static void update() {
search(EmiScreenManager.search.getText());
}

public static void search(String query) {
synchronized (EmiSearch.class) {
SearchWorker worker = new SearchWorker(query, EmiScreenManager.getSearchSource());
currentWorker = worker;

searchThread = new Thread(worker);
searchThread.setDaemon(true);
searchThread.start();
}
}

public static void apply(SearchWorker worker, List<? extends EmiIngredient> stacks) {
synchronized (EmiSearch.class) {
if (worker == currentWorker) {
EmiSearch.stacks = stacks;
currentWorker = null;
searchThread = null;
}
}
}

public static class CompiledQuery {
public final Query fullQuery;

Expand Down Expand Up @@ -223,48 +207,4 @@ private static void addQuery(String s, boolean negated, List<Query> queries, Fun
queries.add(q);
}
}

private static class SearchWorker implements Runnable {
private final String query;
private final List<? extends EmiIngredient> source;

public SearchWorker(String query, List<? extends EmiIngredient> source) {
this.query = query;
this.source = source;
}

@Override
public void run() {
try {
CompiledQuery compiled = new CompiledQuery(query);
compiledQuery = compiled;
if (compiled.isEmpty()) {
apply(this, source);
return;
}
List<EmiIngredient> stacks = Lists.newArrayList();
int processed = 0;
for (EmiIngredient stack : source) {
if (processed++ >= 1024) {
processed = 0;
if (this != currentWorker) {
return;
}
}
List<EmiStack> ess = stack.getEmiStacks();
// TODO properly support ingredients?
if (ess.size() == 1) {
EmiStack es = ess.get(0);
if (compiled.test(es)) {
stacks.add(stack);
}
}
}
apply(this, List.copyOf(stacks));
} catch (Exception e) {
EmiLog.error("Error when attempting to search:");
e.printStackTrace();
}
}
}
}
Loading