Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/12.x-1.20' into 13.x-1.20.2
Browse files Browse the repository at this point in the history
  • Loading branch information
shedaniel committed Apr 12, 2024
2 parents b98602f + e26d21c commit f59653f
Showing 1 changed file with 155 additions and 116 deletions.
271 changes: 155 additions & 116 deletions runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
import com.google.common.base.Stopwatch;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import it.unimi.dsi.fastutil.longs.Long2LongMap;
import it.unimi.dsi.fastutil.longs.Long2LongMaps;
import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import me.shedaniel.rei.api.client.REIRuntime;
import me.shedaniel.rei.api.client.config.ConfigObject;
import me.shedaniel.rei.api.client.registry.category.CategoryRegistry;
Expand Down Expand Up @@ -108,7 +108,7 @@ private static Map<DisplayCategory<?>, List<DisplaySpec>> _buildMapFor(ViewSearc

Stopwatch stopwatch = Stopwatch.createStarted();
boolean processingVisibilityHandlers = builder.isProcessingVisibilityHandlers();
Set<CategoryIdentifier<?>> categories = builder.getCategories();
Set<CategoryIdentifier<?>> categories = new HashSet<>(builder.getCategories());
Set<CategoryIdentifier<?>> filteringCategories = builder.getFilteringCategories();
List<EntryStack<?>> recipesForStacks = builder.getRecipesFor();
List<EntryStack<?>> usagesForStacks = builder.getUsagesFor();
Expand All @@ -122,27 +122,20 @@ private static Map<DisplayCategory<?>, List<DisplaySpec>> _buildMapFor(ViewSearc
DisplayRegistry displayRegistry = DisplayRegistry.getInstance();
DisplaysHolder displaysHolder = ((DisplayRegistryImpl) displayRegistry).displaysHolder();

Map<DisplayCategory<?>, List<Display>> result = Maps.newLinkedHashMap();
for (CategoryRegistry.CategoryConfiguration<?> categoryConfiguration : CategoryRegistry.getInstance()) {
DisplayCategory<?> category = categoryConfiguration.getCategory();
if (processingVisibilityHandlers && CategoryRegistry.getInstance().isCategoryInvisible(category)) continue;
CategoryIdentifier<?> categoryId = categoryConfiguration.getCategoryIdentifier();
if (!filteringCategories.isEmpty() && !filteringCategories.contains(categoryId)) continue;
List<Display> allRecipesFromCategory = displayRegistry.get((CategoryIdentifier<Display>) categoryId);

Set<Display> set = Sets.newLinkedHashSet();
if (categories.contains(categoryId)) {
for (Display display : allRecipesFromCategory) {
Map<DisplayCategory<?>, Set<Display>> result = Maps.newLinkedHashMap();
forCategories(processingVisibilityHandlers, filteringCategories, displayRegistry, result, (configuration, categoryId, displays, set) -> {
if (categories.contains(categoryId)) { // If the category is in the search, add all displays
for (Display display : displays) {
if (!processingVisibilityHandlers || displayRegistry.isDisplayVisible(display)) {
set.add(display);
}
}
if (!set.isEmpty()) {
CollectionUtils.getOrPutEmptyList(result, category).addAll(set);
getOrPutEmptyLinkedSet(result, configuration.getCategory()).addAll(set);
}
continue;
return;
}
for (Display display : allRecipesFromCategory) {
for (Display display : displays) {
if (processingVisibilityHandlers && !displayRegistry.isDisplayVisible(display)) continue;
if (!recipesForStacks.isEmpty()) {
if (isRecipesFor(displaysHolder, recipesForStacks, display)) {
Expand All @@ -153,42 +146,12 @@ private static Map<DisplayCategory<?>, List<DisplaySpec>> _buildMapFor(ViewSearc
if (!usagesForStacks.isEmpty()) {
if (isUsagesFor(displaysHolder, usagesForStacks, display)) {
set.add(display);
continue;
}
}
}
if (set.isEmpty() && (!recipesForStacksWildcard.isEmpty() || !usagesForStacksWildcard.isEmpty())) {
for (Display display : allRecipesFromCategory) {
if (processingVisibilityHandlers && !displayRegistry.isDisplayVisible(display)) continue;
if (!recipesForStacksWildcard.isEmpty()) {
if (isRecipesFor(displaysHolder, recipesForStacksWildcard, display)) {
set.add(display);
continue;
}
}
if (!usagesForStacksWildcard.isEmpty()) {
if (isUsagesFor(displaysHolder, usagesForStacksWildcard, display)) {
set.add(display);
continue;
}
}
}
}
for (EntryStack<?> usagesFor : Iterables.concat(usagesForStacks, usagesForStacksWildcard)) {
if (isStackWorkStationOfCategory(categoryConfiguration, usagesFor)) {
if (processingVisibilityHandlers) {
set.addAll(CollectionUtils.filterToSet(allRecipesFromCategory, displayRegistry::isDisplayVisible));
} else {
set.addAll(allRecipesFromCategory);
}
break;
}
}
if (!set.isEmpty()) {
CollectionUtils.getOrPutEmptyList(result, category).addAll(set);
}
}
});

// Generate live displays per category
int generatorsCount = 0;

for (Map.Entry<CategoryIdentifier<?>, List<DynamicDisplayGenerator<?>>> entry : displayRegistry.getCategoryDisplayGenerators().entrySet()) {
Expand All @@ -204,90 +167,65 @@ private static Map<DisplayCategory<?>, List<DisplaySpec>> _buildMapFor(ViewSearc
}

if (!set.isEmpty()) {
CollectionUtils.getOrPutEmptyList(result, category).addAll(set);
getOrPutEmptyLinkedSet(result, category).addAll(set);
}
}

Consumer<Display> displayConsumer = display -> {
CategoryIdentifier<?> categoryIdentifier = display.getCategoryIdentifier();
if (!filteringCategories.isEmpty() && !filteringCategories.contains(categoryIdentifier)) return;
CollectionUtils.getOrPutEmptyList(result, CategoryRegistry.getInstance().get(categoryIdentifier).getCategory()).add(display);
getOrPutEmptyLinkedSet(result, CategoryRegistry.getInstance().get(categoryIdentifier).getCategory()).add(display);
};
for (DynamicDisplayGenerator<Display> generator : (List<DynamicDisplayGenerator<Display>>) (List<? extends DynamicDisplayGenerator<?>>) displayRegistry.getGlobalDisplayGenerators()) {
generatorsCount++;
generateLiveDisplays(displayRegistry, wrapForError(generator), builder, displayConsumer);
}

Map<DisplayCategory<?>, List<DisplaySpec>> resultSpeced = (Map<DisplayCategory<?>, List<DisplaySpec>>) (Map) new LinkedHashMap<>(result);
// optimize displays
if (builder.isMergingDisplays() && ConfigObject.getInstance().doMergeDisplayUnderOne()) {
for (Map.Entry<DisplayCategory<?>, List<Display>> entry : result.entrySet()) {
DisplayMerger<Display> merger = (DisplayMerger<Display>) entry.getKey().getDisplayMerger();

if (merger != null) {
class Wrapped implements DisplaySpec {
private final Display display;
private List<ResourceLocation> ids = null;
private final int hash;

public Wrapped(Display display) {
this.display = display;
this.hash = merger.hashOf(display);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Wrapped)) return false;
Wrapped wrapped = (Wrapped) o;
return hash == wrapped.hash && merger.canMerge(display, wrapped.display);
}

@Override
public int hashCode() {
return hash;
}

@Override
public Display provideInternalDisplay() {
return display;
}

@Override
public Collection<ResourceLocation> provideInternalDisplayIds() {
if (ids == null) {
ids = new ArrayList<>();
Optional<ResourceLocation> location = display.getDisplayLocation();
if (location.isPresent()) {
ids.add(location.get());
}
}
return ids;
}

public void add(Display display) {
Optional<ResourceLocation> location = display.getDisplayLocation();
if (location.isPresent()) {
provideInternalDisplayIds().add(location.get());
}
if (CollectionUtils.allMatch(result.values(), Set::isEmpty) && (!recipesForStacksWildcard.isEmpty() || !usagesForStacksWildcard.isEmpty())) {
// Run wildcard search because no displays were found
forCategories(processingVisibilityHandlers, filteringCategories, displayRegistry, result, (configuration, categoryId, displays, set) -> {
if (categories.contains(categoryId)) return;
for (Display display : displays) {
if (processingVisibilityHandlers && !displayRegistry.isDisplayVisible(display)) continue;
if (!recipesForStacksWildcard.isEmpty()) {
if (isRecipesFor(displaysHolder, recipesForStacksWildcard, display)) {
set.add(display);
continue;
}
}
Map<Wrapped, Wrapped> wrappedSet = new LinkedHashMap<>();
List<Wrapped> wrappeds = new ArrayList<>();

for (Display display : sortAutoCrafting(entry.getValue())) {
Wrapped wrapped = new Wrapped(display);
if (wrappedSet.containsKey(wrapped)) {
wrappedSet.get(wrapped).add(display);
} else {
wrappedSet.put(wrapped, wrapped);
wrappeds.add(wrapped);
if (!usagesForStacksWildcard.isEmpty()) {
if (isUsagesFor(displaysHolder, usagesForStacksWildcard, display)) {
set.add(display);
}
}

resultSpeced.put(entry.getKey(), (List<DisplaySpec>) (List) wrappeds);
}
});
}

forCategories(processingVisibilityHandlers, filteringCategories, displayRegistry, result, (configuration, categoryId, displays, set) -> {
if (categories.contains(categoryId)) return;
for (EntryStack<?> usagesFor : Iterables.concat(usagesForStacks, usagesForStacksWildcard)) {
if (isStackWorkStationOfCategory(configuration, usagesFor)) {
categories.add(categoryId);
if (processingVisibilityHandlers) {
set.addAll(CollectionUtils.filterToSet(displays, displayRegistry::isDisplayVisible));
} else {
set.addAll(displays);
}
break;
}
}
});

Map<DisplayCategory<?>, List<DisplaySpec>> resultSpec = (Map<DisplayCategory<?>, List<DisplaySpec>>) (Map) new LinkedHashMap<>();
for (CategoryRegistry.CategoryConfiguration<?> configuration : CategoryRegistry.getInstance()) {
Set<Display> displays = result.get(configuration.getCategory());
if (displays == null) continue;
resultSpec.put(configuration.getCategory(), new ArrayList<>(displays));
}
// optimize displays
if (builder.isMergingDisplays() && ConfigObject.getInstance().doMergeDisplayUnderOne()) {
mergeAndOptimize(result, resultSpec);
}

String message = String.format("Built Recipe View in %s for %d categories, %d recipes for, %d usages for and %d live recipe generators.",
Expand All @@ -297,7 +235,30 @@ public void add(Display display) {
} else {
InternalLogger.getInstance().trace(message);
}
return resultSpeced;
return resultSpec;
}

private static void forCategories(boolean processingVisibilityHandlers, Set<CategoryIdentifier<?>> filteringCategories, DisplayRegistry displayRegistry, Map<DisplayCategory<?>, Set<Display>> result, QuadConsumer<CategoryRegistry.CategoryConfiguration<?>, CategoryIdentifier<?>, List<Display>, Set<Display>> displayConsumer) {
for (CategoryRegistry.CategoryConfiguration<?> configuration : CategoryRegistry.getInstance()) {
if (processingVisibilityHandlers && CategoryRegistry.getInstance().isCategoryInvisible(configuration.getCategory())) continue;
CategoryIdentifier<?> categoryId = configuration.getCategoryIdentifier();
if (!filteringCategories.isEmpty() && !filteringCategories.contains(categoryId)) continue;
List<Display> allRecipesFromCategory = displayRegistry.get((CategoryIdentifier<Display>) categoryId);
Set<Display> set = new LinkedHashSet<>();
displayConsumer.accept(configuration, categoryId, allRecipesFromCategory, set);
if (!set.isEmpty()) {
getOrPutEmptyLinkedSet(result, configuration.getCategory()).addAll(set);
}
}
}

public static <A, B> Set<B> getOrPutEmptyLinkedSet(Map<A, Set<B>> map, A key) {
Set<B> b = map.get(key);
if (b != null) {
return b;
}
map.put(key, new ReferenceOpenHashSet<>());
return map.get(key);
}

public static boolean isRecipesFor(@Nullable DisplaysHolder displaysHolder, List<EntryStack<?>> stacks, Display display) {
Expand Down Expand Up @@ -334,7 +295,7 @@ private static boolean checkUsages(List<EntryStack<?>> stacks, Display display,
return false;
}

private static Iterable<Display> sortAutoCrafting(List<Display> displays) {
private static Iterable<Display> sortAutoCrafting(Iterable<Display> displays) {
Set<Display> successfulDisplays = new LinkedHashSet<>();
Set<Display> applicableDisplays = new LinkedHashSet<>();

Expand Down Expand Up @@ -555,6 +516,84 @@ private static <T> boolean isStackWorkStationOfCategory(CategoryRegistry.Categor

@Override
public void startReload() {

}

private static void mergeAndOptimize(Map<DisplayCategory<?>, Set<Display>> displays, Map<DisplayCategory<?>, List<DisplaySpec>> resultSpec) {
for (Map.Entry<DisplayCategory<?>, Set<Display>> entry : displays.entrySet()) {
DisplayMerger<Display> merger = (DisplayMerger<Display>) entry.getKey().getDisplayMerger();

if (merger != null) {
Map<WrappedDisplaySpec, WrappedDisplaySpec> wrappedSet = new LinkedHashMap<>();
List<WrappedDisplaySpec> specs = new ArrayList<>();

for (Display display : sortAutoCrafting(entry.getValue())) {
WrappedDisplaySpec wrapped = new WrappedDisplaySpec(merger, display);
if (wrappedSet.containsKey(wrapped)) {
wrappedSet.get(wrapped).add(display);
} else {
wrappedSet.put(wrapped, wrapped);
specs.add(wrapped);
}
}

resultSpec.put(entry.getKey(), (List<DisplaySpec>) (List) specs);
}
}
}

private static class WrappedDisplaySpec implements DisplaySpec {
private final DisplayMerger<Display> merger;
private final Display display;
private List<ResourceLocation> ids = null;
private final int hash;

public WrappedDisplaySpec(DisplayMerger<Display> merger, Display display) {
this.merger = merger;
this.display = display;
this.hash = merger.hashOf(display);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof WrappedDisplaySpec)) return false;
WrappedDisplaySpec wrapped = (WrappedDisplaySpec) o;
return hash == wrapped.hash && merger.canMerge(display, wrapped.display);
}

@Override
public int hashCode() {
return hash;
}

@Override
public Display provideInternalDisplay() {
return display;
}

@Override
public Collection<ResourceLocation> provideInternalDisplayIds() {
if (ids == null) {
ids = new ArrayList<>();
Optional<ResourceLocation> location = display.getDisplayLocation();
if (location.isPresent()) {
ids.add(location.get());
}
}
return ids;
}

public void add(Display display) {
Optional<ResourceLocation> location = display.getDisplayLocation();
if (location.isPresent()) {
provideInternalDisplayIds().add(location.get());
}
}
}

@FunctionalInterface
private interface QuadConsumer<P1, P2, P3, P4> {
void accept(P1 p1, P2 p2, P3 p3, P4 p4);
}
}

0 comments on commit f59653f

Please sign in to comment.