55 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			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);
 | |
| 	}
 | |
| }
 |