Kaynağa Gözat

4.0.3-unstable
- Adds async search
- Adds debug search option
- Set entry size range from 50%-400% to 25%-400%

Signed-off-by: shedaniel <daniel@shedaniel.me>

shedaniel 5 yıl önce
ebeveyn
işleme
7b2fc1ccc9

+ 1 - 1
gradle.properties

@@ -1,4 +1,4 @@
-mod_version=4.0.2-unstable
+mod_version=4.0.3-unstable
 minecraft_version=20w07a
 yarn_version=20w07a+build.1
 fabricloader_version=0.7.8+build.184

+ 8 - 0
src/main/java/me/shedaniel/rei/api/ConfigObject.java

@@ -122,4 +122,12 @@ public interface ConfigObject {
     
     List<EntryStack> getFilteredStacks();
     
+    @ApiStatus.Experimental
+    boolean shouldAsyncSearch();
+    
+    @ApiStatus.Experimental
+    int getNumberAsyncSearch();
+    
+    @ApiStatus.Experimental
+    boolean doDebugSearchTimeRequired();
 }

+ 39 - 8
src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java

@@ -40,7 +40,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.*;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
@@ -633,12 +633,43 @@ public class EntryListWidget extends WidgetWithBounds {
             boolean checkCraftable = ConfigManager.getInstance().isCraftableOnlyEnabled() && !ScreenHelper.inventoryStacks.isEmpty();
             List<EntryStack> workingItems = checkCraftable ? RecipeHelper.getInstance().findCraftableEntriesByItems(CollectionUtils.map(ScreenHelper.inventoryStacks, EntryStack::create)) : null;
             List<EntryStack> stacks = EntryRegistry.getInstance().getPreFilteredList();
-            if (stacks instanceof CopyOnWriteArrayList) {
-                for (EntryStack stack : stacks) {
-                    if (canLastSearchTermsBeAppliedTo(stack)) {
-                        if (workingItems != null && CollectionUtils.findFirstOrNullEqualsEntryIgnoreAmount(workingItems, stack) == null)
-                            continue;
-                        list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT));
+            if (stacks instanceof CopyOnWriteArrayList && !stacks.isEmpty()) {
+                if (ConfigObject.getInstance().shouldAsyncSearch()) {
+                    int size = ConfigObject.getInstance().getNumberAsyncSearch();
+                    List<CompletableFuture<List<EntryStack>>> completableFutures = Lists.newArrayList();
+                    for (int i = 0; i < stacks.size(); i += size) {
+                        int[] start = {i};
+                        completableFutures.add(CompletableFuture.supplyAsync(() -> {
+                            int end = Math.min(stacks.size() - 1, start[0] + size);
+                            List<EntryStack> filtered = Lists.newArrayList();
+                            for (; start[0] < end; start[0]++) {
+                                EntryStack stack = stacks.get(start[0]);
+                                if (canLastSearchTermsBeAppliedTo(stack)) {
+                                    if (workingItems != null && CollectionUtils.findFirstOrNullEqualsEntryIgnoreAmount(workingItems, stack) == null)
+                                        continue;
+                                    filtered.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT));
+                                }
+                            }
+                            return filtered;
+                        }));
+                    }
+                    try {
+                        CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).get(30, TimeUnit.SECONDS);
+                    } catch (InterruptedException | ExecutionException | TimeoutException e) {
+                        e.printStackTrace();
+                    }
+                    for (CompletableFuture<List<EntryStack>> future : completableFutures) {
+                        List<EntryStack> now = future.getNow(null);
+                        if (now != null)
+                            list.addAll(now);
+                    }
+                } else {
+                    for (EntryStack stack : stacks) {
+                        if (canLastSearchTermsBeAppliedTo(stack)) {
+                            if (workingItems != null && CollectionUtils.findFirstOrNullEqualsEntryIgnoreAmount(workingItems, stack) == null)
+                                continue;
+                            list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT));
+                        }
                     }
                 }
             }
@@ -678,7 +709,7 @@ public class EntryListWidget extends WidgetWithBounds {
             favoritesListWidget.updateSearch(this, searchTerm);
         long ended = System.nanoTime();
         long time = ended - started;
-        if (RoughlyEnoughItemsCore.isDebugModeEnabled())
+        if (ConfigObject.getInstance().doDebugSearchTimeRequired())
             RoughlyEnoughItemsCore.LOGGER.info("[REI] Search Used: %.2fms", time * 1e-6);
         updateEntriesPosition();
     }

+ 23 - 1
src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java

@@ -289,6 +289,24 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
         return filtering.filteredStacks;
     }
     
+    @Override
+    @ApiStatus.Experimental
+    public boolean shouldAsyncSearch() {
+        return performance.asyncSearch;
+    }
+    
+    @Override
+    @ApiStatus.Experimental
+    public int getNumberAsyncSearch() {
+        return performance.numberAsyncSearch;
+    }
+    
+    @Override
+    @ApiStatus.Experimental
+    public boolean doDebugSearchTimeRequired() {
+        return technical.debugSearchTimeRequired;
+    }
+    
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.FIELD})
     @interface DontApplyFieldName {}
@@ -348,7 +366,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
         @Comment("Declares the location of the favorites list.") private boolean displayFavoritesOnTheLeft = true;
         @Comment("Declares whether favorites tooltip should be displayed.") private boolean displayFavoritesTooltip = false;
         @Comment("Declares whether favorites will be searched.") private boolean searchFavorites = true;
-        @UsePercentage(min = 0.5, max = 4.0) private double entrySize = 1.0;
+        @UsePercentage(min = 0.25, max = 4.0) private double entrySize = 1.0;
         private boolean useCompactTabs = true;
         private boolean lowerConfigButton = false;
     }
@@ -360,6 +378,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
         @Comment("Declares the command used to change weather.") private String weatherCommand = "/weather {weather}";
         private boolean registerRecipesInAnotherThread = true;
         private boolean debugRenderTimeRequired = false;
+        @Comment("Experimental: Declares whether search time should be debugged.") private boolean debugSearchTimeRequired = false;
     }
     
     public static class Modules {
@@ -373,6 +392,9 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
     public static class Performance {
         @Comment("Whether REI should render entry's enchantment glint") private boolean renderEntryEnchantmentGlint = true;
         private boolean newFastEntryRendering = true;
+        @Comment("Experimental: Declares whether REI should search async.") private boolean asyncSearch = true;
+        @Comment("Experimental: Declares how many entries should be grouped one async search.") @ConfigEntry.BoundedDiscrete(min = 25, max = 400)
+        private int numberAsyncSearch = 75;
     }
     
     public static class Filtering {

+ 1 - 0
src/main/java/me/shedaniel/rei/tests/plugin/REITestPlugin.java

@@ -51,6 +51,7 @@ public class REITestPlugin implements REIPluginV0 {
     
     public EntryStack transformStack(EntryStack stack) {
         stack.setAmount(random.nextInt(Byte.MAX_VALUE));
+        stack.setting(EntryStack.Settings.CHECK_AMOUNT, EntryStack.Settings.TRUE);
         return stack;
     }
     

+ 3 - 0
src/main/resources/assets/roughlyenoughitems/lang/en_us.json

@@ -123,6 +123,8 @@
   "config.roughlyenoughitems.filteredEntries.show": "Show Selected",
   "config.roughlyenoughitems.filteredEntries.loadWorldFirst": "Load World First!",
   "config.roughlyenoughitems.entrySize": "Entry Size:",
+  "config.roughlyenoughitems.asyncSearch": "Async Search:",
+  "config.roughlyenoughitems.numberAsyncSearch": "Async Entry Group Size:",
   "config.roughlyenoughitems.useCompactTabs": "Compact Tabs:",
   "config.roughlyenoughitems.darkTheme": "Appearance Theme:",
   "config.roughlyenoughitems.darkTheme.boolean.true": "Dark Theme",
@@ -135,6 +137,7 @@
   "config.roughlyenoughitems.mirrorItemPanel.boolean.true": "Left Side",
   "config.roughlyenoughitems.mirrorItemPanel.boolean.false": "Right Side",
   "config.roughlyenoughitems.debugRenderTimeRequired": "Entry List Debug Mode:",
+  "config.roughlyenoughitems.debugSearchTimeRequired": "Search Debug Mode:",
   "config.roughlyenoughitems.searchFieldLocation": "Search Field Position:",
   "config.roughlyenoughitems.searchFieldLocation.bottom_side": "Bottom Left / Right",
   "config.roughlyenoughitems.searchFieldLocation.top_side": "Top Left / Right",