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.core.TaskProfiler; import codechicken.nei.ItemList; import codechicken.nei.NEIClientConfig; class RecipeHandlerQuery { private final Function recipeHandlerFunction; private final List recipeHandlers; private final List serialRecipeHandlers; private final String[] errorMessage; private boolean error = false; RecipeHandlerQuery(Function recipeHandlerFunction, List recipeHandlers, List serialRecipeHandlers, String... errorMessage) { this.recipeHandlerFunction = recipeHandlerFunction; this.recipeHandlers = recipeHandlers; this.serialRecipeHandlers = serialRecipeHandlers; this.errorMessage = errorMessage; } ArrayList runWithProfiling(String profilerSection) { TaskProfiler profiler = ProfilerRecipeHandler.getProfiler(); profiler.start(profilerSection); try { ArrayList handlers = getRecipeHandlersParallel(); if (error) { displayRecipeLookupError(); } return handlers; } catch (InterruptedException | ExecutionException e) { printLog(e); displayRecipeLookupError(); return new ArrayList<>(0); } finally { profiler.end(); } } private ArrayList getRecipeHandlersParallel() throws InterruptedException, ExecutionException { // Pre-find the fuels so we're not fighting over it FuelRecipeHandler.findFuelsOnceParallel(); ArrayList handlers = getSerialHandlersWithRecipes(); handlers.addAll(getHandlersWithRecipes()); handlers.sort(NEIClientConfig.HANDLER_COMPARATOR); return handlers; } private ArrayList getSerialHandlersWithRecipes() { return serialRecipeHandlers.stream().map(handler -> { try { return recipeHandlerFunction.apply(handler); } catch (Throwable t) { printLog(t); error = true; return null; } }).filter(h -> h != null && h.numRecipes() > 0).collect(Collectors.toCollection(ArrayList::new)); } private ArrayList getHandlersWithRecipes() throws InterruptedException, ExecutionException { return ItemList.forkJoinPool.submit(() -> recipeHandlers.parallelStream().map(handler -> { try { return recipeHandlerFunction.apply(handler); } catch (Throwable t) { printLog(t); error = true; return null; } }).filter(h -> h != null && h.numRecipes() > 0).collect(Collectors.toCollection(ArrayList::new))).get(); } 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); } } }