Generate resource cache using resource reload workers
This commit is contained in:
parent
65e12016b6
commit
b55129a8ca
|
|
@ -1,16 +1,19 @@
|
|||
package org.embeddedt.modernfix.resources;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.util.PackTypeHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
|
@ -26,6 +29,7 @@ public class PackResourcesCacheEngine {
|
|||
private final Map<PackType, Set<String>> namespacesByType;
|
||||
private final Set<CachedResourcePath> containedPaths;
|
||||
private final EnumMap<PackType, Map<String, List<CachedResourcePath>>> resourceListings;
|
||||
private CompletableFuture<Void> cacheFuture;
|
||||
|
||||
public PackResourcesCacheEngine(Function<PackType, Set<String>> namespacesRetriever, BiFunction<PackType, String, Path> basePathRetriever) {
|
||||
this.namespacesByType = new EnumMap<>(PackType.class);
|
||||
|
|
@ -36,32 +40,50 @@ public class PackResourcesCacheEngine {
|
|||
}
|
||||
this.containedPaths = new ObjectOpenHashSet<>();
|
||||
this.resourceListings = new EnumMap<>(PackType.class);
|
||||
CompletableFuture<Void> future = CompletableFuture.completedFuture(null);
|
||||
Stopwatch watch = Stopwatch.createStarted();
|
||||
// used for log message
|
||||
Path debugPath = basePathRetriever.apply(PackType.CLIENT_RESOURCES, "minecraft").toAbsolutePath();
|
||||
for(PackType type : PackType.values()) {
|
||||
Collection<String> namespaces = PackTypeHelper.isVanillaPackType(type) ? this.namespacesByType.get(type) : namespacesRetriever.apply(type);
|
||||
ImmutableMap.Builder<String, List<CachedResourcePath>> packTypedMap = ImmutableMap.builder();
|
||||
for(String namespace : namespaces) {
|
||||
try {
|
||||
ImmutableList.Builder<CachedResourcePath> namespacedList = ImmutableList.builder();
|
||||
Path root = basePathRetriever.apply(type, namespace).toAbsolutePath();
|
||||
String[] prefix = new String[] { type.getDirectory(), namespace };
|
||||
try (Stream<Path> stream = Files.walk(root)) {
|
||||
stream
|
||||
.map(path -> root.relativize(path.toAbsolutePath()))
|
||||
.filter(PackResourcesCacheEngine::isValidCachedResourcePath)
|
||||
.forEach(path -> {
|
||||
CachedResourcePath cachedPath = new CachedResourcePath(prefix, path);
|
||||
this.containedPaths.add(cachedPath);
|
||||
if(!cachedPath.getFileName().endsWith(".mcmeta"))
|
||||
namespacedList.add(cachedPath);
|
||||
});
|
||||
future = future.thenRunAsync(() -> {
|
||||
ImmutableMap.Builder<String, List<CachedResourcePath>> packTypedMap = ImmutableMap.builder();
|
||||
for(String namespace : namespaces) {
|
||||
try {
|
||||
ImmutableList.Builder<CachedResourcePath> namespacedList = ImmutableList.builder();
|
||||
Path root = basePathRetriever.apply(type, namespace).toAbsolutePath();
|
||||
String[] prefix = new String[] { type.getDirectory(), namespace };
|
||||
try (Stream<Path> stream = Files.walk(root)) {
|
||||
stream
|
||||
.map(path -> root.relativize(path.toAbsolutePath()))
|
||||
.filter(PackResourcesCacheEngine::isValidCachedResourcePath)
|
||||
.forEach(path -> {
|
||||
CachedResourcePath cachedPath = new CachedResourcePath(prefix, path);
|
||||
synchronized (this.containedPaths) {
|
||||
this.containedPaths.add(cachedPath);
|
||||
}
|
||||
if(!cachedPath.getFileName().endsWith(".mcmeta"))
|
||||
namespacedList.add(cachedPath);
|
||||
});
|
||||
}
|
||||
packTypedMap.put(namespace, namespacedList.build());
|
||||
} catch(IOException ignored) {
|
||||
}
|
||||
packTypedMap.put(namespace, namespacedList.build());
|
||||
} catch(IOException ignored) {
|
||||
}
|
||||
}
|
||||
this.resourceListings.put(type, packTypedMap.build());
|
||||
synchronized (this.resourceListings) {
|
||||
this.resourceListings.put(type, packTypedMap.build());
|
||||
}
|
||||
}, ModernFix.resourceReloadExecutor());
|
||||
}
|
||||
((ObjectOpenHashSet<CachedResourcePath>)this.containedPaths).trim();
|
||||
future = future.thenRunAsync(() -> {
|
||||
((ObjectOpenHashSet<CachedResourcePath>)this.containedPaths).trim();
|
||||
watch.stop();
|
||||
}, ModernFix.resourceReloadExecutor());
|
||||
this.cacheFuture = future;
|
||||
// print debug message in separate task to prevent slowing down rest of load
|
||||
future.thenRunAsync(() -> {
|
||||
ModernFix.LOGGER.debug("Generated cache for {} in {}", debugPath, watch);
|
||||
}, ModernFix.resourceReloadExecutor());
|
||||
}
|
||||
|
||||
private static boolean isValidCachedResourcePath(Path path) {
|
||||
|
|
@ -86,13 +108,22 @@ public class PackResourcesCacheEngine {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void awaitLoad() {
|
||||
if(this.cacheFuture != null) {
|
||||
this.cacheFuture.join();
|
||||
this.cacheFuture = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasResource(String path) {
|
||||
awaitLoad();
|
||||
return this.containedPaths.contains(new CachedResourcePath(path));
|
||||
}
|
||||
|
||||
public Collection<ResourceLocation> getResources(PackType type, String resourceNamespace, String pathIn, int maxDepth, Predicate<String> filter) {
|
||||
if(!PackTypeHelper.isVanillaPackType(type))
|
||||
throw new IllegalArgumentException("Only vanilla PackTypes are supported");
|
||||
awaitLoad();
|
||||
List<CachedResourcePath> paths = resourceListings.get(type).getOrDefault(resourceNamespace, Collections.emptyList());
|
||||
if(paths.isEmpty())
|
||||
return Collections.emptyList();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user