Files
NotEnoughItems/src/main/java/codechicken/nei/recipe/RecipeHandlerQuery.java
T

130 lines
4.8 KiB
Java

package codechicken.nei.recipe;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import codechicken.nei.ItemList;
import codechicken.nei.NEIClientConfig;
public class RecipeHandlerQuery<T extends IRecipeHandler> {
private final Function<T, T> recipeHandlerFunction;
private final List<T> recipeHandlers;
private final List<T> serialRecipeHandlers;
private final String[] errorMessage;
private boolean error = false;
public RecipeHandlerQuery(Function<T, T> recipeHandlerFunction, List<T> recipeHandlers,
List<T> serialRecipeHandlers, String... errorMessage) {
this.recipeHandlerFunction = recipeHandlerFunction;
this.recipeHandlers = recipeHandlers;
this.serialRecipeHandlers = serialRecipeHandlers;
this.errorMessage = errorMessage;
}
public ArrayList<T> runWithProfiling(String profilerSection) {
return ProfilerRecipeHandler.recipeProfiler.start(profilerSection, () -> {
try {
ArrayList<T> handlers = getRecipeHandlersParallel();
if (error) {
displayRecipeLookupError();
}
return handlers;
} catch (InterruptedException | ExecutionException e) {
printLog(e);
displayRecipeLookupError();
return new ArrayList<>(0);
}
});
}
private ArrayList<T> getRecipeHandlersParallel() throws InterruptedException, ExecutionException {
// Pre-find the fuels so we're not fighting over it
if (NEIClientConfig.getBooleanSetting("findFuelsParallel")) {
FuelRecipeHandler.findFuelsOnceParallel();
} else {
FuelRecipeHandler.findFuelsOnce();
}
ArrayList<T> handlers = getSerialHandlersWithRecipes();
handlers.addAll(getHandlersWithRecipes());
handlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
return handlers;
}
private ArrayList<T> getSerialHandlersWithRecipes() {
return serialRecipeHandlers.stream()
.map(handler -> ProfilerRecipeHandler.recipeProfiler.profile(handler, () -> {
try {
return isHidden(handler) ? null : recipeHandlerFunction.apply(handler);
} catch (Throwable t) {
printLog(t);
error = true;
return null;
}
}))
.filter(
h -> h != null && h.numRecipes() > 0
&& SearchRecipeHandler.findFirst(h, (recipeIndex) -> true) != -1)
.collect(Collectors.toCollection(ArrayList::new));
}
private ArrayList<T> getHandlersWithRecipes() throws InterruptedException, ExecutionException {
return ItemList.forkJoinPool.submit(
() -> recipeHandlers.parallelStream()
.map(handler -> ProfilerRecipeHandler.recipeProfiler.profile(handler, () -> {
try {
return isHidden(handler) ? null : recipeHandlerFunction.apply(handler);
} catch (Throwable t) {
printLog(t);
error = true;
return null;
}
}))
.filter(
h -> h != null && h.numRecipes() > 0
&& SearchRecipeHandler.findFirst(h, (recipeIndex) -> true) != -1)
.collect(Collectors.toCollection(ArrayList::new)))
.get();
}
private boolean isHidden(T handler) {
final String handlerName = handler.getHandlerId();
final String handlerId = handler.getOverlayIdentifier();
return NEIClientConfig.hiddenHandlers.stream().anyMatch(h -> h.equals(handlerId) || h.equals(handlerName));
}
private void printLog(Throwable t) {
for (String message : errorMessage) {
NEIClientConfig.logger.error(message);
}
t.printStackTrace();
}
private void displayRecipeLookupError() {
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
if (player != null) {
IChatComponent chat = new ChatComponentTranslation("nei.chat.recipe.error");
chat.getChatStyle().setColor(EnumChatFormatting.RED);
player.addChatComponentMessage(chat);
}
}
}