minecraft-src/net/minecraft/util/DependencySorter.java
2025-07-04 01:41:11 +03:00

55 lines
2.1 KiB
Java

package net.minecraft.util;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class DependencySorter<K, V extends DependencySorter.Entry<K>> {
private final Map<K, V> contents = new HashMap();
public DependencySorter<K, V> addEntry(K key, V value) {
this.contents.put(key, value);
return this;
}
private void visitDependenciesAndElement(Multimap<K, K> dependencies, Set<K> visited, K element, BiConsumer<K, V> action) {
if (visited.add(element)) {
dependencies.get(element).forEach(object -> this.visitDependenciesAndElement(dependencies, visited, (K)object, action));
V entry = (V)this.contents.get(element);
if (entry != null) {
action.accept(element, entry);
}
}
}
private static <K> boolean isCyclic(Multimap<K, K> dependencies, K source, K target) {
Collection<K> collection = dependencies.get(target);
return collection.contains(source) ? true : collection.stream().anyMatch(object2 -> isCyclic(dependencies, source, (K)object2));
}
private static <K> void addDependencyIfNotCyclic(Multimap<K, K> dependencies, K source, K target) {
if (!isCyclic(dependencies, source, target)) {
dependencies.put(source, target);
}
}
public void orderByDependencies(BiConsumer<K, V> action) {
Multimap<K, K> multimap = HashMultimap.create();
this.contents.forEach((object, entry) -> entry.visitRequiredDependencies(object2 -> addDependencyIfNotCyclic(multimap, (K)object, (K)object2)));
this.contents.forEach((object, entry) -> entry.visitOptionalDependencies(object2 -> addDependencyIfNotCyclic(multimap, (K)object, (K)object2)));
Set<K> set = new HashSet();
this.contents.keySet().forEach(object -> this.visitDependenciesAndElement(multimap, set, (K)object, action));
}
public interface Entry<K> {
void visitRequiredDependencies(Consumer<K> visitor);
void visitOptionalDependencies(Consumer<K> visitor);
}
}